Name | flask-typed-routes JSON |
Version |
0.2.5
JSON |
| download |
home_page | None |
Summary | Flask extension designed to effortlessly validate requests with Pydantic based on standard Python type hints. |
upload_time | 2025-02-18 15:39:01 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.10 |
license | MIT License
Copyright (c) 2024 Rolando Morales Perez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
|
keywords |
python
flask
pydantic
validation
extension
typing
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
[](https://github.com/rmoralespp/flask_typed_routes/actions?query=event%3Arelease+workflow%3ACI)
[](https://pypi.python.org/pypi/flask_typed_routes)
[](https://app.codecov.io/gh/rmoralespp/flask_typed_routes)
[](https://github.com/rmoralespp/flask_typed_routes/blob/main/LICENSE)
[](https://pepy.tech/project/flask_typed_routes)
<div align="center">
<a href="https://rmoralespp.github.io/flask_typed_routes/" target="_blank">
<img class="off-glb" src="https://raw.githubusercontent.com/rmoralespp/flask_typed_routes/main/docs/images/logo.svg"
width="20%" height="auto" alt="logo">
</a>
</div>
<div align="center"><b>Validate requests with Pydantic based on standard Python type hints.</b></div>
## About
**flask_typed_routes** is a `Flask` extension designed to effortlessly validate requests with `Pydantic` based on standard Python type hints.
**Documentation**: https://rmoralespp.github.io/flask_typed_routes/
## Features
- **Easy:** Easy to use and integrate with [Flask applications](https://flask.palletsprojects.com).
- **Standard-based:** Based on [OpenAPI Specification](https://spec.openapis.org/oas/v3.1.0)
- **Data validation:** Fast data verification based on [Pydantic](https://docs.pydantic.dev/)
## Requirements
- Python 3.10+
- Pydantic 2.0+
- Flask
## Installation
To install **flask_typed_routes** using `pip`, run the following command:
```bash
pip install flask_typed_routes
```
## Getting Started
This tool allows you to validate request parameters in Flask, similar to how FastAPI handles validation. It supports
**Path**, **Query**, **Header**, **Cookie**, and **Body** validation.
## Example
Create a file `items.py` with:
```python
import flask
import flask_typed_routes as ftr
app = flask.Flask(__name__)
ftr.FlaskTypedRoutes(app=app)
@app.get("/")
def read_root():
return flask.jsonify({"Hello": "World"})
@app.get("/items/<user>/")
def read_items(user: str, skip: int = 0, limit: int = 10):
return flask.jsonify({"user": user, "skip": skip, "limit": limit})
```
**Run the server with:**
```bash
flask --app items run --debug
```
Open your browser and go to `http://127.0.0.1:5000/items/myuser/?skip=20`
You will see the JSON response as:
```json
{
"limit": 10,
"skip": 20,
"user": "myuser"
}
```
**Validation:** Open your browser and go to `http://127.0.0.1:5000/items/myuser/?skip=abc`
You will see the JSON response with the error details because the `skip` parameter is not an integer:
```json
{
"errors": [
{
"input": "abc",
"loc": [
"query",
"skip"
],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"type": "int_parsing",
"url": "https://errors.pydantic.dev/2.9/v/int_parsing"
}
]
}
```
### Example Body Validation
You can also use Pydantic models to validate the request body.
Now let's update the `items.py` file with:
```python
import flask
import flask_typed_routes as ftr
import pydantic
app = flask.Flask(__name__)
ftr.FlaskTypedRoutes(app=app)
class Item(pydantic.BaseModel):
name: str
price: float
description: str = None
@app.get("/")
def read_root():
return flask.jsonify({"Hello": "World"})
@app.get("/items/<user>/")
def read_items(user: str, skip: int = 0, limit: int = 10):
return flask.jsonify({"user": user, "skip": skip, "limit": limit})
@app.post('/items/')
def create_item(item: Item):
return flask.jsonify(item.model_dump())
@app.put('/items/<item_id>/')
def update_item(item_id: int, item: Item):
return flask.jsonify({'item_id': item_id, **item.model_dump()})
```
### Example Flask Blueprints
Now let's update the `items.py` file with:
```python
import flask
import flask_typed_routes as ftr
app = flask.Flask(__name__)
ftr.FlaskTypedRoutes(app=app)
orders = flask.Blueprint('orders', __name__)
@orders.get("/orders/<user>/")
def read_orders(user: str, skip: int = 0, limit: int = 10):
return flask.jsonify({"user": user, "skip": skip, "limit": limit})
app.register_blueprint(orders)
```
### Example Flask Class-Based Views
Now let's update the `items.py` file with:
```python
import flask
import flask.views
import flask_typed_routes as ftr
app = flask.Flask(__name__)
ftr.FlaskTypedRoutes(app=app)
class UserProducts(flask.views.View):
def dispatch_request(self, user: str, skip: int = 0, limit: int = 10):
data = {'user': user, 'skip': skip, 'limit': limit}
return flask.jsonify(data)
class UserOrders(flask.views.MethodView):
def get(self, user: str, skip: int = 0, limit: int = 10):
data = {'user': user, 'skip': skip, 'limit': limit}
return flask.jsonify(data)
app.add_url_rule('/products/<user>/', view_func=UserProducts.as_view('user_products'))
app.add_url_rule('/orders/<user>/', view_func=UserOrders.as_view('user_orders'))
```
### Interactive API docs
You can generate interactive API docs for your Flask application using OpenAPI schema generated by `flask_typed_routes`
with any OpenAPI UI library. For example, you can use `swagger-ui-py` to generate the API docs.
```bash
pip install swagger-ui-py # ignore if already installed
```
```python
import flask
import flask_typed_routes as ftr
import pydantic
import swagger_ui
app = flask.Flask(__name__)
app_ftr = ftr.FlaskTypedRoutes(app=app)
class Item(pydantic.BaseModel):
name: str
price: float
description: str = None
@app.get('/items/<user>/')
def read_items(user: str, skip: int = 0, limit: int = 10):
data = {'user': user, 'skip': skip, 'limit': limit}
return flask.jsonify(data)
@app.post('/items/')
def create_item(item: Item):
return flask.jsonify(item.model_dump())
@app.put('/items/<item_id>/')
def update_item(item_id: int, item: Item):
return flask.jsonify({'item_id': item_id, **item.model_dump()})
@app.delete('/items/<item_id>/')
def remove_item(item_id: int):
return flask.jsonify({'item_id': item_id})
swagger_ui.api_doc(app, config=app_ftr.get_openapi_schema(), url_prefix='/docs')
```
Open your browser and go to `http://127.0.0.1:5000/docs/`

**Create item** endpoint:

**Read Items** endpoint:

## Documentation
For more detailed information and usage examples, refer to the
project [documentation](https://rmoralespp.github.io/flask_typed_routes/)
## Development
To contribute to the project, you can run the following commands for testing and documentation:
### Running Unit Tests
Install the development dependencies and run the tests:
```
(env)$ pip install -r requirements-dev.txt # Skip if already installed
(env)$ python -m pytest tests/
(env)$ python -m pytest --cov # Run tests with coverage
```
### Building the Documentation
To build the documentation locally, use the following commands:
```
(env)$ pip install -r requirements-doc.txt # Skip if already installed
(env)$ mkdocs serve # Start live-reloading docs server
(env)$ mkdocs build # Build the documentation site
```
## License
This project is licensed under the [MIT license](LICENSE).
Raw data
{
"_id": null,
"home_page": null,
"name": "flask-typed-routes",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "python, flask, pydantic, validation, extension, typing",
"author": null,
"author_email": "rmoralespp <rmoralespp@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/29/69/15de0731c167bec421333350bafa71fcbf1a1bd7f1bd4862e65a424ee67c/flask_typed_routes-0.2.5.tar.gz",
"platform": null,
"description": "[](https://github.com/rmoralespp/flask_typed_routes/actions?query=event%3Arelease+workflow%3ACI)\n[](https://pypi.python.org/pypi/flask_typed_routes)\n[](https://app.codecov.io/gh/rmoralespp/flask_typed_routes)\n[](https://github.com/rmoralespp/flask_typed_routes/blob/main/LICENSE)\n[](https://pepy.tech/project/flask_typed_routes)\n\n<div align=\"center\">\n <a href=\"https://rmoralespp.github.io/flask_typed_routes/\" target=\"_blank\">\n <img class=\"off-glb\" src=\"https://raw.githubusercontent.com/rmoralespp/flask_typed_routes/main/docs/images/logo.svg\" \n width=\"20%\" height=\"auto\" alt=\"logo\">\n </a>\n</div>\n<div align=\"center\"><b>Validate requests with Pydantic based on standard Python type hints.</b></div>\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\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/<user>/\")\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\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/<user>/\")\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/<item_id>/')\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\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/<user>/\")\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\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/<user>/', view_func=UserProducts.as_view('user_products'))\napp.add_url_rule('/orders/<user>/', 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\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/<user>/')\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/<item_id>/')\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/<item_id>/')\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\n\n**Create item** endpoint:\n\n\n\n**Read Items** endpoint:\n\n\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### Running Unit Tests\n\nInstall the development dependencies and run the tests:\n\n```\n(env)$ pip install -r requirements-dev.txt # Skip if already installed\n(env)$ python -m pytest tests/\n(env)$ python -m pytest --cov # Run tests with coverage\n```\n\n### Building the Documentation\n\nTo build the documentation locally, use the following commands:\n\n```\n(env)$ pip install -r requirements-doc.txt # Skip if already installed\n(env)$ mkdocs serve # Start live-reloading docs server\n(env)$ mkdocs build # Build the documentation site\n```\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2024 Rolando Morales Perez\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n ",
"summary": "Flask extension designed to effortlessly validate requests with Pydantic based on standard Python type hints.",
"version": "0.2.5",
"project_urls": {
"Changelog": "https://github.com/rmoralespp/flask_typed_routes/blob/main/CHANGELOG.md",
"Documentation": "https://rmoralespp.github.io/flask_typed_routes/",
"Homepage": "https://github.com/rmoralespp/flask_typed_routes",
"Issues": "https://github.com/rmoralespp/flask_typed_routes/issues",
"Source": "https://github.com/rmoralespp/flask_typed_routes"
},
"split_keywords": [
"python",
" flask",
" pydantic",
" validation",
" extension",
" typing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7dc0ac4d74dc08ede754da9138fccc1d8c40a56e532ca6413e7f66e2297bbb6f",
"md5": "a1f600632ac87df849fa854a5264e4bd",
"sha256": "04ace19e66b07d60941a8eaefa4b64d43d5771723eadd4691e520aff90a15c95"
},
"downloads": -1,
"filename": "flask_typed_routes-0.2.5-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a1f600632ac87df849fa854a5264e4bd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 19166,
"upload_time": "2025-02-18T15:38:59",
"upload_time_iso_8601": "2025-02-18T15:38:59.787157Z",
"url": "https://files.pythonhosted.org/packages/7d/c0/ac4d74dc08ede754da9138fccc1d8c40a56e532ca6413e7f66e2297bbb6f/flask_typed_routes-0.2.5-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "296915de0731c167bec421333350bafa71fcbf1a1bd7f1bd4862e65a424ee67c",
"md5": "3b7c2c2d7b4c7bbe738f92c0e24b6a05",
"sha256": "bdc31e255c0fe36db99a005f0573ded36baed8b090e5ff1b3db833d850b7ed57"
},
"downloads": -1,
"filename": "flask_typed_routes-0.2.5.tar.gz",
"has_sig": false,
"md5_digest": "3b7c2c2d7b4c7bbe738f92c0e24b6a05",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 19566,
"upload_time": "2025-02-18T15:39:01",
"upload_time_iso_8601": "2025-02-18T15:39:01.712205Z",
"url": "https://files.pythonhosted.org/packages/29/69/15de0731c167bec421333350bafa71fcbf1a1bd7f1bd4862e65a424ee67c/flask_typed_routes-0.2.5.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-18 15:39:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rmoralespp",
"github_project": "flask_typed_routes",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "flask-typed-routes"
}