{"id":6366,"library":"flask-pydantic","title":"Flask-Pydantic","description":"Flask-Pydantic is a Flask extension that integrates the Pydantic library for robust data validation and serialization. It streamlines the process of validating incoming request data (query parameters, JSON bodies, form data, and path parameters) and serializing outgoing responses using Pydantic models, enhancing type safety and developer experience in Flask applications. The current version is 0.14.0, and it is actively maintained as part of the Pallets Community Ecosystem, with regular releases addressing new features and bug fixes.","status":"active","version":"0.14.0","language":"en","source_language":"en","source_url":"https://github.com/pallets-eco/flask-pydantic","tags":["Flask","Pydantic","validation","API","web","dataclasses","openapi"],"install":[{"cmd":"pip install Flask-Pydantic","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core web framework integration.","package":"Flask"},{"reason":"Data validation and serialization engine.","package":"Pydantic"}],"imports":[{"symbol":"validate","correct":"from flask_pydantic import validate"},{"symbol":"BaseModel","correct":"from pydantic import BaseModel"},{"symbol":"Flask","correct":"from flask import Flask"}],"quickstart":{"code":"from typing import Optional\nfrom flask import Flask, request, jsonify\nfrom pydantic import BaseModel, Field\nfrom flask_pydantic import validate\n\napp = Flask(__name__)\n\nclass QueryModel(BaseModel):\n    age: int = Field(..., ge=0, description=\"User's age\")\n    city: Optional[str] = None\n\nclass RequestBodyModel(BaseModel):\n    name: str = Field(..., min_length=2, max_length=50)\n    email: str = Field(..., pattern=\"^.+@.+\\..+$\") # Simple email regex\n\nclass ResponseModel(BaseModel):\n    message: str\n    user_info: dict\n\n@app.route(\"/users\", methods=[\"GET\"])\n@validate(query=QueryModel)\ndef get_user_info(query: QueryModel):\n    \"\"\"Get user info based on query parameters.\"\"\"\n    return jsonify(ResponseModel(\n        message=\"User info retrieved successfully\",\n        user_info={\"age\": query.age, \"city\": query.city}\n    ).model_dump())\n\n@app.route(\"/users\", methods=[\"POST\"])\n@validate(body=RequestBodyModel)\ndef create_user(body: RequestBodyModel):\n    \"\"\"Create a new user with validated request body.\"\"\"\n    # In a real app, you would save `body` to a database\n    return jsonify(ResponseModel(\n        message=f\"User {body.name} created with email {body.email}\",\n        user_info=body.model_dump()\n    ).model_dump()), 201\n\nif __name__ == \"__main__\":\n    # Example usage: start server and make requests like:\n    # GET /users?age=30&city=NewYork\n    # POST /users with JSON body: {\"name\": \"Alice\", \"email\": \"alice@example.com\"}\n    app.run(debug=True, port=5000)\n","lang":"python","description":"This quickstart demonstrates how to use `flask-pydantic` to validate query parameters for a GET request and a JSON request body for a POST request. It defines Pydantic `BaseModel` classes for both input validation and response serialization, applying the `@validate` decorator to Flask routes to automatically handle data parsing and validation. Errors result in a 400 Bad Request response by default."},"warnings":[{"fix":"Review the official Pydantic V1 to V2 migration guide. Use Pydantic V2 methods like `.model_dump()`, `.model_dump_json()`, and `.model_validate()`. Alternatively, for existing V1 models, you can explicitly import `from pydantic.v1 import BaseModel` (note: `pydantic.v1` is not supported on Python 3.14+).","message":"When migrating to Pydantic V2, direct usage of Pydantic V1 methods (e.g., `.dict()`, `.json()`, `.parse_obj()`) on your Pydantic models will break. Flask-Pydantic (from v0.13.0) supports both Pydantic V1 and V2, but your application code must be updated.","severity":"breaking","affected_versions":"All versions where user code interacts directly with Pydantic models installed as Pydantic V2."},{"fix":"Ensure `@app.route` is defined *before* `@validate()` for all your Flask routes.","message":"The order of decorators matters. The `@app.route` decorator must always precede the `@validate()` decorator (i.e., `@validate()` should be closer to the function definition). Incorrect order will lead to validation not being applied.","severity":"gotcha","affected_versions":"All"},{"fix":"Upgrade `flask-pydantic` to version `0.13.2` or newer to ensure proper support for asynchronous view functions.","message":"Prior to version 0.13.2, `flask-pydantic` did not fully support asynchronous Flask views. Using `@validate` on `async def` routes might have led to unexpected behavior or errors.","severity":"gotcha","affected_versions":"<0.13.2"},{"fix":"Upgrade `flask-pydantic` to version `0.14.0` or newer to resolve issues with path parameter validation in views using dependency injection.","message":"Path parameter validation with dependency injection was fixed in version 0.14.0. Users on older versions might encounter issues where path parameters are not correctly validated or injected when used alongside other dependencies.","severity":"gotcha","affected_versions":"<0.14.0"},{"fix":"You can configure `FLASK_PYDANTIC_VALIDATION_ERROR_STATUS_CODE` in your Flask app config to change the status code. For full customization, set `FLASK_PYDANTIC_VALIDATION_ERROR_RAISE = True` in your Flask config and then use `app.register_error_handler(flask_pydantic.ValidationError, custom_error_handler)` to catch and handle the validation error globally.","message":"By default, `flask-pydantic` returns a 400 HTTP status code with a JSON error message upon validation failure. If you need custom error responses (e.g., a different status code, error format, or to raise a specific exception), the default behavior needs to be overridden.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z"}