From 56deabb560119b674f6f3bfbb4d56be7e5317170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 10 Dec 2018 07:55:59 +0400 Subject: [PATCH] :memo: Update README.md --- README.md | 295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..3557be2a4 --- /dev/null +++ b/README.md @@ -0,0 +1,295 @@ +

+ FastAPI +

+

+ FastAPI framework, high performance, easy to learn, fast to code, ready for production +

+

+ + Build Status + + + Coverage + + + Package version + +

+ +--- + +**Documentation**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com) + +--- + +FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+. + +The key features are: + +* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). +* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. +* **Easy**: Designed to be easy to use and learn. Less time reading docs. +* **Short**: Minimize code duplication. Multiple features from each parameter declaration. +* **Robust**: Get production-ready code. With automatic interactive documentation. +* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI and JSON Schema. + + +## Requirements + +Python 3.6+ + +FastAPI stands on the shoulders of giants: + +* Starlette for the web parts. +* Pydantic for the data parts. + + +## Installation + +```shell +$ pip3 install fastapi +``` + +You will also need an ASGI server, for production such as uvicorn. + +```shell +$ pip3 install uvicorn +``` + +## Example + +* Create a file `main.py` with: + +```Python +from fastapi import FastAPI + +app = FastAPI() + +@app.get('/') +async def read_root(): + return {'hello': 'world'} +``` + +* Run the server with: + +```bash +uvicorn main:app --debug +``` + +**Note**: the command `uvicorn main:app` refers to: + +* `main`: the file `main.py` (the Python "module"). +* `app`: the object created inside of `main.py` with the line `app = FastAPI()`. +* `--debug`: make the server restart after code changes. Only use for development. + +### Check it + +Open your browser at http://127.0.0.1:8000. + +You will see the JSON response as: + +```JSON +{"hello": "world"} +``` + +### Interactive API docs + +Now go to http://127.0.0.1:8000/docs. + +You will see the automatic interactive API documentation (provided by Swagger UI): + +![Swagger UI](img/index/index-01-swagger-ui-simple.png) + + +### Alternative API docs + +And now, go to http://127.0.0.1:8000/redoc. + +You will see the alternative automatic documentation (provided by ReDoc): + +![ReDoc](img/index/index-02-redoc-simple.png) + +## Example upgrade + +Now modify the file `main.py` to include: + +* a path parameter `item_id`. +* a body, declared using standard Python types (thanks to Pydantic). +* an optional query parameter `q`. + + +```Python +from fastapi import FastAPI +from pydantic import BaseModel + +app = FastAPI() + + +class Item(BaseModel): + name: str + price: float + is_offer: bool = None + + +@app.get('/') +async def read_root(): + return {'hello': 'world'} + + +@app.post('/items/{item_id}') +async def create_item(item_id: int, item: Item, q: str = None): + return {"item_name": item.name, "item_id": item_id, "query": q} +``` + +The server should reload automatically (because you added `--debug` to the `uvicorn` command above). + +### Interactive API docs upgrade + +Now go to http://127.0.0.1:8000/docs. + +* The interactive API documentation will be automatically updated, including the new query, and body: + +![Swagger UI](img/index/index-03-swagger-02.png) + +* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API: + +![Swagger UI interaction](img/index/index-04-swagger-03.png) + +* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen: + +![Swagger UI interaction](img/index/index-05-swagger-04.png) + + +### Alternative API docs upgrade + +And now, go to http://127.0.0.1:8000/redoc. + +* The alternative documentation will also reflect the new query parameter and body: + +![ReDoc](img/index/index-06-redoc-02.png) + + +### Recap + +In summary, you declare **once** the types of parameters, body, etc. as function parameters. You don't have to learn a new syntax, use a specific library, class or object to declare fields, you just type standard Python types. + +For example, for an `int`: + +```Python +item_id: int +``` + +or for a more complex `Item` model: + +```Python +item: Item +``` + +...and with that single declaration you get: + +* Editor support, including: + * Completion. + * Type checks. +* Validation of data: + * Automatic and clear errors when the data is invalid. + * Validation even for deeply nested JSON objects. +* Serialization of input data: from the network to Python, reading from: + * JSON. + * Forms. + * Files. + * Path parameters. + * Query parameters. + * Cookies. + * Headers. +* Serialization of output data: from Python to network (as JSON): + * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc). + * `datetime` objects. + * `UUID` objects. + * Database models. + * ...and many more. +* Automatic interactive API documentation, including 2 alternative user interfaces: + * Swagger UI. + * ReDoc. + +--- + +Coming back to the previous code example, **FastAPI** will: + +* Validate that there is an `item_id` in the path. +* Validate that the `item_id` is of type `int`. If it is not, the client will see a useful error. +* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`). As the `q` parameter is declared with `= None`, it is optional. Without the `None` it would be required (as is the body). +* Read the body as JSON: + * Check that it has a required attribute `name` that should be a `str`. + * Check that is has a required attribute `price` that has to be a `float`. + * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present. + * All this would also work for deeply nested JSON objects +* Convert from and to JSON automatically. +* Document everything as OpenAPI, so the interactive documentation is created and updated automatically. +* Provide the interactive documentation web interfaces. + + +--- + +We just scratched the surface, but you already get the idea of how it all works. + +Try changing the line with: + +```Python + return {"item_name": item.name, "item_id": item_id, "query": q} +``` + +...from: + +```Python + ... "item_name": item.name ... +``` + +...to: + +```Python + ... "item_price": item.price ... +``` + +...and see how your editor will auto-complete the attributes and know their types: + +![editor support](img/vscode-completion.png) + + +For a more complete example including more features, [see the tutorial](tutorial). + +**Spoiler alert**: the tutorial, although very short, includes: + +* Declaration of **parameters** from different places as: headers, cookies, form data and files. +* How to set **validation constrains** as `maximum_length` or `regex`. +* A very powerful and easy to use **Dependency Injection** system (also known as "components", "resources", "providers", "services"). +* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth. +* More advanced (but equally easy) techniques for declaring **deeply nested models** (JSON body, Form and Files) (thanks to Pydantic). +* Many extra features (thanks to Starlette) as **WebSockets**, **GraphQL**, extremely easy tests based on `requests` and `pytest`, CORS, Cookie Sessions and more. + + + +## Optional Dependencies + +Used by Pydantic: + +* ujson - for faster JSON parsing. +* email_validator - for email validation. + + +Used by Starlette: + +* requests - Required if you want to use the `TestClient`. +* aiofiles - Required if you want to use `FileResponse` or `StaticFiles`. +* jinja2 - Required if you want to use the default template configuration. +* python-multipart - Required if you want to support form parsing, with `request.form()`. +* itsdangerous - Required for `SessionMiddleware` support. +* pyyaml - Required for `SchemaGenerator` support. +* graphene - Required for `GraphQLApp` support. +* ujson - Required if you want to use `UJSONResponse`. + + +You can install all of these with `pip3 install fastapi[full]`. + +## License + +This project is licensed under the terms of the MIT license.