<p align="center">
<a href="https://www.xpresso-api.dev"><img src="https://github.com/adriangb/xpresso/raw/main/docs/assets/images/xpresso-title.png" alt="Xpresso"></a>
</p>
<p align="center">
<a href="https://github.com/adriangb/xpresso/actions?query=workflow%3ACI%2FCD+event%3Apush+branch%3Amain" target="_blank">
<img src="https://github.com/adriangb/xpresso/actions/workflows/workflow.yaml/badge.svg?event=push&branch=main" alt="Test">
</a>
<a href="https://codecov.io/gh/adriangb/xpresso" target="_blank">
<img src="https://img.shields.io/codecov/c/github/adriangb/xpresso?color=%2334D058" alt="Coverage">
</a>
<a href="https://pypi.org/project/xpresso" target="_blank">
<img src="https://img.shields.io/pypi/v/xpresso?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/xpresso" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/xpresso.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>
Xpresso is an ASGI web framework built on top of [Starlette], [Pydantic] and [di], with heavy inspiration from [FastAPI].
Some of the standout features are:
- ASGI support for high performance (within the context of Python web frameworks)
- OpenAPI documentation generation
- Automatic parsing and validation of request bodies and parameters, with hooks for custom extractors
- Full support for [OpenAPI parameter serialization](https://swagger.io/docs/specification/serialization/)
- Highly typed and tested codebase with great IDE support
- A powerful dependency injection system, backed by [di]
## Requirements
Python 3.7+
## Installation
```shell
pip install xpresso
```
You'll also want to install an ASGI server, such as [Uvicorn].
```shell
pip install uvicorn
```
## Example
Create a file named `example.py`:
```python
from pydantic import BaseModel
from xpresso import App, Path, FromPath, FromQuery
class Item(BaseModel):
item_id: int
name: str
async def read_item(item_id: FromPath[int], name: FromQuery[str]) -> Item:
return Item(item_id=item_id, name=name)
app = App(
routes=[
Path(
"/items/{item_id}",
get=read_item,
)
]
)
```
Run the application:
```shell
uvicorn example:app
```
Navigate to [http://127.0.0.1:8000/items/123?name=foobarbaz](http://127.0.0.1:8000/items/123?name=foobarbaz) in your browser.
You will get the following JSON response:
```json
{"item_id":123,"name":"foobarbaz"}
```
Now navigate to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) to poke around the interactive [Swagger UI] documentation:
![Swagger UI](docs/readme_example_swagger.png)
For more examples, tutorials and reference materials, see our [documentation].
## Inspiration and relationship to other frameworks
Xpresso is mainly inspired by FastAPI.
FastAPI pioneered several ideas that are core to Xpresso's approach:
- Leverage Pydantic for JSON parsing, validation and schema generation.
- Leverage Starlette for routing and other low level web framework functionality.
- Provide a simple but powerful dependency injection system.
- Use that dependency injection system to provide extraction of request bodies, forms, query parameters, etc.
Xpresso takes these ideas and refines them by:
- Decoupling the dependency injection system from the request/response cycle, leading to an overall much more flexible and powerful dependency injection system, packaged up as the standalone [di] library.
- Decoupling the framework from Pydantic by using `Annotated` ([PEP 593]) instead of default values (`param: FromQuery[str]` instead of `param: str = Query(...)`).
- [Middleware on Routers] so that you can use generic ASGI middleware in a routing-aware manner (for example, installing profiling middleware on only some paths without using regex matching).
- Support for [lifespans on any Router or mounted App] (this silently fails in FastAPI and Starlette)
- [dependency injection into the application lifespan] and support for [multiple dependency scopes].
- Formalizing the framework for extracting parameters and bodies from requests into the [Binder API] so that 3rd party extensions can do anything the framework does.
- Support for [customizing parameter and form serialization].
- Better performance by implementing [dependency resolution in Rust], [executing dependencies concurrently] and [controlling threading of sync dependencies on a per-dependency basis].
## Current state
This project is under active development.
It should not be considered "stable" or ready to be used in production.
It is however ready for experimentation and learning!
### What is implemented and mostly stable?
1. Extraction and OpenAPI documentation of parameters (query, headers, etc.) and request bodies (including multipart requests).
1. Parameter serialization.
1. Routing, including applications, routers and routes.
1. Dependency injection and testing utilities (dependency overrides).
Most of this APIs will be _generally_ stable going forward, although some minor aspects like argument names will probably change at some point.
### What is not implemented or unstable?
1. Low-level API for binders (stuff in `xpresso.binders`): this is public, but should be considered experimental and is likely to change. The high level APIs (`FromPath[str]` and `Annotated[str, PathParam(...)]`) are likely to be stable.
1. Security dependencies and OpenAPI integration. This part used to exist, but needed some work. It is planned for the future, but we need to think about the scope of these features and the API.
[Starlette]: https://github.com/encode/starlette
[Pydantic]: https://github.com/samuelcolvin/pydantic/
[FastAPI]: https://github.com/adriangb/xpresso
[di]: https://github.com/adriangb/di
[Uvicorn]: http://www.uvicorn.org/
[documentation]: https://www.xpresso-api.dev/
[Swagger UI]: https://swagger.io/tools/swagger-ui/
[dependency injection into the application lifespan]: https://xpresso-api.dev/latest/tutorial/lifespan
[multiple dependency scopes]: https://xpresso-api.dev/latest/tutorial/dependencies/scopes/
[dependency resolution in Rust]: https://github.com/adriangb/graphlib2
[executing dependencies concurrently]: https://xpresso-api.dev/latest/advanced/dependencies/performance/#concurrent-execution
[controlling threading of sync dependencies on a per-dependency basis]: https://xpresso-api.dev/latest/advanced/dependencies/performance/#sync-vs-async
[PEP 593]: https://www.python.org/dev/peps/pep-0593/
[Binder API]: https://xpresso-api.dev/latest/advanced/binders/
[customizing parameter and form serialization]: https://xpresso-api.dev/latest/tutorial/query_params/#customizing-deserialization
[lifespans on any Router or mounted App]: https://xpresso-api.dev/latest/tutorial/lifespan/
[Middleware on Routers]: https://xpresso-api.dev/0.14.1/tutorial/middleware/#middleware-on-routers
See this release on GitHub: [v0.46.0](https://github.com/adriangb/xpresso/releases/tag/0.46.0)
Raw data
{
"_id": null,
"home_page": "https://github.com/adriangb/xpresso",
"name": "xpresso",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7,<4",
"maintainer_email": "",
"keywords": "web-framework,http,openapi",
"author": "Adrian Garcia Badaracco",
"author_email": "adrian@adriangb.com",
"download_url": "https://files.pythonhosted.org/packages/9b/37/aa86b88be41bbf2a15264012076ab974b16390b625d8741cfcb6f1d9e306/xpresso-0.46.0.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <a href=\"https://www.xpresso-api.dev\"><img src=\"https://github.com/adriangb/xpresso/raw/main/docs/assets/images/xpresso-title.png\" alt=\"Xpresso\"></a>\n</p>\n\n<p align=\"center\">\n<a href=\"https://github.com/adriangb/xpresso/actions?query=workflow%3ACI%2FCD+event%3Apush+branch%3Amain\" target=\"_blank\">\n <img src=\"https://github.com/adriangb/xpresso/actions/workflows/workflow.yaml/badge.svg?event=push&branch=main\" alt=\"Test\">\n</a>\n<a href=\"https://codecov.io/gh/adriangb/xpresso\" target=\"_blank\">\n <img src=\"https://img.shields.io/codecov/c/github/adriangb/xpresso?color=%2334D058\" alt=\"Coverage\">\n</a>\n<a href=\"https://pypi.org/project/xpresso\" target=\"_blank\">\n <img src=\"https://img.shields.io/pypi/v/xpresso?color=%2334D058&label=pypi%20package\" alt=\"Package version\">\n</a>\n<a href=\"https://pypi.org/project/xpresso\" target=\"_blank\">\n <img src=\"https://img.shields.io/pypi/pyversions/xpresso.svg?color=%2334D058\" alt=\"Supported Python versions\">\n</a>\n</p>\n\nXpresso is an ASGI web framework built on top of [Starlette], [Pydantic] and [di], with heavy inspiration from [FastAPI].\n\nSome of the standout features are:\n\n- ASGI support for high performance (within the context of Python web frameworks)\n- OpenAPI documentation generation\n- Automatic parsing and validation of request bodies and parameters, with hooks for custom extractors\n- Full support for [OpenAPI parameter serialization](https://swagger.io/docs/specification/serialization/)\n- Highly typed and tested codebase with great IDE support\n- A powerful dependency injection system, backed by [di]\n\n## Requirements\n\nPython 3.7+\n\n## Installation\n\n```shell\npip install xpresso\n```\n\nYou'll also want to install an ASGI server, such as [Uvicorn].\n\n```shell\npip install uvicorn\n```\n\n## Example\n\nCreate a file named `example.py`:\n\n```python\nfrom pydantic import BaseModel\nfrom xpresso import App, Path, FromPath, FromQuery\n\nclass Item(BaseModel):\n item_id: int\n name: str\n\nasync def read_item(item_id: FromPath[int], name: FromQuery[str]) -> Item:\n return Item(item_id=item_id, name=name)\n\napp = App(\n routes=[\n Path(\n \"/items/{item_id}\",\n get=read_item,\n )\n ]\n)\n```\n\nRun the application:\n\n```shell\nuvicorn example:app\n```\n\nNavigate to [http://127.0.0.1:8000/items/123?name=foobarbaz](http://127.0.0.1:8000/items/123?name=foobarbaz) in your browser.\nYou will get the following JSON response:\n\n```json\n{\"item_id\":123,\"name\":\"foobarbaz\"}\n```\n\nNow navigate to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) to poke around the interactive [Swagger UI] documentation:\n\n![Swagger UI](docs/readme_example_swagger.png)\n\nFor more examples, tutorials and reference materials, see our [documentation].\n\n## Inspiration and relationship to other frameworks\n\nXpresso is mainly inspired by FastAPI.\nFastAPI pioneered several ideas that are core to Xpresso's approach:\n\n- Leverage Pydantic for JSON parsing, validation and schema generation.\n- Leverage Starlette for routing and other low level web framework functionality.\n- Provide a simple but powerful dependency injection system.\n- Use that dependency injection system to provide extraction of request bodies, forms, query parameters, etc.\n\nXpresso takes these ideas and refines them by:\n\n- Decoupling the dependency injection system from the request/response cycle, leading to an overall much more flexible and powerful dependency injection system, packaged up as the standalone [di] library.\n- Decoupling the framework from Pydantic by using `Annotated` ([PEP 593]) instead of default values (`param: FromQuery[str]` instead of `param: str = Query(...)`).\n- [Middleware on Routers] so that you can use generic ASGI middleware in a routing-aware manner (for example, installing profiling middleware on only some paths without using regex matching).\n- Support for [lifespans on any Router or mounted App] (this silently fails in FastAPI and Starlette)\n- [dependency injection into the application lifespan] and support for [multiple dependency scopes].\n- Formalizing the framework for extracting parameters and bodies from requests into the [Binder API] so that 3rd party extensions can do anything the framework does.\n- Support for [customizing parameter and form serialization].\n- Better performance by implementing [dependency resolution in Rust], [executing dependencies concurrently] and [controlling threading of sync dependencies on a per-dependency basis].\n\n## Current state\n\nThis project is under active development.\nIt should not be considered \"stable\" or ready to be used in production.\nIt is however ready for experimentation and learning!\n\n### What is implemented and mostly stable?\n\n1. Extraction and OpenAPI documentation of parameters (query, headers, etc.) and request bodies (including multipart requests).\n1. Parameter serialization.\n1. Routing, including applications, routers and routes.\n1. Dependency injection and testing utilities (dependency overrides).\n\nMost of this APIs will be _generally_ stable going forward, although some minor aspects like argument names will probably change at some point.\n\n### What is not implemented or unstable?\n\n1. Low-level API for binders (stuff in `xpresso.binders`): this is public, but should be considered experimental and is likely to change. The high level APIs (`FromPath[str]` and `Annotated[str, PathParam(...)]`) are likely to be stable.\n1. Security dependencies and OpenAPI integration. This part used to exist, but needed some work. It is planned for the future, but we need to think about the scope of these features and the API.\n\n[Starlette]: https://github.com/encode/starlette\n[Pydantic]: https://github.com/samuelcolvin/pydantic/\n[FastAPI]: https://github.com/adriangb/xpresso\n[di]: https://github.com/adriangb/di\n[Uvicorn]: http://www.uvicorn.org/\n[documentation]: https://www.xpresso-api.dev/\n[Swagger UI]: https://swagger.io/tools/swagger-ui/\n[dependency injection into the application lifespan]: https://xpresso-api.dev/latest/tutorial/lifespan\n[multiple dependency scopes]: https://xpresso-api.dev/latest/tutorial/dependencies/scopes/\n[dependency resolution in Rust]: https://github.com/adriangb/graphlib2\n[executing dependencies concurrently]: https://xpresso-api.dev/latest/advanced/dependencies/performance/#concurrent-execution\n[controlling threading of sync dependencies on a per-dependency basis]: https://xpresso-api.dev/latest/advanced/dependencies/performance/#sync-vs-async\n[PEP 593]: https://www.python.org/dev/peps/pep-0593/\n[Binder API]: https://xpresso-api.dev/latest/advanced/binders/\n[customizing parameter and form serialization]: https://xpresso-api.dev/latest/tutorial/query_params/#customizing-deserialization\n[lifespans on any Router or mounted App]: https://xpresso-api.dev/latest/tutorial/lifespan/\n[Middleware on Routers]: https://xpresso-api.dev/0.14.1/tutorial/middleware/#middleware-on-routers\n\nSee this release on GitHub: [v0.46.0](https://github.com/adriangb/xpresso/releases/tag/0.46.0)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A developer centric, performant Python web framework",
"version": "0.46.0",
"split_keywords": [
"web-framework",
"http",
"openapi"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "004e4da53fbdce35077baab3afd537a3",
"sha256": "72034522eee732a78c4ddf67ec6c10080b499eb9e7f32dba43d5464b0a71b5d1"
},
"downloads": -1,
"filename": "xpresso-0.46.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "004e4da53fbdce35077baab3afd537a3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7,<4",
"size": 62846,
"upload_time": "2022-12-21T18:32:14",
"upload_time_iso_8601": "2022-12-21T18:32:14.729706Z",
"url": "https://files.pythonhosted.org/packages/21/50/a4fd8df8b74590c18a1381a7774cc137a7882d70203d48ef6dc211410f9f/xpresso-0.46.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "536b59eeb84ebcf83a977a4f1b88baf1",
"sha256": "04eb84086f49e8e8c8876e9c4f42e427b87497369d91afca6d464ab17b2ee91f"
},
"downloads": -1,
"filename": "xpresso-0.46.0.tar.gz",
"has_sig": false,
"md5_digest": "536b59eeb84ebcf83a977a4f1b88baf1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7,<4",
"size": 44203,
"upload_time": "2022-12-21T18:32:16",
"upload_time_iso_8601": "2022-12-21T18:32:16.353098Z",
"url": "https://files.pythonhosted.org/packages/9b/37/aa86b88be41bbf2a15264012076ab974b16390b625d8741cfcb6f1d9e306/xpresso-0.46.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-21 18:32:16",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "adriangb",
"github_project": "xpresso",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "xpresso"
}