Proposal change to pydantic
Here is example excerpt of response model in Pydantic:
class AccountItem(BaseModel):
id: PositiveInt
name: RegexName
owner: Authority
active: Authority
posting: Authority
memo_key: RegexKey
json_metadata: str | Json
posting_json_metadata: str | Json
proxy: str
last_owner_update: HiveDateTime
last_account_update: HiveDateTime
Generally we can create all of responses schemas in object oriented model and reuse fields like HiveDateTime, Authority. For example that is code of creation HiveDateTime which we use to validate date in format ISO:
class HiveDateTime(datetime):
@validator('isoformat')
def check_custom_format(cls, v):
try:
datetime.strptime(v, '%Y-%m-%dT%H:%M:%S')
except ValueError:
raise ValueError('date must be in format %Y-%m-%dT%H:%M:%S')
return v
Plus is that we have much shorter code than before, for example schema of public key in Pydantic:
class RegexKey(ConstrainedStr):
regex = re.compile(r'^(?:STM|TST)[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{7,51}$')
And in schemas:
class CustomSchema(Schema):
@abstractmethod
def _define_schema(self) -> Schema:
pass
def _create_core_of_schema(self) -> Dict[str, typing.Any]:
return self._define_schema()._create_schema()
class PublicKey(CustomSchema):
def _define_schema(self) -> Schema:
wif_private_key_regex = r'^(?:STM|TST)[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{7,51}$'
return Str(pattern=wif_private_key_regex)
Pydantic make some work for us, for example when in response we have int in string format it will try to convert it to int automatically. So we can use much pydantic ready fields or simply create our own.
To create Pydantic model from response we just need to:
class FindAccount(BaseModel):
accounts: list[AccountItem] # AccountItem is base class for find_accounts and list_accounts api responses
try:
find_accounts = HiveResult.factory(FindAccount, **response_to_check)
except ValidationError as e:
print(e.json())
We use HiveResult class to give just 'result' from response to analise.
We can convert Pydantic model to JSON schema:
find_accounts.schema_json(indent=2)
In Pydantic models 'podpowiadaczka' also works:
So generally we have: response schemas in object oriented model, simple way to define special fields(like HiveDateTime) and less code. Here is link to my branch to see more specifically how does it works: https://gitlab.syncad.com/hive/hive/-/tree/jziebinski-2