6

I want to validate JSON object (it is in Telegram Bot API) which contains from field (which is reserved word in Python) by using pydantic validator. So my model should look like the following:

class Message(BaseModel):
  message_id: int
  from: Optional[str]
  date: int
  chat: Any
  ...

But using from keyword is not allowed in this context.

How could I do this?

Note: this is different than "Why we can't use keywords as attributes" because here we get external JSON we don't control and we anyway should handle JSON with from field.

Relequestual
  • 11,631
  • 6
  • 47
  • 83
likern
  • 3,744
  • 5
  • 36
  • 47
  • Possible duplicate of [Why can't attribute names be Python keywords?](https://stackoverflow.com/questions/9746838/why-cant-attribute-names-be-python-keywords) – esqew Apr 10 '19 at 19:11
  • 3
    The proposed duplicate says *why* you can't use `from` as an attribute, not how you would work around that here to accommodate a JSON object using `from` as a key. – chepner Apr 10 '19 at 19:16
  • One way that *may* work (probably not the "right" way to do it) is to update the annotations yourself: `Message.__annotations__.update({'from': Optional[str]})` – alkasm Apr 10 '19 at 19:24

2 Answers2

15

I believe you can replace from with from_.

You can do it like this:

class Message(BaseModel):
    message_id: int
    from_: Optional[str]
    date: int
    chat: Any

    class Config:
        fields = {
        'from_': 'from'
        }
    ...
Amir Shabani
  • 3,857
  • 6
  • 30
  • 67
2

There might be a way to do this using a class statement, but I didn't see anything in a quick skim of the documentation. What you could do is use dynamic model creation instead.

fields = {
    'message_id': (int,),
    'from': (Optional[str], ...),
    'date': (int, ...),
    'chat': (Any, ...)
 }
 Message = create_model("Message", **fields)
chepner
  • 497,756
  • 71
  • 530
  • 681