Browse Source

Add support for docs translations (#1168)

* 🌐 Refactor file structure to support internationalization

*  Update tests changed after i18n

* 🔀 Merge Typer style from master

* 🔧 Update MkConfig with Typer-styles

* 🎨 Format mkdocs.yml with cannonical form

* 🎨 Format mkdocs.yml

* 🔧 Update MkDocs config

*  Add docs translation scripts dependencies

*  Add Typer scripts to handle translations

*  Add missing translation snippet to include

*  Update contributing docs, add docs for translations

* 🙈 Add docs_build to gitignore

* 🔧 Update scripts with new locations and docs scripts

* 👷 Update docs deploy action with translations

* 📝 Add note about languages not supported in the theme

*  Add first translation, for Spanish
pull/1169/head
Sebastián Ramírez 5 years ago
committed by GitHub
parent
commit
6205935323
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .github/workflows/deploy-docs.yml
  2. 1
      .gitignore
  3. 176
      docs/contributing.md
  4. 10
      docs/en/docs/advanced/additional-responses.md
  5. 4
      docs/en/docs/advanced/additional-status-codes.md
  6. 10
      docs/en/docs/advanced/advanced-dependencies.md
  7. 16
      docs/en/docs/advanced/async-sql-databases.md
  8. 14
      docs/en/docs/advanced/custom-request-and-route.md
  9. 24
      docs/en/docs/advanced/custom-response.md
  10. 5
      docs/en/docs/advanced/events.md
  11. 20
      docs/en/docs/advanced/extending-openapi.md
  12. 5
      docs/en/docs/advanced/graphql.md
  13. 2
      docs/en/docs/advanced/index.md
  14. 8
      docs/en/docs/advanced/middleware.md
  15. 18
      docs/en/docs/advanced/nosql-databases.md
  16. 10
      docs/en/docs/advanced/openapi-callbacks.md
  17. 10
      docs/en/docs/advanced/path-operation-advanced-configuration.md
  18. 4
      docs/en/docs/advanced/response-change-status-code.md
  19. 6
      docs/en/docs/advanced/response-cookies.md
  20. 6
      docs/en/docs/advanced/response-directly.md
  21. 6
      docs/en/docs/advanced/response-headers.md
  22. 8
      docs/en/docs/advanced/security/http-basic-auth.md
  23. 2
      docs/en/docs/advanced/security/index.md
  24. 18
      docs/en/docs/advanced/security/oauth2-scopes.md
  25. 36
      docs/en/docs/advanced/sql-databases-peewee.md
  26. 8
      docs/en/docs/advanced/sub-applications-proxy.md
  27. 10
      docs/en/docs/advanced/templates.md
  28. 4
      docs/en/docs/advanced/testing-dependencies.md
  29. 6
      docs/en/docs/advanced/testing-events.md
  30. 4
      docs/en/docs/advanced/testing-websockets.md
  31. 4
      docs/en/docs/advanced/using-request-directly.md
  32. 9
      docs/en/docs/advanced/websockets.md
  33. 4
      docs/en/docs/advanced/wsgi.md
  34. 2
      docs/en/docs/alternatives.md
  35. 2
      docs/en/docs/async.md
  36. 2
      docs/en/docs/benchmarks.md
  37. 441
      docs/en/docs/contributing.md
  38. 0
      docs/en/docs/css/custom.css
  39. 0
      docs/en/docs/css/termynal.css
  40. 2
      docs/en/docs/deployment.md
  41. 2
      docs/en/docs/external-links.md
  42. 9
      docs/en/docs/features.md
  43. 2
      docs/en/docs/help-fastapi.md
  44. 2
      docs/en/docs/history-design-future.md
  45. 0
      docs/en/docs/img/favicon.png
  46. 0
      docs/en/docs/img/github-social-preview.png
  47. 0
      docs/en/docs/img/github-social-preview.svg
  48. 0
      docs/en/docs/img/icon-transparent-bg.png
  49. 0
      docs/en/docs/img/icon-white-bg.png
  50. 0
      docs/en/docs/img/icon-white.svg
  51. 0
      docs/en/docs/img/index/index-01-swagger-ui-simple.png
  52. 0
      docs/en/docs/img/index/index-02-redoc-simple.png
  53. 0
      docs/en/docs/img/index/index-03-swagger-02.png
  54. 0
      docs/en/docs/img/index/index-04-swagger-03.png
  55. 0
      docs/en/docs/img/index/index-05-swagger-04.png
  56. 0
      docs/en/docs/img/index/index-06-redoc-02.png
  57. 0
      docs/en/docs/img/logo-margin/logo-teal-vector.svg
  58. 0
      docs/en/docs/img/logo-margin/logo-teal.png
  59. 0
      docs/en/docs/img/logo-margin/logo-teal.svg
  60. 0
      docs/en/docs/img/logo-margin/logo-white-bg.png
  61. 0
      docs/en/docs/img/logo-teal-vector.svg
  62. 0
      docs/en/docs/img/logo-teal.svg
  63. 0
      docs/en/docs/img/pycharm-completion.png
  64. 0
      docs/en/docs/img/python-types/image01.png
  65. 0
      docs/en/docs/img/python-types/image02.png
  66. 0
      docs/en/docs/img/python-types/image03.png
  67. 0
      docs/en/docs/img/python-types/image04.png
  68. 0
      docs/en/docs/img/python-types/image05.png
  69. 0
      docs/en/docs/img/python-types/image06.png
  70. 0
      docs/en/docs/img/tutorial/additional-responses/image01.png
  71. 0
      docs/en/docs/img/tutorial/application-configuration/image01.png
  72. 0
      docs/en/docs/img/tutorial/async-sql-databases/image01.png
  73. 0
      docs/en/docs/img/tutorial/bigger-applications/image01.png
  74. 0
      docs/en/docs/img/tutorial/body-fields/image01.png
  75. 0
      docs/en/docs/img/tutorial/body-nested-models/image01.png
  76. 0
      docs/en/docs/img/tutorial/body/image01.png
  77. 0
      docs/en/docs/img/tutorial/body/image02.png
  78. 0
      docs/en/docs/img/tutorial/body/image03.png
  79. 0
      docs/en/docs/img/tutorial/body/image04.png
  80. 0
      docs/en/docs/img/tutorial/body/image05.png
  81. 0
      docs/en/docs/img/tutorial/custom-response/image01.png
  82. 0
      docs/en/docs/img/tutorial/debugging/image01.png
  83. 0
      docs/en/docs/img/tutorial/dependencies/image01.png
  84. 0
      docs/en/docs/img/tutorial/dependencies/image02.png
  85. 0
      docs/en/docs/img/tutorial/extending-openapi/image01.png
  86. 0
      docs/en/docs/img/tutorial/graphql/image01.png
  87. 0
      docs/en/docs/img/tutorial/openapi-callbacks/image01.png
  88. 0
      docs/en/docs/img/tutorial/path-operation-configuration/image01.png
  89. 0
      docs/en/docs/img/tutorial/path-operation-configuration/image02.png
  90. 0
      docs/en/docs/img/tutorial/path-operation-configuration/image03.png
  91. 0
      docs/en/docs/img/tutorial/path-operation-configuration/image04.png
  92. 0
      docs/en/docs/img/tutorial/path-operation-configuration/image05.png
  93. 0
      docs/en/docs/img/tutorial/path-params/image01.png
  94. 0
      docs/en/docs/img/tutorial/path-params/image02.png
  95. 0
      docs/en/docs/img/tutorial/path-params/image03.png
  96. 0
      docs/en/docs/img/tutorial/query-params-str-validations/image01.png
  97. 0
      docs/en/docs/img/tutorial/query-params-str-validations/image02.png
  98. 0
      docs/en/docs/img/tutorial/response-model/image01.png
  99. 0
      docs/en/docs/img/tutorial/response-model/image02.png
  100. 0
      docs/en/docs/img/tutorial/response-status-code/image01.png

4
.github/workflows/deploy-docs.yml

@ -16,8 +16,8 @@ jobs:
run: python3.7 -m pip install flit
- name: Install docs extras
run: python3.7 -m flit install --extras doc
- name: Build MkDocs
run: python3.7 -m mkdocs build
- name: Build Docs
run: python3.7 ./scripts/docs.py build-all
- name: Deploy to Netlify
uses: nwtgck/[email protected]
with:

1
.gitignore

@ -14,3 +14,4 @@ test.db
log.txt
Pipfile.lock
env3.*
docs_build

176
docs/contributing.md

@ -1,176 +0,0 @@
First, you might want to see the basic ways to [help FastAPI and get help](help-fastapi.md){.internal-link target=_blank}.
## Developing
If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.
### Virtual environment with `venv`
You can create a virtual environment in a directory using Python's `venv` module:
```console
$ python -m venv env
```
That will create a directory `./env/` with the Python binaries and then you will be able to install packages for that isolated environment.
### Activate the environment
Activate the new environment with:
```console
$ source ./env/bin/activate
```
Or in Windows' PowerShell:
```console
$ .\env\Scripts\Activate.ps1
```
Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
```console
$ source ./env/Scripts/activate
```
To check it worked, use:
```console
$ which pip
some/directory/fastapi/env/bin/pip
```
If it shows the `pip` binary at `env/bin/pip` then it worked. 🎉
Or in Windows PowerShell:
```console
$ Get-Command pip
some/directory/fastapi/env/bin/pip
```
!!! tip
Every time you install a new package with `pip` under that environment, activate the environment again.
This makes sure that if you use a terminal program installed by that package (like `flit`), you use the one from your local environment and not any other that could be installed globally.
### Flit
**FastAPI** uses <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> to build, package and publish the project.
After activating the environment as described above, install `flit`:
```console
$ pip install flit
```
Now re-activate the environment to make sure you are using the `flit` you just installed (and not a global one).
And now use `flit` to install the development dependencies:
```console
$ flit install --deps develop --symlink
```
It will install all the dependencies and your local FastAPI in your local environment.
#### Using your local FastAPI
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
And if you update that local FastAPI source code, as it is installed with `--symlink`, when you run that Python file again, it will use the fresh version of FastAPI you just edited.
That way, you don't have to "install" your local version to be able to test every change.
### Format
There is a script that you can run that will format and clean all your code:
```console
$ bash scripts/format.sh
```
It will also auto-sort all your imports.
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above:
```console
$ flit install --symlink
```
### Format imports
There is another script that formats all the imports and makes sure you don't have unused imports:
```console
$ bash scripts/format-imports.sh
```
As it runs one command after the other and modifies and reverts many files, it takes a bit longer to run, so it might be easier to use `scripts/format.sh` frequently and `scripts/format-imports.sh` only before committing.
## Docs
The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
All the documentation is in Markdown format in the directory `./docs`.
Many of the tutorials have blocks of code.
In most of the cases, these blocks of code are actual complete applications that can be run as is.
In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs/src/` directory.
And those Python files are included/injected in the documentation when generating the site.
### Docs for tests
Most of the tests actually run against the example source files in the documentation.
This helps making sure that:
* The documentation is up to date.
* The documentation examples can be run as is.
* Most of the features are covered by the documentation, ensured by test coverage.
During local development, there is a script that builds the site and checks for any changes, live-reloading:
```console
$ bash scripts/docs-live.sh
```
It will serve the documentation on `http://0.0.0.0:8008`.
That way, you can edit the documentation/source files and see the changes live.
### Apps and docs at the same time
If you run the examples with, e.g.:
```console
$ uvicorn tutorial001:app --reload
```
as Uvicorn by default will use the port `8000`, the documentation on port `8008` won't clash.
## Tests
There is a script that you can run locally to test all the code and generate coverage reports in HTML:
```console
$ bash scripts/test-cov-html.sh
```
This command generates a directory `./htmlcov/`, if you open the file `./htmlcov/index.html` in your browser, you can explore interactively the regions of code that are covered by the tests, and notice if there is any region missing.
### Tests in your editor
If you want to use the integrated tests in your editor add `./docs/src` to your `PYTHONPATH` variable.
For example, in VS Code you can create a file `.env` with:
```env
PYTHONPATH=./docs/src
```

10
docs/advanced/additional-responses.md → docs/en/docs/advanced/additional-responses.md

@ -1,3 +1,5 @@
# Additional Responses in OpenAPI
!!! warning
This is a rather advanced topic.
@ -22,7 +24,7 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod
For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:
```Python hl_lines="18 23"
{!./src/additional_responses/tutorial001.py!}
{!../../../docs_src/additional_responses/tutorial001.py!}
```
!!! note
@ -167,7 +169,7 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
```Python hl_lines="17 18 19 20 21 22 23 24 28"
{!./src/additional_responses/tutorial002.py!}
{!../../../docs_src/additional_responses/tutorial002.py!}
```
!!! note
@ -191,7 +193,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd
And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:
```Python hl_lines="20 21 22 23 24 25 26 27 28 29 30 31"
{!./src/additional_responses/tutorial003.py!}
{!../../../docs_src/additional_responses/tutorial003.py!}
```
It will all be combined and included in your OpenAPI, and shown in the API docs:
@ -227,7 +229,7 @@ You can use that technique to re-use some predefined responses in your *path ope
For example:
```Python hl_lines="11 12 13 14 15 24"
{!./src/additional_responses/tutorial004.py!}
{!../../../docs_src/additional_responses/tutorial004.py!}
```
## More information about OpenAPI responses

4
docs/advanced/additional-status-codes.md → docs/en/docs/advanced/additional-status-codes.md

@ -1,3 +1,5 @@
# Additional Status Codes
By default, **FastAPI** will return the responses using a `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`.
It will use the default status code or the one you set in your *path operation*.
@ -13,7 +15,7 @@ But you also want it to accept new items. And when the items didn't exist before
To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want:
```Python hl_lines="2 19"
{!./src/additional_status_codes/tutorial001.py!}
{!../../../docs_src/additional_status_codes/tutorial001.py!}
```
!!! warning

10
docs/advanced/advanced-dependencies.md → docs/en/docs/advanced/advanced-dependencies.md

@ -1,3 +1,5 @@
# Advanced Dependencies
## Parameterized dependencies
All the dependencies we have seen are a fixed function or class.
@ -17,7 +19,7 @@ Not the class itself (which is already a callable), but an instance of that clas
To do that, we declare a method `__call__`:
```Python hl_lines="10"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later.
@ -27,7 +29,7 @@ In this case, this `__call__` is what **FastAPI** will use to check for addition
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
```Python hl_lines="7"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.
@ -37,7 +39,7 @@ In this case, **FastAPI** won't ever touch or care about `__init__`, we will use
We could create an instance of this class with:
```Python hl_lines="16"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.
@ -55,7 +57,7 @@ checker(q="somequery")
...and pass whatever that returns as the value of the dependency in our *path operation function* as the parameter `fixed_content_included`:
```Python hl_lines="20"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
!!! tip

16
docs/advanced/async-sql-databases.md → docs/en/docs/advanced/async-sql-databases.md

@ -1,3 +1,5 @@
# Async SQL (Relational) Databases
You can also use <a href="https://github.com/encode/databases" class="external-link" target="_blank">`encode/databases`</a> with **FastAPI** to connect to databases using `async` and `await`.
It is compatible with:
@ -22,7 +24,7 @@ Later, for your production application, you might want to use a database server
* Create a table `notes` using the `metadata` object.
```Python hl_lines="4 14 16 17 18 19 20 21 22"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! tip
@ -37,7 +39,7 @@ Later, for your production application, you might want to use a database server
* Create a `database` object.
```Python hl_lines="3 9 12"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! tip
@ -53,7 +55,7 @@ Here, this section would run directly, right before starting your **FastAPI** ap
* Create all the tables from the `metadata` object.
```Python hl_lines="25 26 27 28"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
## Create models
@ -64,7 +66,7 @@ Create Pydantic models for:
* Notes to be returned (`Note`).
```Python hl_lines="31 32 33 36 37 38 39"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
By creating these Pydantic models, the input data will be validated, serialized (converted), and annotated (documented).
@ -77,7 +79,7 @@ So, you will be able to see it all in the interactive API docs.
* Create event handlers to connect and disconnect from the database.
```Python hl_lines="42 45 46 47 50 51 52"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
## Read notes
@ -85,7 +87,7 @@ So, you will be able to see it all in the interactive API docs.
Create the *path operation function* to read notes:
```Python hl_lines="55 56 57 58"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! Note
@ -102,7 +104,7 @@ That documents (and validates, serializes, filters) the output data, as a `list`
Create the *path operation function* to create notes:
```Python hl_lines="61 62 63 64 65"
{!./src/async_sql_databases/tutorial001.py!}
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! Note

14
docs/advanced/custom-request-and-route.md → docs/en/docs/advanced/custom-request-and-route.md

@ -1,3 +1,5 @@
# Custom Request and APIRoute class
In some cases, you may want to override the logic used by the `Request` and `APIRoute` classes.
In particular, this may be a good alternative to logic in a middleware.
@ -35,7 +37,7 @@ If there's no `gzip` in the header, it will not try to decompress the body.
That way, the same route class can handle gzip compressed or uncompressed requests.
```Python hl_lines="8 9 10 11 12 13 14 15"
{!./src/custom_request_and_route/tutorial001.py!}
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
```
### Create a custom `GzipRoute` class
@ -49,7 +51,7 @@ This method returns a function. And that function is what will receive a request
Here we use it to create a `GzipRequest` from the original request.
```Python hl_lines="18 19 20 21 22 23 24 25 26"
{!./src/custom_request_and_route/tutorial001.py!}
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
```
!!! note "Technical Details"
@ -83,13 +85,13 @@ We can also use this same approach to access the request body in an exception ha
All we need to do is handle the request inside a `try`/`except` block:
```Python hl_lines="13 15"
{!./src/custom_request_and_route/tutorial002.py!}
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
```
If an exception occurs, the`Request` instance will still be in scope, so we can read and make use of the request body when handling the error:
```Python hl_lines="16 17 18"
{!./src/custom_request_and_route/tutorial002.py!}
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
```
## Custom `APIRoute` class in a router
@ -97,11 +99,11 @@ If an exception occurs, the`Request` instance will still be in scope, so we can
You can also set the `route_class` parameter of an `APIRouter`:
```Python hl_lines="26"
{!./src/custom_request_and_route/tutorial003.py!}
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
```
In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:
```Python hl_lines="13 14 15 16 17 18 19 20"
{!./src/custom_request_and_route/tutorial003.py!}
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
```

24
docs/advanced/custom-response.md → docs/en/docs/advanced/custom-response.md

@ -1,3 +1,5 @@
# Custom Response - HTML, Stream, File, others
By default, **FastAPI** will return the responses using `JSONResponse`.
You can override it by returning a `Response` directly as seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}.
@ -20,7 +22,7 @@ For example, if you are squeezing performance, you can install and use <a href="
Import the `Response` class (sub-class) you want to use and declare it in the *path operation decorator*.
```Python hl_lines="2 7"
{!./src/custom_response/tutorial001b.py!}
{!../../../docs_src/custom_response/tutorial001b.py!}
```
!!! info
@ -41,7 +43,7 @@ To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `content_type` of your *path operation*.
```Python hl_lines="2 7"
{!./src/custom_response/tutorial002.py!}
{!../../../docs_src/custom_response/tutorial002.py!}
```
!!! info
@ -58,7 +60,7 @@ As seen in [Return a Response directly](response-directly.md){.internal-link tar
The same example from above, returning an `HTMLResponse`, could look like:
```Python hl_lines="2 7 19"
{!./src/custom_response/tutorial003.py!}
{!../../../docs_src/custom_response/tutorial003.py!}
```
!!! warning
@ -78,7 +80,7 @@ The `response_class` will then be used only to document the OpenAPI *path operat
For example, it could be something like:
```Python hl_lines="7 23 21"
{!./src/custom_response/tutorial004.py!}
{!../../../docs_src/custom_response/tutorial004.py!}
```
In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
@ -116,7 +118,7 @@ It accepts the following parameters:
FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the media_type and appending a charset for text types.
```Python hl_lines="1 18"
{!./src/response_directly/tutorial002.py!}
{!../../../docs_src/response_directly/tutorial002.py!}
```
### `HTMLResponse`
@ -128,7 +130,7 @@ Takes some text or bytes and returns an HTML response, as you read above.
Takes some text or bytes and returns an plain text response.
```Python hl_lines="2 7 9"
{!./src/custom_response/tutorial005.py!}
{!../../../docs_src/custom_response/tutorial005.py!}
```
### `JSONResponse`
@ -149,7 +151,7 @@ An alternative JSON response using <a href="https://github.com/ultrajson/ultrajs
`ujson` is less careful than Python's built-in implementation in how it handles some edge-cases.
```Python hl_lines="2 7"
{!./src/custom_response/tutorial001.py!}
{!../../../docs_src/custom_response/tutorial001.py!}
```
!!! tip
@ -160,7 +162,7 @@ An alternative JSON response using <a href="https://github.com/ultrajson/ultrajs
Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.
```Python hl_lines="2 9"
{!./src/custom_response/tutorial006.py!}
{!../../../docs_src/custom_response/tutorial006.py!}
```
### `StreamingResponse`
@ -168,7 +170,7 @@ Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default
Takes an async generator or a normal generator/iterator and streams the response body.
```Python hl_lines="2 14"
{!./src/custom_response/tutorial007.py!}
{!../../../docs_src/custom_response/tutorial007.py!}
```
#### Using `StreamingResponse` with file-like objects
@ -178,7 +180,7 @@ If you have a file-like object (e.g. the object returned by `open()`), you can r
This includes many libraries to interact with cloud storage, video processing, and others.
```Python hl_lines="2 10 11"
{!./src/custom_response/tutorial008.py!}
{!../../../docs_src/custom_response/tutorial008.py!}
```
!!! tip
@ -198,7 +200,7 @@ Takes a different set of arguments to instantiate than the other response types:
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
```Python hl_lines="2 10"
{!./src/custom_response/tutorial009.py!}
{!../../../docs_src/custom_response/tutorial009.py!}
```
## Additional documentation

5
docs/advanced/events.md → docs/en/docs/advanced/events.md

@ -1,3 +1,4 @@
# Events: startup - shutdown
You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down.
@ -8,7 +9,7 @@ These functions can be declared with `async def` or normal `def`.
To add a function that should be run before the application starts, declare it with the event `"startup"`:
```Python hl_lines="8"
{!./src/events/tutorial001.py!}
{!../../../docs_src/events/tutorial001.py!}
```
In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
@ -22,7 +23,7 @@ And your application won't start receiving requests until all the `startup` even
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
```Python hl_lines="6"
{!./src/events/tutorial002.py!}
{!../../../docs_src/events/tutorial002.py!}
```
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.

20
docs/advanced/extending-openapi.md → docs/en/docs/advanced/extending-openapi.md

@ -1,3 +1,5 @@
# Extending OpenAPI
!!! warning
This is a rather advanced feature. You probably can skip it.
@ -43,7 +45,7 @@ For example, let's add <a href="https://github.com/Rebilly/ReDoc/blob/master/doc
First, write all your **FastAPI** application as normally:
```Python hl_lines="1 4 7 8 9"
{!./src/extending_openapi/tutorial001.py!}
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Generate the OpenAPI schema
@ -51,7 +53,7 @@ First, write all your **FastAPI** application as normally:
Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
```Python hl_lines="2 15 16 17 18 19 20"
{!./src/extending_openapi/tutorial001.py!}
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Modify the OpenAPI schema
@ -59,7 +61,7 @@ Then, use the same utility function to generate the OpenAPI schema, inside a `cu
Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
```Python hl_lines="21 22 23"
{!./src/extending_openapi/tutorial001.py!}
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Cache the OpenAPI schema
@ -71,7 +73,7 @@ That way, your application won't have to generate the schema every time a user o
It will be generated only once, and then the same cached schema will be used for the next requests.
```Python hl_lines="13 14 24 25"
{!./src/extending_openapi/tutorial001.py!}
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Override the method
@ -79,7 +81,7 @@ It will be generated only once, and then the same cached schema will be used for
Now you can replace the `.openapi()` method with your new function.
```Python hl_lines="28"
{!./src/extending_openapi/tutorial001.py!}
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Check it
@ -172,7 +174,7 @@ $ pip install aiofiles
* "Mount" a `StaticFiles()` instance in a specific path.
```Python hl_lines="7 11"
{!./src/extending_openapi/tutorial002.py!}
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
### Test the static files
@ -206,7 +208,7 @@ The first step is to disable the automatic docs, as those use the CDN by default
To disable them, set their URLs to `None` when creating your `FastAPI` app:
```Python hl_lines="9"
{!./src/extending_openapi/tutorial002.py!}
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
### Include the custom docs
@ -224,7 +226,7 @@ You can re-use FastAPI's internal functions to create the HTML pages for the doc
And similarly for ReDoc...
```Python hl_lines="2 3 4 5 6 14 15 16 17 18 19 20 21 22 25 26 27 30 31 32 33 34 35 36"
{!./src/extending_openapi/tutorial002.py!}
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
!!! tip
@ -239,7 +241,7 @@ And similarly for ReDoc...
Now, to be able to test that everything works, create a *path operation*:
```Python hl_lines="39 40 41"
{!./src/extending_openapi/tutorial002.py!}
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
### Test it

5
docs/advanced/graphql.md → docs/en/docs/advanced/graphql.md

@ -1,3 +1,4 @@
# GraphQL
**FastAPI** has optional support for GraphQL (provided by Starlette directly), using the `graphene` library.
@ -10,7 +11,7 @@ GraphQL is implemented with Graphene, you can check <a href="https://docs.graphe
Import `graphene` and define your GraphQL data:
```Python hl_lines="1 6 7 8 9 10"
{!./src/graphql/tutorial001.py!}
{!../../../docs_src/graphql/tutorial001.py!}
```
## Add Starlette's `GraphQLApp`
@ -18,7 +19,7 @@ Import `graphene` and define your GraphQL data:
Then import and add Starlette's `GraphQLApp`:
```Python hl_lines="3 14"
{!./src/graphql/tutorial001.py!}
{!../../../docs_src/graphql/tutorial001.py!}
```
!!! info

2
docs/advanced/index.md → docs/en/docs/advanced/index.md

@ -1,3 +1,5 @@
# Advanced User Guide - Intro
## Additional Features
The main [Tutorial - User Guide](../tutorial/){.internal-link target=_blank} should be enough to give you a tour through all the main features of **FastAPI**.

8
docs/advanced/middleware.md → docs/en/docs/advanced/middleware.md

@ -1,3 +1,5 @@
# Advanced Middleware
In the main tutorial you read how to add [Custom Middleware](../tutorial/middleware.md){.internal-link target=_blank} to your application.
And then you also read how to handle [CORS with the `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
@ -53,7 +55,7 @@ Enforces that all incoming requests must either be `https` or `wss`.
Any incoming requests to `http` or `ws` will be redirected to the secure scheme instead.
```Python hl_lines="2 6"
{!./src/advanced_middleware/tutorial001.py!}
{!../../../docs_src/advanced_middleware/tutorial001.py!}
```
## `TrustedHostMiddleware`
@ -61,7 +63,7 @@ Any incoming requests to `http` or `ws` will be redirected to the secure scheme
Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.
```Python hl_lines="2 6 7 8"
{!./src/advanced_middleware/tutorial002.py!}
{!../../../docs_src/advanced_middleware/tutorial002.py!}
```
The following arguments are supported:
@ -77,7 +79,7 @@ Handles GZip responses for any request that includes `"gzip"` in the `Accept-Enc
The middleware will handle both standard and streaming responses.
```Python hl_lines="2 6 7 8"
{!./src/advanced_middleware/tutorial002.py!}
{!../../../docs_src/advanced_middleware/tutorial002.py!}
```
The following arguments are supported:

18
docs/advanced/nosql-databases.md → docs/en/docs/advanced/nosql-databases.md

@ -1,3 +1,5 @@
# NoSQL (Distributed / Big Data) Databases
**FastAPI** can also be integrated with any <abbr title="Distributed database (Big Data), also 'Not Only SQL'">NoSQL</abbr>.
Here we'll see an example using **<a href="https://www.couchbase.com/" class="external-link" target="_blank">Couchbase</a>**, a <abbr title="Document here refers to a JSON object (a dict), with keys and values, and those values can also be other JSON objects, arrays (lists), numbers, strings, booleans, etc.">document</abbr> based NoSQL database.
@ -18,7 +20,7 @@ You can adapt it to any other NoSQL database like:
For now, don't pay attention to the rest, only the imports:
```Python hl_lines="6 7 8"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Define a constant to use as a "document type"
@ -28,7 +30,7 @@ We will use it later as a fixed field `type` in our documents.
This is not required by Couchbase, but is a good practice that will help you afterwards.
```Python hl_lines="10"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Add a function to get a `Bucket`
@ -53,7 +55,7 @@ This utility function will:
* Return it.
```Python hl_lines="13 14 15 16 17 18 19 20 21 22"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Create Pydantic models
@ -65,7 +67,7 @@ As **Couchbase** "documents" are actually just "JSON objects", we can model them
First, let's create a `User` model:
```Python hl_lines="25 26 27 28 29"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
We will use this model in our *path operation function*, so, we don't include in it the `hashed_password`.
@ -79,7 +81,7 @@ This will have the data that is actually stored in the database.
We don't create it as a subclass of Pydantic's `BaseModel` but as a subclass of our own `User`, because it will have all the attributes in `User` plus a couple more:
```Python hl_lines="32 33 34"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
!!! note
@ -99,7 +101,7 @@ Now create a function that will:
By creating a function that is only dedicated to getting your user from a `username` (or any other parameter) independent of your *path operation function*, you can more easily re-use it in multiple parts and also add <abbr title="Automated test, written in code, that checks if another piece of code is working correctly.">unit tests</abbr> for it:
```Python hl_lines="37 38 39 40 41 42 43"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
### f-strings
@ -134,7 +136,7 @@ UserInDB(username="johndoe", hashed_password="some_hash")
### Create the `FastAPI` app
```Python hl_lines="47"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
### Create the *path operation function*
@ -144,7 +146,7 @@ As our code is calling Couchbase and we are not using the <a href="https://docs.
Also, Couchbase recommends not using a single `Bucket` object in multiple "<abbr title="A sequence of code being executed by the program, while at the same time, or at intervals, there can be others being executed too.">thread</abbr>s", so, we can get just get the bucket directly and pass it to our utility functions:
```Python hl_lines="50 51 52 53 54"
{!./src/nosql_databases/tutorial001.py!}
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Recap

10
docs/advanced/openapi-callbacks.md → docs/en/docs/advanced/openapi-callbacks.md

@ -1,3 +1,5 @@
# OpenAPI Callbacks
You could create an API with a *path operation* that could trigger a request to an *external API* created by someone else (probably the same developer that would be *using* your API).
The process that happens when your API app calls the *external API* is named a "callback". Because the software that the external developer wrote sends a request to your API and then your API *calls back*, sending a request to an *external API* (that was probably created by the same developer).
@ -30,7 +32,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query
This part is pretty normal, most of the code is probably already familiar to you:
```Python hl_lines="8 9 10 11 12 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53"
{!./src/openapi_callbacks/tutorial001.py!}
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
!!! tip
@ -91,7 +93,7 @@ Because of that, you need to declare what will be the `default_response_class`,
But as we are never calling `app.include_router(some_router)`, we need to set the `default_response_class` during creation of the `APIRouter`.
```Python hl_lines="3 24"
{!./src/openapi_callbacks/tutorial001.py!}
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
### Create the callback *path operation*
@ -104,7 +106,7 @@ It should look just like a normal FastAPI *path operation*:
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.
```Python hl_lines="15 16 17 20 21 27 28 29 30 31"
{!./src/openapi_callbacks/tutorial001.py!}
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
There are 2 main differences from a normal *path operation*:
@ -171,7 +173,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that
Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:
```Python hl_lines="34"
{!./src/openapi_callbacks/tutorial001.py!}
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
!!! tip

10
docs/advanced/path-operation-advanced-configuration.md → docs/en/docs/advanced/path-operation-advanced-configuration.md

@ -1,3 +1,5 @@
# Path Operation Advanced Configuration
## OpenAPI operationId
!!! warning
@ -8,7 +10,7 @@ You can set the OpenAPI `operationId` to be used in your *path operation* with t
You would have to make sure that it is unique for each operation.
```Python hl_lines="6"
{!./src/path_operation_advanced_configuration/tutorial001.py!}
{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### Using the *path operation function* name as the operationId
@ -18,7 +20,7 @@ If you want to use your APIs' function names as `operationId`s, you can iterate
You should do it after adding all your *path operations*.
```Python hl_lines="2 12 13 14 15 16 17 18 19 20 21 24"
{!./src/path_operation_advanced_configuration/tutorial002.py!}
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
!!! tip
@ -34,7 +36,7 @@ You should do it after adding all your *path operations*.
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`;
```Python hl_lines="6"
{!./src/path_operation_advanced_configuration/tutorial003.py!}
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## Advanced description from docstring
@ -46,5 +48,5 @@ Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate
It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.
```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
{!./src/path_operation_advanced_configuration/tutorial004.py!}
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```

4
docs/advanced/response-change-status-code.md → docs/en/docs/advanced/response-change-status-code.md

@ -1,3 +1,5 @@
# Response - Change Status Code
You probably read before that you can set a default [Response Status Code](../tutorial/response-status-code.md){.internal-link target=_blank}.
But in some cases you need to return a different status code than the default.
@ -19,7 +21,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set the `status_code` in that *temporal* response object.
```Python hl_lines="1 9 12"
{!./src/response_change_status_code/tutorial001.py!}
{!../../../docs_src/response_change_status_code/tutorial001.py!}
```
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).

6
docs/advanced/response-cookies.md → docs/en/docs/advanced/response-cookies.md

@ -1,3 +1,5 @@
# Response Cookies
## Use a `Response` parameter
You can declare a parameter of type `Response` in your *path operation function*.
@ -5,7 +7,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set cookies in that *temporal* response object.
```Python hl_lines="1 8 9"
{!./src/response_cookies/tutorial002.py!}
{!../../../docs_src/response_cookies/tutorial002.py!}
```
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@ -25,7 +27,7 @@ To do that, you can create a response as described in [Return a Response Directl
Then set Cookies in it, and then return it:
```Python hl_lines="10 11 12"
{!./src/response_cookies/tutorial001.py!}
{!../../../docs_src/response_cookies/tutorial001.py!}
```
!!! tip

6
docs/advanced/response-directly.md → docs/en/docs/advanced/response-directly.md

@ -1,3 +1,5 @@
# Return a Response Directly
When you create a **FastAPI** *path operation* you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc.
By default, **FastAPI** would automatically convert that return value to JSON using the `jsonable_encoder` explained in [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
@ -30,7 +32,7 @@ For example, you cannot put a Pydantic model in a `JSONResponse` without first c
For those cases, you can use the `jsonable_encoder` to convert your data before passing it to a response:
```Python hl_lines="4 6 20 21"
{!./src/response_directly/tutorial001.py!}
{!../../../docs_src/response_directly/tutorial001.py!}
```
!!! note "Technical Details"
@ -49,7 +51,7 @@ Let's say that you want to return an <a href="https://en.wikipedia.org/wiki/XML"
You could put your XML content in a string, put it in a `Response`, and return it:
```Python hl_lines="1 18"
{!./src/response_directly/tutorial002.py!}
{!../../../docs_src/response_directly/tutorial002.py!}
```
## Notes

6
docs/advanced/response-headers.md → docs/en/docs/advanced/response-headers.md

@ -1,3 +1,5 @@
# Response Headers
## Use a `Response` parameter
You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies).
@ -5,7 +7,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set headers in that *temporal* response object.
```Python hl_lines="1 7 8"
{!./src/response_headers/tutorial002.py!}
{!../../../docs_src/response_headers/tutorial002.py!}
```
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@ -23,7 +25,7 @@ You can also add headers when you return a `Response` directly.
Create a response as described in [Return a Response Directly](response-directly.md){.internal-link target=_blank} and pass the headers as an additional parameter:
```Python hl_lines="10 11 12"
{!./src/response_headers/tutorial001.py!}
{!../../../docs_src/response_headers/tutorial001.py!}
```
!!! note "Technical Details"

8
docs/advanced/security/http-basic-auth.md → docs/en/docs/advanced/security/http-basic-auth.md

@ -1,3 +1,5 @@
# HTTP Basic Auth
For the simplest cases, you can use HTTP Basic Auth.
In HTTP Basic Auth, the application expects a header that contains a username and a password.
@ -19,7 +21,7 @@ Then, when you type that username and password, the browser sends them in the he
* It contains the `username` and `password` sent.
```Python hl_lines="2 6 10"
{!./src/security/tutorial006.py!}
{!../../../docs_src/security/tutorial006.py!}
```
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
@ -35,7 +37,7 @@ Use a dependency to check if the username and password are correct.
For this, use the Python standard module <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> to check the username and password:
```Python hl_lines="1 11 12 13"
{!./src/security/tutorial007.py!}
{!../../../docs_src/security/tutorial007.py!}
```
This will ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`. This would be similar to:
@ -101,5 +103,5 @@ That way, using `secrets.compare_digest()` in your application code, it will be
After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:
```Python hl_lines="15 16 17 18 19"
{!./src/security/tutorial007.py!}
{!../../../docs_src/security/tutorial007.py!}
```

2
docs/advanced/security/index.md → docs/en/docs/advanced/security/index.md

@ -1,3 +1,5 @@
# Advanced Security - Intro
## Additional Features
There are some extra features to handle security apart from the ones covered in the [Tutorial - User Guide: Security](../../tutorial/security/){.internal-link target=_blank}.

18
docs/advanced/security/oauth2-scopes.md → docs/en/docs/advanced/security/oauth2-scopes.md

@ -1,3 +1,5 @@
# OAuth2 scopes
You can use OAuth2 scopes directly with **FastAPI**, they are integrated to work seamlessly.
This would allow you to have a more fine-grained permission system, following the OAuth2 standard, integrated into your OpenAPI application (and the API docs).
@ -55,7 +57,7 @@ They are normally used to declare specific security permissions, for example:
First, let's quickly see the parts that change from the examples in the main **Tutorial - User Guide** for [OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Now using OAuth2 scopes:
```Python hl_lines="2 5 9 13 47 65 106 108 109 110 111 112 113 114 115 116 122 123 124 125 129 130 131 132 133 134 135 140 154"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
Now let's review those changes step by step.
@ -67,7 +69,7 @@ The first change is that now we are declaring the OAuth2 security scheme with tw
The `scopes` parameter receives a `dict` with each scope as a key and the description as the value:
```Python hl_lines="63 64 65 66"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
Because we are now declaring those scopes, they will show up in the API docs when you log-in/authorize.
@ -92,7 +94,7 @@ And we return the scopes as part of the JWT token.
But in your application, for security, you should make sure you only add the scopes that the user is actually able to have, or the ones you have predefined.
```Python hl_lines="155"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
## Declare scopes in *path operations* and dependencies
@ -117,7 +119,7 @@ In this case, it requires the scope `me` (it could require more than one scope).
We are doing it here to demonstrate how **FastAPI** handles scopes declared at different levels.
```Python hl_lines="5 140 167"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
!!! info "Technical Details"
@ -142,7 +144,7 @@ We also declare a special parameter of type `SecurityScopes`, imported from `fas
This `SecurityScopes` class is similar to `Request` (`Request` was used to get the request object directly).
```Python hl_lines="9 106"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
## Use the `scopes`
@ -158,7 +160,7 @@ We create an `HTTPException` that we can re-use (`raise`) later at several point
In this exception, we include the scopes required (if any) as a string separated by spaces (using `scope_str`). We put that string containing the scopes in in the `WWW-Authenticate` header (this is part of the spec).
```Python hl_lines="106 108 109 110 111 112 113 114 115 116"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
## Verify the `username` and data shape
@ -176,7 +178,7 @@ Instead of, for example, a `dict`, or something else, as it could break the appl
We also verify that we have a user with that username, and if not, we raise that same exception we created before.
```Python hl_lines="47 117 118 119 120 121 122 123 124 125 126 127 128"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
## Verify the `scopes`
@ -186,7 +188,7 @@ We now verify that all the scopes required, by this dependency and all the depen
For this, we use `security_scopes.scopes`, that contains a `list` with all these scopes as `str`.
```Python hl_lines="129 130 131 132 133 134 135"
{!./src/security/tutorial005.py!}
{!../../../docs_src/security/tutorial005.py!}
```
## Dependency tree and scopes

36
docs/advanced/sql-databases-peewee.md → docs/en/docs/advanced/sql-databases-peewee.md

@ -1,3 +1,5 @@
# SQL (Relational) Databases with Peewee
!!! warning
If you are just starting, the tutorial [SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank} that uses SQLAlchemy should be enough.
@ -60,7 +62,7 @@ Let's refer to the file `sql_app/database.py`.
Let's first check all the normal Peewee code, create a Peewee database:
```Python hl_lines="3 5 22"
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
!!! tip
@ -112,7 +114,7 @@ This might seem a bit complex (and it actually is), you don't really need to com
We will create a `PeeweeConnectionState`:
```Python hl_lines="10 11 12 13 14 15 16 17 18 19"
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
This class inherits from a special internal class used by Peewee.
@ -133,7 +135,7 @@ So, we need to do some extra tricks to make it work as if it was just using `thr
Now, overwrite the `._state` internal attribute in the Peewee database `db` object using the new `PeeweeConnectionState`:
```Python hl_lines="24"
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
!!! tip
@ -160,7 +162,7 @@ This is the same you would do if you followed the Peewee tutorial and updated th
Import `db` from `database` (the file `database.py` from above) and use it here.
```Python hl_lines="3 6 7 8 9 10 11 12 15 16 17 18 19 20 21"
{!./src/sql_databases_peewee/sql_app/models.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
```
!!! tip
@ -188,7 +190,7 @@ Now let's check the file `sql_app/schemas.py`.
Create all the same Pydantic models as in the SQLAlchemy tutorial:
```Python hl_lines="16 17 18 21 22 25 26 27 28 29 30 34 35 38 39 42 43 44 45 46 47 48"
{!./src/sql_databases_peewee/sql_app/schemas.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
!!! tip
@ -213,7 +215,7 @@ But recent versions of Pydantic allow providing a custom class that inherits fro
We are going to create a custom `PeeweeGetterDict` class and use it in all the same Pydantic *models* / schemas that use `orm_mode`:
```Python hl_lines="3 8 9 10 11 12 13 31 49"
{!./src/sql_databases_peewee/sql_app/schemas.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
Here we are checking if the attribute that is being accessed (e.g. `.items` in `some_user.items`) is an instance of `peewee.ModelSelect`.
@ -234,7 +236,7 @@ Now let's see the file `sql_app/crud.py`.
Create all the same CRUD utils as in the SQLAlchemy tutorial, all the code is very similar:
```Python hl_lines="1 4 5 8 9 12 13 16 17 18 19 20 23 24 27 28 29 30"
{!./src/sql_databases_peewee/sql_app/crud.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
```
There are some differences with the code for the SQLAlchemy tutorial.
@ -258,7 +260,7 @@ And now in the file `sql_app/main.py` let's integrate and use all the other part
In a very simplistic way create the database tables:
```Python hl_lines="9 10 11"
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
### Create a dependency
@ -266,7 +268,7 @@ In a very simplistic way create the database tables:
Create a dependency that will connect the database right at the beginning of a request and disconnect it at the end:
```Python hl_lines="23 24 25 26 27 28 29"
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
Here we have an empty `yield` because we are actually not using the database object directly.
@ -280,7 +282,7 @@ And then, in each *path operation function* that needs to access the database we
But we are not using the value given by this dependency (it actually doesn't give any value, as it has an empty `yield`). So, we don't add it to the *path operation function* but to the *path operation decorator* in the `dependencies` parameter:
```Python hl_lines="32 40 47 59 65 72"
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
### Context variable sub-dependency
@ -290,7 +292,7 @@ For all the `contextvars` parts to work, we need to make sure we have an indepen
For that, we need to create another `async` dependency `reset_db_state()` that is used as a sub-dependency in `get_db()`. It will set the value for the context variable (with just a default `dict`) that will be used as the database state for the whole request. And then the dependency `get_db()` will store in it the database state (connection, transactions, etc).
```Python hl_lines="18 19 20"
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
For the **next request**, as we will reset that context variable again in the `async` dependency `reset_db_state()` and then create a new connection in the `get_db()` dependency, that new request will have its own database state (connection, transactions, etc).
@ -319,7 +321,7 @@ async def reset_db_state():
Now, finally, here's the standard **FastAPI** *path operations* code.
```Python hl_lines="32 33 34 35 36 37 40 41 42 43 46 47 48 49 50 51 52 53 56 57 58 59 60 61 62 65 66 67 68 71 72 73 74 75 76 77 78 79"
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
### About `def` vs `async def`
@ -436,31 +438,31 @@ Repeat the same process with the 10 tabs. This time all of them will wait and yo
* `sql_app/database.py`:
```Python
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
* `sql_app/models.py`:
```Python
{!./src/sql_databases_peewee/sql_app/models.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
```
* `sql_app/schemas.py`:
```Python
{!./src/sql_databases_peewee/sql_app/schemas.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
* `sql_app/crud.py`:
```Python
{!./src/sql_databases_peewee/sql_app/crud.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
```
* `sql_app/main.py`:
```Python
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
## Technical Details

8
docs/advanced/sub-applications-proxy.md → docs/en/docs/advanced/sub-applications-proxy.md

@ -1,3 +1,5 @@
# Sub Applications - Behind a Proxy, Mounts
There are at least two situations where you could need to create your **FastAPI** application using some specific paths.
But then you need to set them up to be served with a path prefix.
@ -44,7 +46,7 @@ You could want to do this if you have several "independent" applications that yo
First, create the main, top-level, **FastAPI** application, and its *path operations*:
```Python hl_lines="3 6 7 8"
{!./src/sub_applications/tutorial001.py!}
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Sub-application
@ -56,7 +58,7 @@ This sub-application is just another standard FastAPI application, but this is t
When creating the sub-application, use the parameter `openapi_prefix`. In this case, with a prefix of `/subapi`:
```Python hl_lines="11 14 15 16"
{!./src/sub_applications/tutorial001.py!}
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Mount the sub-application
@ -66,7 +68,7 @@ In your top-level application, `app`, mount the sub-application, `subapi`.
Here you need to make sure you use the same path that you used for the `openapi_prefix`, in this case, `/subapi`:
```Python hl_lines="11 19"
{!./src/sub_applications/tutorial001.py!}
{!../../../docs_src/sub_applications/tutorial001.py!}
```
## Check the automatic API docs

10
docs/advanced/templates.md → docs/en/docs/advanced/templates.md

@ -1,3 +1,5 @@
# Templates
You can use any template engine you want with **FastAPI**.
A common election is Jinja2, the same one used by Flask and other tools.
@ -38,7 +40,7 @@ $ pip install aiofiles
* Use the `templates` you created to render and return a `TemplateResponse`, passing the `request` as one of the key-value pairs in the Jinja2 "context".
```Python hl_lines="3 10 14 15"
{!./src/templates/tutorial001.py!}
{!../../../docs_src/templates/tutorial001.py!}
```
!!! note
@ -54,7 +56,7 @@ $ pip install aiofiles
Then you can write a template at `templates/item.html` with:
```jinja hl_lines="7"
{!./src/templates/templates/item.html!}
{!../../../docs_src/templates/templates/item.html!}
```
It will show the `id` taken from the "context" `dict` you passed:
@ -68,13 +70,13 @@ It will show the `id` taken from the "context" `dict` you passed:
And you can also use `url_for()` inside of the template, and use it, for example, with the `StaticFiles` you mounted.
```jinja hl_lines="4"
{!./src/templates/templates/item.html!}
{!../../../docs_src/templates/templates/item.html!}
```
In this example, it would link to a CSS file at `static/styles.css` with:
```CSS hl_lines="4"
{!./src/templates/static/styles.css!}
{!../../../docs_src/templates/static/styles.css!}
```
And because you are using `StaticFiles`, that CSS file would be served automatically by your **FastAPI** application at the URL `/static/styles.css`.

4
docs/advanced/testing-dependencies.md → docs/en/docs/advanced/testing-dependencies.md

@ -1,3 +1,5 @@
# Testing Dependencies with Overrides
## Overriding dependencies during testing
There are some scenarios where you might want to override a dependency during testing.
@ -39,7 +41,7 @@ To override a dependency for testing, you put as a key the original dependency (
And then **FastAPI** will call that override instead of the original dependency.
```Python hl_lines="24 25 28"
{!./src/dependency_testing/tutorial001.py!}
{!../../../docs_src/dependency_testing/tutorial001.py!}
```
!!! tip

6
docs/advanced/testing-events.md → docs/en/docs/advanced/testing-events.md

@ -1,7 +1,7 @@
## Testing Events, `startup` and `shutdown`
# Testing Events: startup - shutdown
When you need your event handlers (`startup` and `shutdown`) to run in your tests, you can use the `TestClient` with a `with` statement:
```Python hl_lines="9 10 11 12 20 21 22 23 24"
{!./src/app_testing/tutorial003.py!}
```
{!../../../docs_src/app_testing/tutorial003.py!}
```

4
docs/advanced/testing-websockets.md → docs/en/docs/advanced/testing-websockets.md

@ -1,9 +1,9 @@
## Testing WebSockets
# Testing WebSockets
You can use the same `TestClient` to test WebSockets.
For this, you use the `TestClient` in a `with` statement, connecting to the WebSocket:
```Python hl_lines="27 28 29 30 31"
{!./src/app_testing/tutorial002.py!}
{!../../../docs_src/app_testing/tutorial002.py!}
```

4
docs/advanced/using-request-directly.md → docs/en/docs/advanced/using-request-directly.md

@ -1,3 +1,5 @@
# Using the Request Directly
Up to now, you have been declaring the parts of the request that you need with their types.
Taking data from:
@ -28,7 +30,7 @@ Let's imagine you want to get the client's IP address/host inside of your *path
For that you need to access the request directly.
```Python hl_lines="1 7 8"
{!./src/using_request_directly/tutorial001.py!}
{!../../../docs_src/using_request_directly/tutorial001.py!}
```
By declaring a *path operation function* parameter with the type being the `Request` **FastAPI** will know to pass the `Request` in that parameter.

9
docs/advanced/websockets.md → docs/en/docs/advanced/websockets.md

@ -1,3 +1,4 @@
# WebSockets
You can use <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a> with **FastAPI**.
@ -24,7 +25,7 @@ In production you would have one of the options above.
But it's the simplest way to focus on the server-side of WebSockets and have a working example:
```Python hl_lines="2 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 41 42 43"
{!./src/websockets/tutorial001.py!}
{!../../../docs_src/websockets/tutorial001.py!}
```
## Create a `websocket`
@ -32,7 +33,7 @@ But it's the simplest way to focus on the server-side of WebSockets and have a w
In your **FastAPI** application, create a `websocket`:
```Python hl_lines="1 46 47"
{!./src/websockets/tutorial001.py!}
{!../../../docs_src/websockets/tutorial001.py!}
```
!!! note "Technical Details"
@ -45,7 +46,7 @@ In your **FastAPI** application, create a `websocket`:
In your WebSocket route you can `await` for messages and send messages.
```Python hl_lines="48 49 50 51 52"
{!./src/websockets/tutorial001.py!}
{!../../../docs_src/websockets/tutorial001.py!}
```
You can receive and send binary, text, and JSON data.
@ -64,7 +65,7 @@ In WebSocket endpoints you can import from `fastapi` and use:
They work the same way as for other FastAPI endpoints/*path operations*:
```Python hl_lines="53 54 55 56 57 58 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76"
{!./src/websockets/tutorial002.py!}
{!../../../docs_src/websockets/tutorial002.py!}
```
!!! info

4
docs/advanced/wsgi.md → docs/en/docs/advanced/wsgi.md

@ -1,3 +1,5 @@
# Including WSGI - Flask, Django, others
You can mount WSGI applications as you saw with [Sub Applications - Behind a Proxy, Mounts](./sub-applications-proxy.md){.internal-link target=_blank}.
For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI application, for example, Flask, Django, etc.
@ -11,7 +13,7 @@ Then wrap the WSGI (e.g. Flask) app with the middleware.
And then mount that under a path.
```Python hl_lines="1 3 22"
{!./src/wsgi/tutorial001.py!}
{!../../../docs_src/wsgi/tutorial001.py!}
```
## Check it

2
docs/alternatives.md → docs/en/docs/alternatives.md

@ -1,3 +1,5 @@
# Alternatives, Inspiration and Comparisons
What inspired **FastAPI**, how it compares to other alternatives and what it learned from them.
## Intro

2
docs/async.md → docs/en/docs/async.md

@ -1,3 +1,5 @@
# Concurrency and async / await
Details about the `async def` syntax for *path operation functions* and some background about asynchronous code, concurrency, and parallelism.
## In a hurry?

2
docs/benchmarks.md → docs/en/docs/benchmarks.md

@ -1,3 +1,5 @@
# Benchmarks
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
But when checking benchmarks and comparisons you should have the following in mind.

441
docs/en/docs/contributing.md

@ -0,0 +1,441 @@
# Development - Contributing
First, you might want to see the basic ways to [help FastAPI and get help](help-fastapi.md){.internal-link target=_blank}.
## Developing
If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.
### Virtual environment with `venv`
You can create a virtual environment in a directory using Python's `venv` module:
<div class="termy">
```console
$ python -m venv env
```
</div>
That will create a directory `./env/` with the Python binaries and then you will be able to install packages for that isolated environment.
### Activate the environment
Activate the new environment with:
<div class="termy">
```console
$ source ./env/bin/activate
```
</div>
Or in Windows' PowerShell:
<div class="termy">
```console
$ .\env\Scripts\Activate.ps1
```
</div>
Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
<div class="termy">
```console
$ source ./env/Scripts/activate
```
</div>
To check it worked, use:
<div class="termy">
```console
$ which pip
some/directory/fastapi/env/bin/pip
```
</div>
If it shows the `pip` binary at `env/bin/pip` then it worked. 🎉
Or in Windows PowerShell:
<div class="termy">
```console
$ Get-Command pip
some/directory/fastapi/env/bin/pip
```
</div>
!!! tip
Every time you install a new package with `pip` under that environment, activate the environment again.
This makes sure that if you use a terminal program installed by that package (like `flit`), you use the one from your local environment and not any other that could be installed globally.
### Flit
**FastAPI** uses <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> to build, package and publish the project.
After activating the environment as described above, install `flit`:
<div class="termy">
```console
$ pip install flit
---> 100%
```
</div>
Now re-activate the environment to make sure you are using the `flit` you just installed (and not a global one).
And now use `flit` to install the development dependencies:
<div class="termy">
```console
$ flit install --deps develop --symlink
---> 100%
```
</div>
It will install all the dependencies and your local FastAPI in your local environment.
#### Using your local FastAPI
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
And if you update that local FastAPI source code, as it is installed with `--symlink`, when you run that Python file again, it will use the fresh version of FastAPI you just edited.
That way, you don't have to "install" your local version to be able to test every change.
### Format
There is a script that you can run that will format and clean all your code:
<div class="termy">
```console
$ bash scripts/format.sh
```
</div>
It will also auto-sort all your imports.
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above:
<div class="termy">
```console
$ flit install --symlink
---> 100%
```
</div>
### Format imports
There is another script that formats all the imports and makes sure you don't have unused imports:
<div class="termy">
```console
$ bash scripts/format-imports.sh
```
</div>
As it runs one command after the other and modifies and reverts many files, it takes a bit longer to run, so it might be easier to use `scripts/format.sh` frequently and `scripts/format-imports.sh` only before committing.
## Docs
First, make sure you set up your environment as described above, that will install all the requirements.
The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
And there are extra tools/scripts in place to handle translations in `./scripts/docs.py`.
!!! tip
You don't need to see the code in `./scripts/docs.py`, you just use it in the command line.
All the documentation is in Markdown format in the directory `./docs/en/`.
Many of the tutorials have blocks of code.
In most of the cases, these blocks of code are actual complete applications that can be run as is.
In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs_src/` directory.
And those Python files are included/injected in the documentation when generating the site.
### Docs for tests
Most of the tests actually run against the example source files in the documentation.
This helps making sure that:
* The documentation is up to date.
* The documentation examples can be run as is.
* Most of the features are covered by the documentation, ensured by test coverage.
During local development, there is a script that builds the site and checks for any changes, live-reloading:
<div class="termy">
```console
$ python ./scripts/docs.py live
<span style="color: green;">[INFO]</span> Serving on http://0.0.0.0:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
It will serve the documentation on `http://0.0.0.0:8008`.
That way, you can edit the documentation/source files and see the changes live.
#### Typer CLI (optional)
The instructions here show you how to use the script at `./scripts/docs.py` with the `python` program directly.
But you can also use <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">Typer CLI</a>, and you will get autocompletion in your terminal for the commands after installing completion.
If you install Typer CLI, you can install completion with:
<div class="termy">
```console
$ typer --install-completion
zsh completion installed in /home/user/.bashrc.
Completion will take effect once you restart the terminal.
```
</div>
### Apps and docs at the same time
If you run the examples with, e.g.:
<div class="termy">
```console
$ uvicorn tutorial001:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
as Uvicorn by default will use the port `8000`, the documentation on port `8008` won't clash.
### Translations
Help with translations is VERY MUCH appreciated! And it can't be done without the help from the community. 🌎 🚀
Here are the steps to help with translations.
#### Tips
✨ Add a single Pull Request per page translated. That will make it much easier for others to review it.
For the languages I don't speak, I'll wait for several others to review the translation before merging.
✨ You can also check if there are translations for your language and add a review to them, that will help me know that the translation is correct and I can merge it.
✨ To check the 2-letter code for the language you want to translate you can use the table <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">List of ISO 639-1 codes</a>.
#### Existing language
Let's say you want to translate a page for a language that already has translations for some pages, like Spanish.
In the case of Spanish, the 2-letter code is `es`. So, the directory for Spanish translations is located at `docs/es/`.
!!! tip
The main ("official") language is English, located at `docs/en/`.
Now run the live server for the docs in Spanish:
<div class="termy">
```console
// Use the command "live" and pass the language code as a CLI argument
$ python ./scripts/docs.py live es
<span style="color: green;">[INFO]</span> Serving on http://0.0.0.0:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
Now you can go to <a href="http://0.0.0.0:8008" class="external-link" target="_blank">http://0.0.0.0:8008</a> and see your changes live.
If you look at the FastAPI docs website, you will see that every language has all the pages. But some are not translated and have a notification about the the translation is missing.
But when you run it locally like this, you will only see the pages that are already translated.
Now let's say that you want to add a translation for the section [Advanced User Guide: Extending OpenAPI](advanced/extending-openapi.md){.internal-link target=_blank}.
* Copy the file at:
```
docs/en/docs/advanced/extending-openapi.md
```
* Paste it in exactly the same location but for the language you want to translate, e.g.:
```
docs/es/docs/advanced/extending-openapi.md
```
!!! tip
Notice that the only change in the path and file name is the language code, from `en` to `es`.
* Now open the MkDocs config file at:
```
docs/en/docs/mkdocs.yml
```
* Find the place where that `advanced/extending-openapi.md` is located in the config file. Somewhere like:
```YAML hl_lines="9"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
# More stuff
- Advanced User Guide:
# More stuff
- advanced/testing-dependencies.md
- advanced/extending-openapi.md
- advanced/openapi-callbacks.md
```
* Open the MkDocs config file for the language you are editing, e.g.:
```
docs/es/docs/mkdocs.yml
```
* Add the equivalent structure code and add it at the exact same location it would be, e.g.:
```YAML hl_lines="6 9"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
# More stuff
- Guía de Usuario Avanzada:
# More stuff
- advanced/testing-dependencies.md
- advanced/extending-openapi.md
- advanced/openapi-callbacks.md
```
Notice that the `Advanced User Guide` is translated to `Guía de Usuario Avanzada`.
Also, make sure that if there are other entries, the new entry with your translation is in exactly in the same order as in the English version.
If you go to your browser you will see that now the docs show your new section. 🎉
Now you can translate it all and see how it looks as you save the file.
#### New Language
Let's say that you want to add translations for a language that is not yet translated, not even some pages.
Let's say you want to add translations for Creole, and it's not yet there in the docs.
Checking the link from above, the code for "Creole" is `ht`.
The next step is to run the script to generate a new translation directory:
<div class="termy">
```console
// Use the command new-lang, pass the language code as a CLI argument
$ python ./scripts/docs.py new-lang ht
Successfully initialized: docs/ht
Updating ht
Updating en
```
</div>
Now you can check in your code editor the newly created directory `docs/ht/`.
Start by translating the main page, `docs/ht/index.md`.
Then you can continue with the previous instructions, for an "Existing Language".
##### New Language not supported
If when running the live server script you get an error about the language not being supported, something like:
```
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: partials/language/xx.html
```
That means that the theme doesn't support that language (in this case, with a fake 2-letter code of `xx`).
But don't worry, you can set the theme language to English and then translate the content of the docs.
If you need to do that, edit the `mkdocs.yml` for your new language, it will have something like:
```YAML hl_lines="5"
site_name: FastAPI
# More stuff
theme:
# More stuff
language: xx
```
Change that language from `xx` (from your language code) to `en`.
Then you can start the live server again.
## Tests
There is a script that you can run locally to test all the code and generate coverage reports in HTML:
<div class="termy">
```console
$ bash scripts/test-cov-html.sh
```
</div>
This command generates a directory `./htmlcov/`, if you open the file `./htmlcov/index.html` in your browser, you can explore interactively the regions of code that are covered by the tests, and notice if there is any region missing.
### Tests in your editor
If you want to use the integrated tests in your editor add `./docs/src` to your `PYTHONPATH` variable.
For example, in VS Code you can create a file `.env` with:
```env
PYTHONPATH=./docs/src
```

0
docs/css/custom.css → docs/en/docs/css/custom.css

0
docs/css/termynal.css → docs/en/docs/css/termynal.css

2
docs/deployment.md → docs/en/docs/deployment.md

@ -1,3 +1,5 @@
# Deployment
Deploying a **FastAPI** application is relatively easy.
There are several ways to do it depending on your specific use case and the tools that you use.

2
docs/external-links.md → docs/en/docs/external-links.md

@ -1,3 +1,5 @@
# External Links and Articles
**FastAPI** has a great community constantly growing.
There are many posts, articles, tools, and projects, related to **FastAPI**.

9
docs/features.md → docs/en/docs/features.md

@ -1,3 +1,4 @@
# Features
## FastAPI features
@ -16,11 +17,11 @@ Interactive API documentation and exploration web user interfaces. As the framew
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, with interactive exploration, call and test your API directly from the browser.
![Swagger UI interaction](img/index/index-03-swagger-02.png)
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Alternative API documentation with <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
![ReDoc](img/index/index-06-redoc-02.png)
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Just Modern Python
@ -82,11 +83,11 @@ Here's how your editor might help you:
* in <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
![editor support](img/vscode-completion.png)
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
* in <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
![editor support](img/pycharm-completion.png)
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
You will get completion in code you might even consider impossible before. As for example, the `price` key inside a JSON body (that could have been nested) that comes from a request.

2
docs/help-fastapi.md → docs/en/docs/help-fastapi.md

@ -1,3 +1,5 @@
# Help FastAPI - Get Help
Do you like **FastAPI**?
Would you like to help FastAPI, other users, and the author?

2
docs/history-design-future.md → docs/en/docs/history-design-future.md

@ -1,3 +1,5 @@
# History, Design and Future
Some time ago, <a href="https://github.com/tiangolo/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">a **FastAPI** user asked</a>:
> What’s the history of this project? It seems to have come from nowhere to awesome in a few weeks [...]

0
docs/img/favicon.png → docs/en/docs/img/favicon.png

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

0
docs/img/github-social-preview.png → docs/en/docs/img/github-social-preview.png

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

0
docs/img/github-social-preview.svg → docs/en/docs/img/github-social-preview.svg

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

0
docs/img/icon-transparent-bg.png → docs/en/docs/img/icon-transparent-bg.png

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

0
docs/img/icon-white-bg.png → docs/en/docs/img/icon-white-bg.png

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

0
docs/img/icon-white.svg → docs/en/docs/img/icon-white.svg

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

0
docs/img/index/index-01-swagger-ui-simple.png → docs/en/docs/img/index/index-01-swagger-ui-simple.png

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

0
docs/img/index/index-02-redoc-simple.png → docs/en/docs/img/index/index-02-redoc-simple.png

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

0
docs/img/index/index-03-swagger-02.png → docs/en/docs/img/index/index-03-swagger-02.png

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

0
docs/img/index/index-04-swagger-03.png → docs/en/docs/img/index/index-04-swagger-03.png

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

0
docs/img/index/index-05-swagger-04.png → docs/en/docs/img/index/index-05-swagger-04.png

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

0
docs/img/index/index-06-redoc-02.png → docs/en/docs/img/index/index-06-redoc-02.png

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

0
docs/img/logo-margin/logo-teal-vector.svg → docs/en/docs/img/logo-margin/logo-teal-vector.svg

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

0
docs/img/logo-margin/logo-teal.png → docs/en/docs/img/logo-margin/logo-teal.png

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

0
docs/img/logo-margin/logo-teal.svg → docs/en/docs/img/logo-margin/logo-teal.svg

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
docs/img/logo-margin/logo-white-bg.png → docs/en/docs/img/logo-margin/logo-white-bg.png

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

0
docs/img/logo-teal-vector.svg → docs/en/docs/img/logo-teal-vector.svg

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

0
docs/img/logo-teal.svg → docs/en/docs/img/logo-teal.svg

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

0
docs/img/pycharm-completion.png → docs/en/docs/img/pycharm-completion.png

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

0
docs/img/python-types/image01.png → docs/en/docs/img/python-types/image01.png

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

0
docs/img/python-types/image02.png → docs/en/docs/img/python-types/image02.png

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

0
docs/img/python-types/image03.png → docs/en/docs/img/python-types/image03.png

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

0
docs/img/python-types/image04.png → docs/en/docs/img/python-types/image04.png

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

0
docs/img/python-types/image05.png → docs/en/docs/img/python-types/image05.png

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

0
docs/img/python-types/image06.png → docs/en/docs/img/python-types/image06.png

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

0
docs/img/tutorial/additional-responses/image01.png → docs/en/docs/img/tutorial/additional-responses/image01.png

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

0
docs/img/tutorial/application-configuration/image01.png → docs/en/docs/img/tutorial/application-configuration/image01.png

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

0
docs/img/tutorial/async-sql-databases/image01.png → docs/en/docs/img/tutorial/async-sql-databases/image01.png

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

0
docs/img/tutorial/bigger-applications/image01.png → docs/en/docs/img/tutorial/bigger-applications/image01.png

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

0
docs/img/tutorial/body-fields/image01.png → docs/en/docs/img/tutorial/body-fields/image01.png

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

0
docs/img/tutorial/body-nested-models/image01.png → docs/en/docs/img/tutorial/body-nested-models/image01.png

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

0
docs/img/tutorial/body/image01.png → docs/en/docs/img/tutorial/body/image01.png

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

0
docs/img/tutorial/body/image02.png → docs/en/docs/img/tutorial/body/image02.png

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

0
docs/img/tutorial/body/image03.png → docs/en/docs/img/tutorial/body/image03.png

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

0
docs/img/tutorial/body/image04.png → docs/en/docs/img/tutorial/body/image04.png

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

0
docs/img/tutorial/body/image05.png → docs/en/docs/img/tutorial/body/image05.png

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

0
docs/img/tutorial/custom-response/image01.png → docs/en/docs/img/tutorial/custom-response/image01.png

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

0
docs/img/tutorial/debugging/image01.png → docs/en/docs/img/tutorial/debugging/image01.png

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

0
docs/img/tutorial/dependencies/image01.png → docs/en/docs/img/tutorial/dependencies/image01.png

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

0
docs/img/tutorial/dependencies/image02.png → docs/en/docs/img/tutorial/dependencies/image02.png

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

0
docs/img/tutorial/extending-openapi/image01.png → docs/en/docs/img/tutorial/extending-openapi/image01.png

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

0
docs/img/tutorial/graphql/image01.png → docs/en/docs/img/tutorial/graphql/image01.png

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

0
docs/img/tutorial/openapi-callbacks/image01.png → docs/en/docs/img/tutorial/openapi-callbacks/image01.png

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

0
docs/img/tutorial/path-operation-configuration/image01.png → docs/en/docs/img/tutorial/path-operation-configuration/image01.png

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

0
docs/img/tutorial/path-operation-configuration/image02.png → docs/en/docs/img/tutorial/path-operation-configuration/image02.png

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

0
docs/img/tutorial/path-operation-configuration/image03.png → docs/en/docs/img/tutorial/path-operation-configuration/image03.png

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

0
docs/img/tutorial/path-operation-configuration/image04.png → docs/en/docs/img/tutorial/path-operation-configuration/image04.png

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

0
docs/img/tutorial/path-operation-configuration/image05.png → docs/en/docs/img/tutorial/path-operation-configuration/image05.png

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

0
docs/img/tutorial/path-params/image01.png → docs/en/docs/img/tutorial/path-params/image01.png

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 77 KiB

0
docs/img/tutorial/path-params/image02.png → docs/en/docs/img/tutorial/path-params/image02.png

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

0
docs/img/tutorial/path-params/image03.png → docs/en/docs/img/tutorial/path-params/image03.png

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

0
docs/img/tutorial/query-params-str-validations/image01.png → docs/en/docs/img/tutorial/query-params-str-validations/image01.png

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

0
docs/img/tutorial/query-params-str-validations/image02.png → docs/en/docs/img/tutorial/query-params-str-validations/image02.png

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

0
docs/img/tutorial/response-model/image01.png → docs/en/docs/img/tutorial/response-model/image01.png

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

0
docs/img/tutorial/response-model/image02.png → docs/en/docs/img/tutorial/response-model/image02.png

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

0
docs/img/tutorial/response-status-code/image01.png → docs/en/docs/img/tutorial/response-status-code/image01.png

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save