# Python request mapper
Map and validate incoming request data to Pydantic models. Request-mapper is framework agnostic with first-party
support for Flask.
## Examples
```python
# Add this in your app initialization code.
setup_mapper(
integration=FlaskIntegration(
# Automatically decorate views to avoid adding @map_request to every view.
# Will not incur any performance overhead for views that don't use request-mapper.
# If map_views is enabled, setup_mapper must be called after
# all views have been registered!
map_views=True,
# Register an error handler that returns 422 alongside pydantic validation errors
# when the request cannot be mapped.
add_error_handler=True,
)
)
# Define models using Pydantic v1 or v2.
class PostCreateRequest(BaseModel):
title: str
content: str
class PostFilterQuery(BaseModel):
status: PostStatus | None = None
@app.get("/posts")
# Map data from the current request.
def post_list_all(query: FromQueryString[PostFilterQuery]) -> PaginatedResponse[Post]:
# "query" is a valid pydantic model at this point.
return PaginatedResponse(...)
@app.post("/posts")
def post_create(body: FromRequestBody[PostCreateRequest]) -> PostCreateResponse:
# "body" is a valid pydantic model at this point.
return PostCreateResponse(...)
```
## Quickstart
* `pip install request-mapper`.
* In your application setup, call `mapper.setup_mapper` with the integration of your choice.
* Decorate targets with `@map_request` (Optional when using flask integration)
* Map request data using one of the provided annotated types
* `FromQueryString[T]` or `Annotated[T, QueryStringMapping()]`
* `FromRequestBody[T]` or `Annotated[T, RequestBodyMapping()]`
* `FromFormData[T]` or `Annotated[T, FormDataMapping()]`
## Integrations
### Flask
* Pull data from flask's request args, json and form data.
* Optional: Automatically map views without having to decorate them.
* Views which do not use request mapper will not incur any performance penalty.
* When using this feature the call to `setup_mapper` must be AFTER all views are registered.
* Optional: Set up an error handler for validation errors which makes the api respond with a 422.
### Custom integrations
You can create your own integration by inheriting `BaseIntegration` and supplying an instance of that
to the `setup_mapper` call.
Note that you must decorate your views with `@map_request`
Raw data
{
"_id": null,
"home_page": "",
"name": "request-mapper",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "flask,django,pydantic,request mapper,request model,model",
"author": "Aldo Mateli",
"author_email": "aldo.mateli@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/13/82/dc6234d85e9d48904d4500d0232b2c109c1c2baa8abd0e95da0c766fb291/request_mapper-0.1.0.tar.gz",
"platform": null,
"description": "# Python request mapper\n\nMap and validate incoming request data to Pydantic models. Request-mapper is framework agnostic with first-party\nsupport for Flask.\n\n## Examples\n\n```python\n# Add this in your app initialization code.\nsetup_mapper(\n integration=FlaskIntegration(\n # Automatically decorate views to avoid adding @map_request to every view.\n # Will not incur any performance overhead for views that don't use request-mapper.\n \n # If map_views is enabled, setup_mapper must be called after \n # all views have been registered!\n map_views=True,\n # Register an error handler that returns 422 alongside pydantic validation errors\n # when the request cannot be mapped.\n add_error_handler=True,\n )\n)\n\n\n# Define models using Pydantic v1 or v2.\nclass PostCreateRequest(BaseModel):\n title: str\n content: str\n\n\nclass PostFilterQuery(BaseModel):\n status: PostStatus | None = None\n\n\n@app.get(\"/posts\")\n# Map data from the current request.\ndef post_list_all(query: FromQueryString[PostFilterQuery]) -> PaginatedResponse[Post]:\n # \"query\" is a valid pydantic model at this point.\n return PaginatedResponse(...)\n\n\n@app.post(\"/posts\")\ndef post_create(body: FromRequestBody[PostCreateRequest]) -> PostCreateResponse:\n # \"body\" is a valid pydantic model at this point.\n return PostCreateResponse(...)\n\n```\n\n## Quickstart\n\n* `pip install request-mapper`.\n* In your application setup, call `mapper.setup_mapper` with the integration of your choice.\n* Decorate targets with `@map_request` (Optional when using flask integration)\n* Map request data using one of the provided annotated types\n * `FromQueryString[T]` or `Annotated[T, QueryStringMapping()]`\n * `FromRequestBody[T]` or `Annotated[T, RequestBodyMapping()]`\n * `FromFormData[T]` or `Annotated[T, FormDataMapping()]`\n\n## Integrations\n\n### Flask\n\n* Pull data from flask's request args, json and form data.\n* Optional: Automatically map views without having to decorate them.\n * Views which do not use request mapper will not incur any performance penalty.\n * When using this feature the call to `setup_mapper` must be AFTER all views are registered.\n* Optional: Set up an error handler for validation errors which makes the api respond with a 422.\n\n### Custom integrations\n\nYou can create your own integration by inheriting `BaseIntegration` and supplying an instance of that\nto the `setup_mapper` call.\n\nNote that you must decorate your views with `@map_request`\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Map request data into pydantic models",
"version": "0.1.0",
"project_urls": null,
"split_keywords": [
"flask",
"django",
"pydantic",
"request mapper",
"request model",
"model"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1621133137a85b7b8801659b1709df414fafca7458948895354546aed980760f",
"md5": "02ecaecb2fc8649ff33e47594ab8d1af",
"sha256": "4aa75b3eafb48dfbeee733aac468fa18fcfe879610a9a6965ad6711c7203afa6"
},
"downloads": -1,
"filename": "request_mapper-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "02ecaecb2fc8649ff33e47594ab8d1af",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 6581,
"upload_time": "2023-11-03T20:51:01",
"upload_time_iso_8601": "2023-11-03T20:51:01.391460Z",
"url": "https://files.pythonhosted.org/packages/16/21/133137a85b7b8801659b1709df414fafca7458948895354546aed980760f/request_mapper-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1382dc6234d85e9d48904d4500d0232b2c109c1c2baa8abd0e95da0c766fb291",
"md5": "a90bc72b9719b0d7e29cdda05d1ec735",
"sha256": "62343e4603e58bfd739c479d145f258eda1352d3e8f470afbae3f12583e6180b"
},
"downloads": -1,
"filename": "request_mapper-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "a90bc72b9719b0d7e29cdda05d1ec735",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 5485,
"upload_time": "2023-11-03T20:51:03",
"upload_time_iso_8601": "2023-11-03T20:51:03.580236Z",
"url": "https://files.pythonhosted.org/packages/13/82/dc6234d85e9d48904d4500d0232b2c109c1c2baa8abd0e95da0c766fb291/request_mapper-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-03 20:51:03",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "request-mapper"
}