{"id":20999784,"url":"https://github.com/rmoralespp/flask_typed_routes","last_synced_at":"2026-02-11T23:20:23.821Z","repository":{"id":262676300,"uuid":"887874407","full_name":"rmoralespp/flask_typed_routes","owner":"rmoralespp","description":"Flask extension designed to effortlessly validate requests with Pydantic based on standard Python type hints.","archived":false,"fork":false,"pushed_at":"2026-02-02T12:02:34.000Z","size":3684,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-03T01:26:44.408Z","etag":null,"topics":["flask","pydantic","python","requests","typing","validation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rmoralespp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-13T12:40:47.000Z","updated_at":"2026-02-02T12:01:39.000Z","dependencies_parsed_at":"2025-02-06T17:28:39.499Z","dependency_job_id":"4078cf9b-8fc6-4750-8c66-cff37fdd01d3","html_url":"https://github.com/rmoralespp/flask_typed_routes","commit_stats":{"total_commits":27,"total_committers":2,"mean_commits":13.5,"dds":"0.14814814814814814","last_synced_commit":"5b17b86569b20af9fe397523814e1fc7f866be9f"},"previous_names":["rmoralespp/flask_typed_routes"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/rmoralespp/flask_typed_routes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmoralespp%2Fflask_typed_routes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmoralespp%2Fflask_typed_routes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmoralespp%2Fflask_typed_routes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmoralespp%2Fflask_typed_routes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rmoralespp","download_url":"https://codeload.github.com/rmoralespp/flask_typed_routes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmoralespp%2Fflask_typed_routes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29349372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T20:11:40.865Z","status":"ssl_error","status_checked_at":"2026-02-11T20:10:41.637Z","response_time":97,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flask","pydantic","python","requests","typing","validation"],"created_at":"2024-11-19T08:08:17.518Z","updated_at":"2026-02-11T23:20:23.816Z","avatar_url":"https://github.com/rmoralespp.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/rmoralespp/flask_typed_routes/workflows/CI/badge.svg)](https://github.com/rmoralespp/flask_typed_routes/actions?query=event%3Arelease+workflow%3ACI)\n[![pypi](https://img.shields.io/pypi/v/flask_typed_routes.svg)](https://pypi.python.org/pypi/flask_typed_routes)\n[![codecov](https://codecov.io/gh/rmoralespp/flask_typed_routes/branch/main/graph/badge.svg)](https://app.codecov.io/gh/rmoralespp/flask_typed_routes)\n[![license](https://img.shields.io/github/license/rmoralespp/flask_typed_routes.svg)](https://github.com/rmoralespp/flask_typed_routes/blob/main/LICENSE)\n[![Downloads](https://pepy.tech/badge/flask_typed_routes)](https://pepy.tech/project/flask_typed_routes)\n\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://rmoralespp.github.io/flask_typed_routes/\" target=\"_blank\"\u003e\n        \u003cimg class=\"off-glb\" src=\"https://raw.githubusercontent.com/rmoralespp/flask_typed_routes/main/docs/images/logo.svg\" \n             width=\"20%\" height=\"auto\" alt=\"logo\"\u003e\n    \u003c/a\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\u003cb\u003eValidate requests with Pydantic based on standard Python type hints.\u003c/b\u003e\u003c/div\u003e\n\n## About \n\n**flask_typed_routes** is a `Flask` extension designed to effortlessly validate requests with `Pydantic` based on standard Python type hints.\n\n**Documentation**: https://rmoralespp.github.io/flask_typed_routes/\n\n## Features\n\n- **Easy:** Easy to use and integrate with [Flask applications](https://flask.palletsprojects.com).\n- **Standard-based:** Based on [OpenAPI Specification](https://spec.openapis.org/oas/v3.1.0)\n- **Data validation:** Fast data verification based on [Pydantic](https://docs.pydantic.dev/)\n\n## Requirements\n\n- Python 3.10+\n- Pydantic 2.0+\n- Flask\n\n## Installation\n\nTo install **flask_typed_routes** using `pip`, run the following command:\n\n```bash\npip install flask_typed_routes\n```\n\n## Getting Started\n\nThis tool allows you to validate request parameters in Flask, similar to how FastAPI handles validation. It supports \n**Path**, **Query**, **Header**, **Cookie**, and **Body** validation.\n\n\n## Example\n\nCreate a file `items.py` with:\n\n```python\n# -*- coding: utf-8 -*-\n\nimport flask\nimport flask_typed_routes as ftr\n\napp = flask.Flask(__name__)\nftr.FlaskTypedRoutes(app=app)\n\n\n@app.get(\"/\")\ndef read_root():\n    return flask.jsonify({\"Hello\": \"World\"})\n\n\n@app.get(\"/items/\u003cuser\u003e/\")\ndef read_items(user: str, skip: int = 0, limit: int = 10):\n    return flask.jsonify({\"user\": user, \"skip\": skip, \"limit\": limit})\n```\n\n**Run the server with:**\n\n```bash\nflask --app items run --debug\n```\n\nOpen your browser and go to `http://127.0.0.1:5000/items/myuser/?skip=20`\nYou will see the JSON response as:\n\n```json\n{\n  \"limit\": 10,\n  \"skip\": 20,\n  \"user\": \"myuser\"\n}\n```\n\n**Validation:** Open your browser and go to `http://127.0.0.1:5000/items/myuser/?skip=abc`\nYou will see the JSON response with the error details because the `skip` parameter is not an integer:\n\n```json\n{\n  \"errors\": [\n    {\n      \"input\": \"abc\",\n      \"loc\": [\n        \"query\",\n        \"skip\"\n      ],\n      \"msg\": \"Input should be a valid integer, unable to parse string as an integer\",\n      \"type\": \"int_parsing\",\n      \"url\": \"https://errors.pydantic.dev/2.9/v/int_parsing\"\n    }\n  ]\n}\n```\n\n### Example Body Validation\n\nYou can also use Pydantic models to validate the request body.\n\nNow let's update the `items.py` file with:\n\n```python\n# -*- coding: utf-8 -*-\n\nimport flask\nimport flask_typed_routes as ftr\nimport pydantic\n\n\napp = flask.Flask(__name__)\nftr.FlaskTypedRoutes(app=app)\n\n\nclass Item(pydantic.BaseModel):\n    name: str\n    price: float\n    description: str = None\n\n\n@app.get(\"/\")\ndef read_root():\n    return flask.jsonify({\"Hello\": \"World\"})\n\n\n@app.get(\"/items/\u003cuser\u003e/\")\ndef read_items(user: str, skip: int = 0, limit: int = 10):\n    return flask.jsonify({\"user\": user, \"skip\": skip, \"limit\": limit})\n\n\n@app.post('/items/')\ndef create_item(item: Item):\n    return flask.jsonify(item.model_dump())\n\n\n@app.put('/items/\u003citem_id\u003e/')\ndef update_item(item_id: int, item: Item):\n    return flask.jsonify({'item_id': item_id, **item.model_dump()})\n```\n\n### Example Flask Blueprints\n\nNow let's update the `items.py` file with:\n\n```python\n# -*- coding: utf-8 -*-\n\nimport flask\nimport flask_typed_routes as ftr\n\napp = flask.Flask(__name__)\nftr.FlaskTypedRoutes(app=app)\norders = flask.Blueprint('orders', __name__)\n\n\n@orders.get(\"/orders/\u003cuser\u003e/\")\ndef read_orders(user: str, skip: int = 0, limit: int = 10):\n    return flask.jsonify({\"user\": user, \"skip\": skip, \"limit\": limit})\n\n\napp.register_blueprint(orders)\n```\n\n### Example Flask Class-Based Views\n\nNow let's update the `items.py` file with:\n\n```python\n# -*- coding: utf-8 -*-\n\nimport flask\nimport flask.views\nimport flask_typed_routes as ftr\n\napp = flask.Flask(__name__)\nftr.FlaskTypedRoutes(app=app)\n\n\nclass UserProducts(flask.views.View):\n\n    def dispatch_request(self, user: str, skip: int = 0, limit: int = 10):\n        data = {'user': user, 'skip': skip, 'limit': limit}\n        return flask.jsonify(data)\n\n\nclass UserOrders(flask.views.MethodView):\n\n    def get(self, user: str, skip: int = 0, limit: int = 10):\n        data = {'user': user, 'skip': skip, 'limit': limit}\n        return flask.jsonify(data)\n\n\napp.add_url_rule('/products/\u003cuser\u003e/', view_func=UserProducts.as_view('user_products'))\napp.add_url_rule('/orders/\u003cuser\u003e/', view_func=UserOrders.as_view('user_orders'))\n```\n\n### Interactive API docs\n\nYou can generate interactive API docs for your Flask application using OpenAPI schema generated by `flask_typed_routes`\nwith any OpenAPI UI library. For example, you can use `swagger-ui-py` to generate the API docs.\n\n```bash\npip install swagger-ui-py  # ignore if already installed\n```\n\n```python\n# -*- coding: utf-8 -*-\n\nimport flask\nimport flask_typed_routes as ftr\nimport pydantic\nimport swagger_ui\n\napp = flask.Flask(__name__)\napp_ftr = ftr.FlaskTypedRoutes(app=app)\n\n\nclass Item(pydantic.BaseModel):\n    name: str\n    price: float\n    description: str = None\n\n\n@app.get('/items/\u003cuser\u003e/')\ndef read_items(user: str, skip: int = 0, limit: int = 10):\n    data = {'user': user, 'skip': skip, 'limit': limit}\n    return flask.jsonify(data)\n\n\n@app.post('/items/')\ndef create_item(item: Item):\n    return flask.jsonify(item.model_dump())\n\n\n@app.put('/items/\u003citem_id\u003e/')\ndef update_item(item_id: int, item: Item):\n    return flask.jsonify({'item_id': item_id, **item.model_dump()})\n\n\n@app.delete('/items/\u003citem_id\u003e/')\ndef remove_item(item_id: int):\n    return flask.jsonify({'item_id': item_id})\n\n\nswagger_ui.api_doc(app, config=app_ftr.get_openapi_schema(), url_prefix='/docs')\n```\n\nOpen your browser and go to `http://127.0.0.1:5000/docs/`\n\n![OpenApi Example](https://raw.githubusercontent.com/rmoralespp/flask_typed_routes/main/docs/images/openapi1.png)\n\n**Create item** endpoint:\n\n![OpenApi Example](https://raw.githubusercontent.com/rmoralespp/flask_typed_routes/main/docs/images/openapi2.png)\n\n**Read Items** endpoint:\n\n![OpenApi Example](https://raw.githubusercontent.com/rmoralespp/flask_typed_routes/main/docs/images/openapi3.png)\n\n## Documentation\n\nFor more detailed information and usage examples, refer to the\nproject [documentation](https://rmoralespp.github.io/flask_typed_routes/)\n\n## Development\n\nTo contribute to the project, you can run the following commands for testing and documentation:\n\n### Setting up the Development Environment\n\nEnsure you have PIP updated:\n\n```bash\npython -m pip install --upgrade pip\n```\n\n### Running Unit Tests\n\nInstall the test dependencies and run the tests:\n\n```bash\npip install --group=test --upgrade  # Skip if already installed\npython -m pytest tests/\npython -m pytest --cov  # With coverage report\n```\n\n### Running the Linter\nTo run the linter, use the following commands:\n\n```bash\npip install --group=lint --upgrade  # Skip if already installed\nruff check .\n```\n\n### Building the Documentation\n\nTo build the documentation locally, use the following commands:\n\n```bash\npip install --group=doc --upgrade  # Skip if already installed\nmkdocs serve  # Start live-reloading docs server\nmkdocs build  # Build the documentation site\n```\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmoralespp%2Fflask_typed_routes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frmoralespp%2Fflask_typed_routes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmoralespp%2Fflask_typed_routes/lists"}