mirror of https://github.com/tiangolo/fastapi.git
📝 Update docs, use the term path operation
This commit is contained in:
parent
617a260df6
commit
8628120873
|
|
@ -1,4 +1,4 @@
|
|||
Details about the `async def` syntax for endpoint functions and some background about asynchronous code, concurrency, and parallelism.
|
||||
Details about the `async def` syntax for path operation functions and some background about asynchronous code, concurrency, and parallelism.
|
||||
|
||||
|
||||
## In a hurry?
|
||||
|
|
@ -12,7 +12,7 @@ If you are using third party libraries that tell you to call them with `await`,
|
|||
results = await some_library()
|
||||
```
|
||||
|
||||
Then, declare your endpoint functions with `async def` like:
|
||||
Then, declare your path operation functions with `async def` like:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
|
|
@ -26,7 +26,7 @@ async def read_results():
|
|||
|
||||
---
|
||||
|
||||
If you are using a third party library that communicates with something (a database, an API, the file system, etc) and doesn't have support for using `await`, (this is currently the case for most database libraries), then declare your endpoint functions as normally, with just `def`, like:
|
||||
If you are using a third party library that communicates with something (a database, an API, the file system, etc) and doesn't have support for using `await`, (this is currently the case for most database libraries), then declare your path operation functions as normally, with just `def`, like:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
|
|
@ -45,7 +45,7 @@ If you just don't know, use normal `def`.
|
|||
|
||||
---
|
||||
|
||||
**Note**: you can mix `def` and `async def` in your endpoints as much as you need and define each one using the best option for you. FastAPI will do the right thing with them.
|
||||
**Note**: you can mix `def` and `async def` in your path operation functions as much as you need and define each one using the best option for you. FastAPI will do the right thing with them.
|
||||
|
||||
Anyway, in any of the cases above, FastAPI will still work asynchronously and be extremely fast.
|
||||
|
||||
|
|
@ -310,7 +310,7 @@ burgers = get_burgers(2)
|
|||
|
||||
---
|
||||
|
||||
So, if you are using a library that tells you that you can call it with `await`, you need to create the endpoint that uses it with `async def`, like in:
|
||||
So, if you are using a library that tells you that you can call it with `await`, you need to create the path operation functions that uses it with `async def`, like in:
|
||||
|
||||
```Python hl_lines="2 3"
|
||||
@app.get('/burgers')
|
||||
|
|
@ -327,7 +327,7 @@ But at the same time, functions defined with `async def` have to be "awaited". S
|
|||
|
||||
So, about the egg and the chicken, how do you call the first `async` function?
|
||||
|
||||
If you are working with **FastAPI** you don't have to worry about that, because that "first" function will be your endpoint, and FastAPI will know how to do the right thing.
|
||||
If you are working with **FastAPI** you don't have to worry about that, because that "first" function will be your path operation function, and FastAPI will know how to do the right thing.
|
||||
|
||||
But if you want to use `async` / `await` without FastAPI, <a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" target="_blank">check the official Python docs</a>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
### Based on open standards
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of endpoints, parameters, body requests, security, etc.
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <abbr title="also known as: endpoints, routes">path</abbr> <abbr title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>, parameters, body requests, security, etc.
|
||||
* Automatic data model documentation with <a href="http://json-schema.org/" target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
|
||||
* Designed around these standards, after a meticulous study. Instead of an afterthought layer on top.
|
||||
* This also allows using automatic **client code generation** in many languages.
|
||||
|
|
@ -139,8 +139,8 @@ FastAPI includes an extremely easy to use, but extremely powerful <abbr title='a
|
|||
|
||||
* Even dependencies can have dependencies, creating a hierarchy or **"graph" of dependencies**.
|
||||
* All **automatically handled** by the framework.
|
||||
* All the dependencies can require data from requests and **augment the endpoint** constraints and automatic documentation.
|
||||
* **Automatic validation** even for endpoint parameters defined in dependencies.
|
||||
* All the dependencies can require data from requests and **augment the path operation** constraints and automatic documentation.
|
||||
* **Automatic validation** even for path operation parameters defined in dependencies.
|
||||
* Support for complex user authentication systems, **database connections**, etc.
|
||||
* **No compromise** with databases, frontends, etc. But easy integration with all of them.
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ FastAPI includes an extremely easy to use, but extremely powerful <abbr title='a
|
|||
|
||||
Or in other way, no need for them, import and use the code you need.
|
||||
|
||||
Any integration is designed to be so simple to use (with dependencies) that you can create a "plug-in" for your application in 2 lines of code using the same structure and syntax used for your endpoints.
|
||||
Any integration is designed to be so simple to use (with dependencies) that you can create a "plug-in" for your application in 2 lines of code using the same structure and syntax used for your path operations.
|
||||
|
||||
|
||||
### Tested
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ uvicorn main:app --debug
|
|||
|
||||
* `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.
|
||||
* `--debug`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
### Check it
|
||||
|
||||
|
|
@ -195,7 +195,13 @@ And now, go to <a href="http://127.0.0.1:8000/redoc" target="_blank">http://127.
|
|||
|
||||
### 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.
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.6+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
|
|
@ -217,15 +223,15 @@ item: Item
|
|||
* Validation of data:
|
||||
* Automatic and clear errors when the data is invalid.
|
||||
* Validation even for deeply nested JSON objects.
|
||||
* Serialization of input data: conversion of data coming from the network to Python data and types. Reading from:
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network, to Python data and types. Reading from:
|
||||
* JSON.
|
||||
* Forms.
|
||||
* Files.
|
||||
* Path parameters.
|
||||
* Query parameters.
|
||||
* Cookies.
|
||||
* Headers.
|
||||
* Serialization of output data: converting from Python data and types to network data (as JSON):
|
||||
* Forms.
|
||||
* Files.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
|
||||
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
|
||||
* `datetime` objects.
|
||||
* `UUID` objects.
|
||||
|
|
@ -240,16 +246,21 @@ item: Item
|
|||
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).
|
||||
* Validate that the `item_id` is of type `int`.
|
||||
* If it is not, the client will see a useful, clear 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
|
||||
* 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.
|
||||
* Document everything as an OpenAPI schema, that can be used by:
|
||||
* Interactive documentation sytems.
|
||||
* Automatic client code generation systems, for many languages.
|
||||
* Provide 2 interactive documentation web interfaces directly.
|
||||
|
||||
|
||||
---
|
||||
|
|
@ -281,14 +292,20 @@ Try changing the line with:
|
|||
|
||||
For a more complete example including more features, [see the tutorial](tutorial/intro/).
|
||||
|
||||
**Spoiler alert**: the tutorial, although very short, includes:
|
||||
**Spoiler alert**: the tutorial includes:
|
||||
|
||||
* Declaration of **parameters** from different places as: headers, cookies, form data and files.
|
||||
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** 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").
|
||||
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
|
||||
* 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.
|
||||
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (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.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ First, of course, you can mix `Path`, `Query` and request body parameter declara
|
|||
|
||||
## Multiple body parameters
|
||||
|
||||
In the previous example, the endpoint would expect a JSON body with the attributes of an `Item`, like:
|
||||
In the previous example, the path operations would expect a JSON body with the attributes of an `Item`, like:
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
|
@ -158,9 +158,9 @@ instead of:
|
|||
|
||||
## Recap
|
||||
|
||||
You can add multiple body parameters to your function endpoint, even though a request can only have a single body.
|
||||
You can add multiple body parameters to your path operation function, even though a request can only have a single body.
|
||||
|
||||
But **FastAPI** will handle it, give you the correct data in your function, and validate and document the correct schema in the endpoint.
|
||||
But **FastAPI** will handle it, give you the correct data in your function, and validate and document the correct schema in the path operation.
|
||||
|
||||
You can also declare singular values to be received as part of the body.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
The same way you can declare additional validation and metadata in endpoint function parameters with `Query`, `Path` and `Body`, you can declare validation and metadata inside of Pydantic models using `Schema`.
|
||||
The same way you can declare additional validation and metadata in path operation function parameters with `Query`, `Path` and `Body`, you can declare validation and metadata inside of Pydantic models using `Schema`.
|
||||
|
||||
## Import Schema
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ You can then use `Schema` with model attributes:
|
|||
`Body` is also a subclass of `Schema` directly. And there are others you will see later that are subclasses of `Body`.
|
||||
|
||||
!!! tip
|
||||
Notice how each model's attribute with a type, default value and `Schema` has the same structure as an endpoint's function's parameter, with `Schema` instead of `Path`, `Query` and `Body`.
|
||||
Notice how each model's attribute with a type, default value and `Schema` has the same structure as a path operation function's parameter, with `Schema` instead of `Path`, `Query` and `Body`.
|
||||
|
||||
## Schema extras
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ For example, this model above declares a JSON "`object`" (or Python `dict`) like
|
|||
|
||||
## Declare it as a parameter
|
||||
|
||||
To add it to your endpoint, declare it the same way you declared path and query parameters:
|
||||
To add it to your path operation, declare it the same way you declared path and query parameters:
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!./tutorial/src/body/tutorial001.py!}
|
||||
|
|
@ -69,7 +69,7 @@ The JSON Schemas of your models will be part of your OpenAPI generated schema, a
|
|||
|
||||
<img src="/img/tutorial/body/image01.png">
|
||||
|
||||
And will be also used in the API docs inside each endpoint that needs them:
|
||||
And will be also used in the API docs inside each path operation that needs them:
|
||||
|
||||
<img src="/img/tutorial/body/image02.png">
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,11 @@ It will show a JSON starting with something like:
|
|||
|
||||
`FastAPI` is a Python class that provides all the functionality for your API.
|
||||
|
||||
!!! note "Technical Details"
|
||||
`FastAPI` is a class that inherits directly from `Starlette`.
|
||||
|
||||
You can use all the Starlette functionality with `FastAPI` too.
|
||||
|
||||
### Step 2: create a `FastAPI` "instance"
|
||||
|
||||
```Python hl_lines="3"
|
||||
|
|
@ -102,7 +107,7 @@ It will show a JSON starting with something like:
|
|||
|
||||
Here the `app` variable will be an "instance" of the class `FastAPI`.
|
||||
|
||||
This will be the main point of interaction to create all your API endpoints.
|
||||
This will be the main point of interaction to create all your API.
|
||||
|
||||
This `app` is the same one referred by `uvicorn` in thet command:
|
||||
|
||||
|
|
@ -122,28 +127,98 @@ And put it in a file `main.py`, then you would call `uvicorn` like:
|
|||
uvicorn main:my_awesome_api --debug
|
||||
```
|
||||
|
||||
### Step 3: create an endpoint
|
||||
### Step 3: create a path operation
|
||||
|
||||
#### Path
|
||||
|
||||
"Path" here refers to the last part of the URL starting from the first `/`.
|
||||
|
||||
So, in a URL like:
|
||||
|
||||
```
|
||||
https://example.com/items/foo
|
||||
```
|
||||
|
||||
...the path would be:
|
||||
|
||||
```
|
||||
/items/foo
|
||||
```
|
||||
|
||||
!!! info
|
||||
A "path" is also commonly called an "endpoint" or a "route".
|
||||
|
||||
Building an API, the "path" is the main way to separate "concerns" and functionalities.
|
||||
|
||||
#### Operation
|
||||
|
||||
"Operation" here refers to one of the HTTP "methods".
|
||||
|
||||
One of:
|
||||
|
||||
* `POST`
|
||||
* `GET`
|
||||
* `PUT`
|
||||
* `DELETE`
|
||||
|
||||
...and the more exotic ones:
|
||||
|
||||
* `OPTIONS`
|
||||
* `HEAD`
|
||||
* `PATCH`
|
||||
* `TRACE`
|
||||
|
||||
In the HTTP protocol, you can communicate to each path using one (or more) of these "methods".
|
||||
|
||||
---
|
||||
|
||||
When building APIs, you normally use these specific HTTP methods to perform a specific operation.
|
||||
|
||||
Normally you use:
|
||||
|
||||
* `POST`: to create data.
|
||||
* `GET`: to read data.
|
||||
* `PUT`: to update data.
|
||||
* `DELETE`: to delete data.
|
||||
|
||||
So, in OpenAPI, each of the HTTP methods is called an "operation".
|
||||
|
||||
We are going to call them "operations" too.
|
||||
|
||||
#### Define a path operation function
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!tutorial/src/first-steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
The `@app.get("/")` tells **FastAPI** that the function right below is an endpoint and that it should go to the path route `/`.
|
||||
The `@app.get("/")` tells **FastAPI** that the function right below is in charge of handling requests that go to:
|
||||
|
||||
You can also use other HTTP methods:
|
||||
* the path `/`
|
||||
* using a <abbr title="an HTTP GET method"><code>get</code> operation</abbr>
|
||||
|
||||
You can also use the other operations:
|
||||
|
||||
* `@app.post()`
|
||||
* `@app.put()`
|
||||
* `@app.delete()`
|
||||
|
||||
And more exotic ones:
|
||||
And the more exotic ones:
|
||||
|
||||
* `@app.options()`
|
||||
* `@app.head()`
|
||||
* `@app.patch()`
|
||||
* `@app.trace()`
|
||||
|
||||
### Step 4: define the endpoint function
|
||||
!!! tip
|
||||
You are free to use each operation (HTTP method) as you wish.
|
||||
|
||||
**FastAPI** doesn't enforce any specific meaning.
|
||||
|
||||
The information here is presented as a guideline, not a requirement.
|
||||
|
||||
For example, when using GraphQL you normally perform all the operations using only `post`.
|
||||
|
||||
### Step 4: define the path operation function
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!tutorial/src/first-steps/tutorial001.py!}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ And then, we can pass more parameters to `Query`. In this case, the `max_length`
|
|||
q: str = Query(None, max_length=50)
|
||||
```
|
||||
|
||||
This will validate the data, show a clear error when the data is not valid, and document the parameter in the OpenAPI schema endpoint.
|
||||
This will validate the data, show a clear error when the data is not valid, and document the parameter in the OpenAPI schema path operation.
|
||||
|
||||
|
||||
## Add more validations
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ The way HTML forms (`<form></form>`) sends the data to the server normally uses
|
|||
|
||||
|
||||
!!! warning
|
||||
You can declare multiple `File` and `Form` parameters in an endpoint, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `multipart/form-data` instead of `application/json`.
|
||||
You can declare multiple `File` and `Form` parameters in a path operation, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `multipart/form-data` instead of `application/json`.
|
||||
|
||||
This is not a limitation of **FastAPI**, it's part of the HTTP protocol.
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Create file and form parameters the same way you would for `Body` or `Query`:
|
|||
The files and form fields will be uploaded as form data and you will receive the files and form fields.
|
||||
|
||||
!!! warning
|
||||
You can declare multiple `File` and `Form` parameters in an endpoint, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `multipart/form-data` instead of `application/json`.
|
||||
You can declare multiple `File` and `Form` parameters in a path operation, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `multipart/form-data` instead of `application/json`.
|
||||
|
||||
This is not a limitation of **FastAPI**, it's part of the HTTP protocol.
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ The way HTML forms (`<form></form>`) sends the data to the server normally uses
|
|||
|
||||
|
||||
!!! warning
|
||||
You can declare multiple `Form` parameters in an endpoint, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `application/x-www-form-urlencoded` instead of `application/json`.
|
||||
You can declare multiple `Form` parameters in a path operation, but you can't also declare `Body` fields that you expect to receive as JSON, as the request will have the body encoded using `application/x-www-form-urlencoded` instead of `application/json`.
|
||||
|
||||
This is not a limitation of **FastAPI**, it's part of the HTTP protocol.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
You can declare the model used for the response with the parameter `response_model` in any of the endpoint creation methods:
|
||||
You can declare the model used for the response with the parameter `response_model` in any of the path operations:
|
||||
|
||||
* `@app.get()`
|
||||
* `@app.post()`
|
||||
|
|
@ -11,13 +11,13 @@ You can declare the model used for the response with the parameter `response_mod
|
|||
```
|
||||
|
||||
!!! note
|
||||
Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc), not of your endpoint function like all the parameters and body.
|
||||
Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your path operation function, like all the parameters and body.
|
||||
|
||||
It receives a standard Pydantic model and will:
|
||||
|
||||
* Convert the output data to the type declarations of the model
|
||||
* Validate the data
|
||||
* Add a JSON Schema for the response, in the OpenAPI endpoint
|
||||
* Add a JSON Schema for the response, in the OpenAPI path operation
|
||||
* Will be used by the automatic documentation systems
|
||||
|
||||
But most importantly:
|
||||
|
|
@ -42,7 +42,7 @@ Now, whenever a browser is creating a user with a password, the API will return
|
|||
|
||||
In this case, it might not be a problem, becase the user himself is sending the password.
|
||||
|
||||
But if we use sthe same model for another endpoint, we could be sending the passwords of our users to every client.
|
||||
But if we use sthe same model for another path operation, we could be sending the passwords of our users to every client.
|
||||
|
||||
!!! danger
|
||||
Never send the plain password of a user in a response.
|
||||
|
|
@ -55,7 +55,7 @@ We can instead create an input model with the plaintext password and an output m
|
|||
{!./tutorial/src/response-model/tutorial003.py!}
|
||||
```
|
||||
|
||||
Here, even though our endpoint function is returning the same input user that contains the password:
|
||||
Here, even though our path operation function is returning the same input user that contains the password:
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!./tutorial/src/response-model/tutorial003.py!}
|
||||
|
|
@ -81,4 +81,4 @@ And both models will be used for the interactive API documentation:
|
|||
|
||||
## Recap
|
||||
|
||||
Use the endpoint decorator's parameter `response_model` to define response models and especially to ensure private data is filtered out.
|
||||
Use the path operation decorator's parameter `response_model` to define response models and especially to ensure private data is filtered out.
|
||||
|
|
|
|||
Loading…
Reference in New Issue