Search code examples
pythonpython-typingmarshmallowpyright

How to add type inference to Python Flask and Marshmallow


I'm new to Python from a Typescript background. Putting together a Flask API server and using Marshmallow to validate input DTOs.

How can I get VSCode to infer types from the Marshmallow Schema load?

class PostInput:
    myString = fields.Str(
        required=True
    )

@app.route('/foo', methods=['POST'])
def post_foo():
    try:
        data = PostInput().load(request.json)
    except ValidationError as err:
        return jsonify(err.messages), 400
      
    myString = data.get("myString")

    myString <== I want this to be known as a str

Solution

  • Adding typing hint to the dict key:

    from marshmallow import fields, Schema
    
    class PostInput(Schema):
        myString = fields.Str(
            required=True
        )
        
    json = '{"myString": "hello"}'
    data = PostInput().loads(json, many=False)
    myString:str = data.get("myString")
    

    or serializing data into the dataclass:

    
    from marshmallow import fields, Schema, post_load
    from dataclasses import dataclass
    
    @dataclass
    class InputClass:
        myString: str
    
    
    class PostInput(Schema):
        myString = fields.Str(
            required=True
        )
        @post_load
        def make_user(self, data, **kwargs) -> InputClass:
            return InputClass(**data)
            
        
    json = '{"myString": "hello"}'
    data: InputClass = PostInput().loads(json, many=False)
    myString = data.myString
    

    I would recommend to use pydantic for validation and loading the json. It does both validates the data and creates smth like a dataclass that inherits types of the attributes:

    from pydantic import BaseModel, Field
    
    class PostInput(BaseModel):
        myString: str = Field(required=True)    
    
    json = '{"myString": "hello"}'
    data = PostInput.model_validate_json(json)
    myString = data.myString