**Documentation**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com)
+**Source**: [https://github.com/tiangolo/fastapi](https://github.com/tiangolo/fastapi)
+
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+.
uvicorn main:app --debug
```
-**Note**: the command `uvicorn main:app` refers to:
+!!! 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.
+ * `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
* 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:
+* Serialization of input data: conversion of data coming from the network to Python data and types. Reading from:
* JSON.
* Forms.
* Files.
* Query parameters.
* Cookies.
* Headers.
-* Serialization of output data: from Python to network (as JSON):
+* Serialization 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.

-For a more complete example including more features, [see the tutorial](tutorial).
+For a more complete example including more features, [see the tutorial]().
**Spoiler alert**: the tutorial, although very short, includes:
Used by Pydantic:
-* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON parsing.
+* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
* <a href="http://docs.python-requests.org" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
-* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form parsing, with `request.form()`.
+* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for `SchemaGenerator` support.
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
--- /dev/null
+The simplest FastAPI file could look like this:
+
+```Python
+{!tutorial/src/first-steps/tutorial001.py!}
+```
+
+Copy that to a file `main.py`.
+
+Run the live server:
+
+```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.
+
+You will see an output like:
+
+```hl_lines="4"
+INFO: Started reloader process [17961]
+INFO: Started server process [17962]
+INFO: Waiting for application startup.
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+That last line shows the URL where your app is being served, in your local machine.
+
+### Check it
+
+Open your browser at <a href="http://127.0.0.1:8000" target="_blank">http://127.0.0.1:8000</a>.
+
+You will see the JSON response as:
+
+```JSON
+{"hello": "world"}
+```
+
+### Interactive API docs
+
+Now go to <a href="http://127.0.0.1:8000/docs" target="_blank">http://127.0.0.1:8000/docs</a>.
+
+You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" target="_blank">Swagger UI</a>):
+
+
+
+
+### Alternative API docs
+
+And now, go to <a href="http://127.0.0.1:8000/redoc" target="_blank">http://127.0.0.1:8000/redoc</a>.
+
+You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" target="_blank">ReDoc</a>):
+
+
+
+## Recap, step by step
+
+### Step 1: import `FastAPI`
+
+```Python hl_lines="1"
+{!tutorial/src/first-steps/tutorial001.py!}
+```
+
+`FastAPI` is a Python class that provides all the functionality for your API.
+
+### Step 2: create a `FastAPI` "instance"
+
+```Python hl_lines="3"
+{!tutorial/src/first-steps/tutorial001.py!}
+```
+
+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 `app` is the same one referred by `uvicorn` in thet command:
+
+```bash
+uvicorn main:app --debug
+```
+
+If you create your app like:
+
+```Python hl_lines="3"
+{!tutorial/src/first-steps/tutorial002.py!}
+```
+
+And put it in a file `main.py`, then you would call `uvicorn` like:
+
+```bash
+uvicorn main:my_awesome_api --debug
+```
+
+### Step 3: create an endpoint
+
+```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 `/`.
+
+### Step 4: define the endpoint function
+
+```Python hl_lines="7"
+{!tutorial/src/first-steps/tutorial001.py!}
+```
+
+This is a Python function.
+
+It will be called by FastAPI whenever it receives a request to the URL "`/`".
+
+In this case, it is an `async` function.
+
+---
+
+You could also define it as a normal function instead of `async def`:
+
+```Python hl_lines="7"
+{!tutorial/src/first-steps/tutorial003.py!}
+```
+
+To know the difference, read the section about [Concurrency and `async` / `await`](/async/).
+
+### Step 5: return the content
+
+```Python hl_lines="8"
+{!tutorial/src/first-steps/tutorial001.py!}
+```
+
+You can return a `dict`, `list`, singular values as `str`, `int`, etc.
+
+You can also return Pydantic models (you'll see more about that later).
+
+There are many other objects and models that will be automatically converted to JSON.
+++ /dev/null
-Sorry! Coming soon... come back in a couple days.
\ No newline at end of file
--- /dev/null
+This tutorial shows you how to use **FastAPI** with all its features, step by step.
+
+Eeach section gradually builds on the previous ones, but it's structured to separate topics, so that you can go directly to any specific one to solve your specific API needs.
+
+It is also built to work as a future reference. So you can come back and see exactly what you need.
+
+And each section is very short, so you can go directly to what you need and get the information fast.
+
+## Run the code
+
+All the code blocks can be copied and used directly (they are actually tested Python files).
+
+To run any of the examples, copy the code to a file `main.py`, and start `uvicorn` with:
+
+```bash
+uvicorn main:app --debug
+```
+
+It is **HIGHLY encouraged** that you write or copy the code, edit it and run it locally.
+
+Using it in your editor is what really shows you the benefits of FastAPI, seeing how little code you have to write, all the type checks, autocompletion, etc.
+
+---
+
+## Install FastAPI
+
+The first step is to install FastAPI.
+
+For the tutorial, you might want to install it with all the optional dependencies and features:
+
+```bash
+pip install fastapi[all]
+```
+
+...that also includes `uvicorn`, that you can use as the server that runs your code.
+
+!!! note
+ You can also install it part by part.
+
+ This is what you would probably do once you want to deploy your application to production:
+
+ ```bash
+ pip install fastapi
+ ```
+
+ Also install `uvicorn` to work as the server:
+
+ ```bash
+ pip install uvicorn
+ ```
+
+ And the same for each of the optional dependencies that you want to use.
--- /dev/null
+You can declare path "parameters" or "variables" with the same syntax used by Python format strings:
+
+```Python hl_lines="6 7"
+{!./tutorial/src/path-params/tutorial001.py!}
+```
+
+The value of the path parameter `item_id` will be passed to your function as the argument `item_id`.
+
+So, if you run this example and go to <a href="http://127.0.0.1:8000/items/foo" target="_blank">http://127.0.0.1:8000/items/foo</a>, you will see a response of:
+
+```JSON
+{"item_id":"foo"}
+```
+
+## Path parameters with types
+
+You can declare the type of a path parameter in the function, using standard Python type annotations:
+
+```Python hl_lines="7"
+{!./tutorial/src/path-params/tutorial002.py!}
+```
+
+In this case, `item_id` is declared to be an `int`.
+
+!!! check
+ This will give you editor support inside of your function, with error checks, completion, etc.
+
+## Data "parsing"
+
+If you run this example and open your browser at <a href="http://127.0.0.1:8000/items/3" target="_blank">http://127.0.0.1:8000/items/3</a>, you will see a response of:
+
+```JSON
+{"item_id":3}
+```
+
+!!! check
+ Notice that the value your function received (and returned) is `3`, as a Python `int`, not a string `"3"`.
+
+ So, with that type declaration, **FastAPI** gives you automatic request <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
+
+## Data validation
+
+But if you go to the browser at <a href="http://127.0.0.1:8000/items/foo" target="_blank">http://127.0.0.1:8000/items/foo</a>, you will see a nice HTTP error of:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+because the path parameter `item_id` had a value of `"foo"`, which is not an `int`.
+
+The same error would appear if you provided a `foat` instead of an int, as in: <a href="http://127.0.0.1:8000/items/4.2" target="_blank">http://127.0.0.1:8000/items/4.2</a>
+
+
+!!! check
+ So, with the same Python type declaration, **FastAPI** gives you data validation.
+
+ Notice that the error also clearly states exactly the point where the validaton didn't pass.
+
+ This is incredibly helpful while developing and debugging code that interacts with your API.
+
+## Documentation
+
+And when you open your browser at <a href="http://127.0.0.1:8000/docs" target="_blank">http://127.0.0.1:8000/docs</a>, you will see an automatic, interactive, API documentation like:
+
+<img src="/img/tutorial/path-params/image01.png">
+
+!!! check
+ Again, just with that same Python type declaration, **FastAPI** gives you automatic, interactive documentation (integrating Swagger UI).
+
+ Notice that the path parameter is declared to be an integer.
+
+## Standards-based benefits, alternative documentation
+
+And because the generated schema is from the <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" target="_blank">OpenAPI</a> standard, there are many compatible tools.
+
+Because of this, **FastAPI** itself provides an alternative API documentation (using ReDoc):
+
+<img src="/img/tutorial/path-params/image02.png">
+
+The same way, there are many compatible tools. Including code generation tools for many languages.
+
+## Pydantic
+
+All the data validation is performed under the hood by <a href="https://pydantic-docs.helpmanual.io/" target="_blank">Pydantic</a>, so you get all the benefits from it. And you know you are in good hands.
+
+You can use the same type declarations with `str`, `float`, `bool` and many other complex data types.
+
+These are explored in the next sections of the tutorial.
+
+## Recap
+
+With **FastAPI**, by using short, intuitive and standard Python type declarations, you get:
+
+* Editor support: error checks, autocompletion, etc.
+* Data "<abbr title="converting the string that comes from an HTTP request into Python data">parsing</abbr>"
+* Data validation
+* API annotation and automatic documentation
+
+And you only have to declare them once.
+
+That's probably the main visible advantage of **FastAPI** compared to alternative frameworks (appart from the raw performance).
\ No newline at end of file
--- /dev/null
+When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.
+
+```Python hl_lines="9"
+{!./tutorial/src/query-params/tutorial001.py!}
+```
+
+The query is the set of key-value pairs that go after the `?` in a URL, separated by `&` characters.
+
+For example, in the url:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+...the query parameters are:
+
+* `skip`: with a value of `0`
+* `limit`: with a value of `10`
+
+As they are part of the URL, they are "naturally" strings.
+
+But when you declare them with Python types (in the example above, as `int`), they are converted to that type and validated against it.
+
+All the same process that applied for path parameters also applies for query parameters:
+
+* Editor support (obviously)
+* Data <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>
+* Data validation
+* Automatic documentation
+
+## Defaults
+
+As query parameters are not a fixed part of a path, they can be optional and can have default values.
+
+In the example above they have default values of `skip=0` and `limit=10`.
+
+So, going to the URL:
+
+```
+http://127.0.0.1:8000/items/
+```
+
+would be the same as going to:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+But if you go to, for example:
+
+```
+http://127.0.0.1:8000/items/?skip=20
+```
+
+The parameter values in your function will be:
+
+* `skip=20`: because you set it in the URL
+* `limit=10`: because that was the default value
+
+## Optional parameters
+
+The same way, you can declare optional query parameters, by setting their default to `None`:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params/tutorial002.py!}
+```
+
+In this case, the function parameter `q` will be optional, and will be `None` by default.
+
+!!! check
+ Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.
+
+## Query parameter type conversion
+
+You can also declare `bool` types, and they will be converted:
+
+```Python hl_lines="7"
+{!./tutorial/src/query-params/tutorial003.py!}
+```
+
+In this case, if you go to:
+
+```
+http://127.0.0.1:8000/items/?short=1
+```
+
+or
+
+```
+http://127.0.0.1:8000/items/?short=True
+```
+
+or
+
+```
+http://127.0.0.1:8000/items/?short=true
+```
+
+or
+
+```
+http://127.0.0.1:8000/items/?short=on
+```
+
+or
+
+```
+http://127.0.0.1:8000/items/?short=yes
+```
+
+or any other case variation (uppercase, first letter in uppercase, etc), your function will see the parameter `short` with a `bool` value of `True`. Otherwise as `False`.
+
+
+## Multiple path and query parameters
+
+You can declare multiple path parameters and query parameters at the same time, **FastAPI** knows which is which.
+
+And you don't have to declare them in any specific order.
+
+They will be detected by name:
+
+```Python hl_lines="6 8"
+{!./tutorial/src/query-params/tutorial004.py!}
+```
+
+## Required query parameters
+
+When you declare a default value for non-path parameters (for now, we have only seen query parameters), then it is not required.
+
+If you don't want to add a specific value but just make it optional, set the default as `None`.
+
+But when you want to make a query parameter required, you can just do not declare any default value:
+
+```Python hl_lines="6 8"
+{!./tutorial/src/query-params/tutorial005.py!}
+```
+
+Here the query parameter `needy` is a required query parameter of type `str`.
+
+If you open in your browser a URL like:
+
+```
+http://127.0.0.1:8000/users/2/items/foo-item
+```
+
+...without adding the required parameter `needy`, you will see an error like:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "query",
+ "needy"
+ ],
+ "msg": "field required",
+ "type": "value_error.missing"
+ }
+ ]
+}
+```
+
+As `needy` is a required parameter, you would need to set it in the URL:
+
+```
+http://127.0.0.1:8000/users/2/items/foo-item?needy=sooooneedy
+```
+
+...this would work:
+
+```JSON
+{
+ "item_id": "foo-item",
+ "owner_id": 2,
+ "needy": "sooooneedy"
+}
+```
\ No newline at end of file
--- /dev/null
+from fastapi import FastAPI
+
+my_awesome_api = FastAPI()
+
+
+@my_awesome_api.get("/")
+async def root():
+ return {"message": "Hello World"}
--- /dev/null
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def root():
+ return {"message": "Hello World"}
--- /dev/null
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/users/{user_id}/items/{item_id}")
+async def read_user_item(
+ user_id: int, item_id: str, needy: str
+):
+ item = {"item_id": item_id, "owner_id": user_id, "needy": needy}
+ return item
+++ /dev/null
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/users/{user_id}/items/{item_id}")
-async def read_user_item(
- user_id: int, item_id: str, needy: str, q: str = None, short: bool = False
-):
- item = {"item_id": item_id, "owner_id": user_id, "needy": needy}
- if q:
- item.update({"q": q})
- if not short:
- item.update(
- {"description": "This is an amazing item that has a long description"}
- )
- return item