-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: metadata api #44
Conversation
:type nft: :py:class:`domain.metadata.token_metdata.TokenNFT` | ||
""" | ||
id: str | ||
verified: Optional[bool] = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Optional
? What does None
mean in this case? Add the description in the docstring, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to let the json have only the fields that matter. Docstring updated.
""" | ||
id: str | ||
verified: Optional[bool] = False | ||
banned: Optional[bool] = False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Optional
? What does None
mean in this case? Add the description in the docstring, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to let the json have only the fields that matter. Docstring updated.
id: str | ||
verified: Optional[bool] = False | ||
banned: Optional[bool] = False | ||
reason: Optional[str] = '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Optional
? What does None
mean in this case? Add the description in the docstring, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property only make sense for banned tokens
@@ -80,7 +80,7 @@ jobs: | |||
REDIS_HOST: ${{ secrets.REDIS_HOST }} | |||
REDIS_PORT: 6379 | |||
REDIS_DB: 0 | |||
TOKEN_METADATA_BUCKET: token-metadata-testnet | |||
METADATA_BUCKET: metadata-testnet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add this in the TODO as well.
Create new buckets, migrate token info from old bucket to the new one and delete old bucket when everything is working fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it covers all, but i'll be more specific
|
||
|
||
@dataclass | ||
class MetaTransaction: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we add any new property in transaction metadata we need to update the explorer service? Imagine we want to mark a tx as banned or as important (don't know why but just imagining possible situations). How do we handle this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and i think that is the right thing to do. Otherwise we could broke things in explorer or have other unpredictable problems.
usecases/get_token_metadata.py
Outdated
|
||
|
||
class GetTokenMetadata: | ||
|
||
def __init__(self, token_gateway: Union[TokenGateway, None] = None) -> None: | ||
self.token_gateway = token_gateway or TokenGateway() | ||
def __init__(self, metadata_gateway: Union[MetadataGateway, None] = None) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Optional[MetadataGateway]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1,17 +1,17 @@ | |||
from typing import Union | |||
|
|||
from gateways.token_gateway import TokenGateway | |||
from gateways.metadata_gateway import MetadataGateway | |||
|
|||
|
|||
class GetTokenMetadata: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mark as deprecated and that it will be removed soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
usecases/get_metadata.py
Outdated
|
||
class GetMetadata: | ||
|
||
def __init__(self, metadata_gateway: Union[MetadataGateway, None] = None) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Optional[MetadataGateway]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
def get(self, type: str, id: str) -> Union[dict, None]: | ||
metadata_methods = { | ||
'token': self.metadata_gateway.get_token_metadata, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the end of the day, both are "BaseTransactions" in the DAG. Isn't it easier to use just one gateway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The gateway is the same, only the method changes. Each method return a different type of meta.
|
||
|
||
class TokenGateway: | ||
"""Gateway for Token | ||
|
||
:param s3_client: Client for s3 manipulation, default to domain S3Client | ||
:type s3_client: | ||
:param hathor_core_client: Client for make hathor-core requests, default to domain HathorCoreClient |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HathorCoreClient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It is the client to make requests for a full-node. get_token
method uses it therefore will be changed soon.
def _metadata_bucket(self) -> str: | ||
metadata_bucket = METADATA_BUCKET | ||
|
||
if metadata_bucket is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it better to validate all configuration in the constructor? So we can assume everything is right when we get to this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so as we can have methods that don't need this constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All methods need this constant for now, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pedroferreira1 yes, but i still feel it's not good to check in constructor. We don't have this var in test env, for instance and i don't think we must to. Of course for some tests we have to mock it, but some tests just don't care about it and i think it doesn't make sense to mock a var only for the class to not break.
I know it's just test but i think it's a good indication why maybe it's not so good to check this on constructor.
gateways/metadata_gateway.py
Outdated
|
||
:param id: token id | ||
:type id: str | ||
:raises Exception: The name of the bucket used to store the jsons must be on config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel this error should belong to this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. This error is thrown by _get_metadata
method, i've removed from the docstring.
gateways/metadata_gateway.py
Outdated
|
||
return TransactionMetadata.from_dict(transaction_metadata) | ||
|
||
def get_token_metadata(self, id: str) -> Union[TokenMetadata, None]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Optional[TokenMetadata]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
@dataclass | ||
class TransactionMetadata(Metadata): | ||
data: Optional[MetaTransaction] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using two classes? I feel it would be simper to use one class with all fields there. Well, we can group in subclasses for specific cases if there are too many fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have only specific cases by now. We can use Union[Meta1, Meta2]
in places that will handle metadata but i think that is not scalable.
faf15fa
to
ee657c0
Compare
def _metadata_bucket(self) -> str: | ||
metadata_bucket = METADATA_BUCKET | ||
|
||
if metadata_bucket is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All methods need this constant for now, right?
"nft_media": { | ||
"type": "IMAGE", | ||
"file": "http://curtis-white.com/mean/officer.png", | ||
"loop": false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it required even for image files? Does it work only for videos or audios can play in loop as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not required in s3 json files but will be always present on responses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the documentation must have the details for each field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the datails on fields structure explanation
f05986c
to
ce8d7be
Compare
text/0003-metadata-api.md
Outdated
|
||
``` | ||
TokenMeta { // if type is token | ||
id: string, // hash id of token or transaction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: 'hash id of token or transaction ' -> 'token uid'
text/0003-metadata-api.md
Outdated
banned: boolean, // if token is banned | ||
reason: string, // reason of ban | ||
nft: boolean, // if token is a NFT | ||
nft_media: { // media data of NFT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: 'media data of NFT (optional)'
text/0003-metadata-api.md
Outdated
} | ||
|
||
TransactionMeta { | ||
id: string, // hash id of token or transaction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: 'hash id of token or transaction ' -> 'transaction hash'
Feature implemented on #67 |
Rendered Design
We'll keep current token meta endpoint for retro compatibility and remove it once the explorer is reaching the new endpoint.
Before Merge
After Merge