Browse Source
* ✨ Add docs and tests for Jinja2 templates * 🎨 Fix format in test, remove unused importpull/187/head
committed by
GitHub
9 changed files with 156 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||
from fastapi import FastAPI |
|||
from starlette.staticfiles import StaticFiles |
|||
|
|||
app = FastAPI() |
|||
|
|||
app.mount("/static", StaticFiles(directory="static"), name="static") |
@ -0,0 +1,3 @@ |
|||
h1 { |
|||
color: green; |
|||
} |
@ -0,0 +1,9 @@ |
|||
<html> |
|||
<head> |
|||
<title>Item Details</title> |
|||
<link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet"> |
|||
</head> |
|||
<body> |
|||
<h1>Item ID: {{ id }}</h1> |
|||
</body> |
|||
</html> |
@ -0,0 +1,16 @@ |
|||
from fastapi import FastAPI |
|||
from starlette.requests import Request |
|||
from starlette.staticfiles import StaticFiles |
|||
from starlette.templating import Jinja2Templates |
|||
|
|||
app = FastAPI() |
|||
|
|||
app.mount("/static", StaticFiles(directory="static"), name="static") |
|||
|
|||
|
|||
templates = Jinja2Templates(directory="templates") |
|||
|
|||
|
|||
@app.get("/items/{id}") |
|||
async def read_item(request: Request, id: str): |
|||
return templates.TemplateResponse("item.html", {"request": request, "id": id}) |
@ -0,0 +1,34 @@ |
|||
You can serve static files automatically from a directory using <a href="https://www.starlette.io/staticfiles/" target="_blank">Starlette's Static Files</a>. |
|||
|
|||
## Install `aiofiles` |
|||
|
|||
First you need to install `aiofiles`: |
|||
|
|||
```bash |
|||
pip install aiofiles |
|||
``` |
|||
|
|||
## Use `StaticFiles` |
|||
|
|||
* Import `StaticFiles` from Starlette. |
|||
* "Mount" it the same way you would <a href="https://fastapi.tiangolo.com/tutorial/sub-applications-proxy/" target="_blank">mount a Sub-Application</a>. |
|||
|
|||
```Python hl_lines="2 6" |
|||
{!./src/static_files/tutorial001.py!} |
|||
``` |
|||
|
|||
Then you could have a directory `./static/` with some files that will be served directly. |
|||
|
|||
## Details |
|||
|
|||
The first `"/static"` refers to the sub-path this "sub-application" will be "mounted" on. So, any path that starts with `"/static"` will be handled by it. |
|||
|
|||
The `directory="static"` refers to the name of the directory that contains your static files. |
|||
|
|||
The `name="static"` gives it a name that can be used internally by **FastAPI**. |
|||
|
|||
All these parameters can be different than "`static`", adjust them with the needs and specific details of your own application. |
|||
|
|||
## More info |
|||
|
|||
For more details and options check <a href="https://www.starlette.io/staticfiles/" target="_blank">Starlette's docs about Static Files</a>. |
@ -0,0 +1,67 @@ |
|||
You can use any template engine you want with **FastAPI**. |
|||
|
|||
A common election is Jinja2, the same one used by Flask and other tools. |
|||
|
|||
Starlette has utilities to configure it easily that you can use directly in your **FastAPI** application. |
|||
|
|||
## Install dependencies |
|||
|
|||
Install `jinja2`: |
|||
|
|||
```bash |
|||
pip install jinja2 |
|||
``` |
|||
|
|||
If you need to also serve static files (as in this example), install `aiofiles`: |
|||
|
|||
```bash |
|||
pip install aiofiles |
|||
``` |
|||
|
|||
## Using `Jinja2Templates` |
|||
|
|||
* Import `Jinja2Templates` form Starlette. |
|||
* Create a `templates` object that you can re-use later. |
|||
* Declare a `Request` parameter in the *path operation* that will return a template. |
|||
* 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="4 11 15 16" |
|||
{!./src/templates/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! note |
|||
Notice that you have to pass the `request` as part of the key-value pairs in the context for Jinja2. So, you also have to declare it in your *path operation*. |
|||
|
|||
## Writing templates |
|||
|
|||
Then you can write a template at `templates/item.html` with: |
|||
|
|||
```jinja hl_lines="7" |
|||
{!./src/templates/templates/item.html!} |
|||
``` |
|||
|
|||
It will show the `id` taken from the "context" `dict` you passed: |
|||
|
|||
```Python |
|||
{"request": request, "id": id} |
|||
``` |
|||
|
|||
## Templates and static files |
|||
|
|||
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!} |
|||
``` |
|||
|
|||
In this example, it would link to a CSS file at `static/styles.css` with: |
|||
|
|||
```CSS hl_lines="4" |
|||
{!./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`. |
|||
|
|||
## More details |
|||
|
|||
For more details, including how to test templates, check <a href="https://www.starlette.io/templates/" target="_blank">Starlette's docs on templates</a>. |
@ -0,0 +1,19 @@ |
|||
import shutil |
|||
|
|||
from starlette.testclient import TestClient |
|||
|
|||
|
|||
def test_main(): |
|||
shutil.copytree("./docs/src/templates/templates/", "./templates") |
|||
shutil.copytree("./docs/src/templates/static/", "./static") |
|||
from templates.tutorial001 import app |
|||
|
|||
client = TestClient(app) |
|||
response = client.get("/items/foo") |
|||
assert response.status_code == 200 |
|||
assert b"<h1>Item ID: foo</h1>" in response.content |
|||
response = client.get("/static/styles.css") |
|||
assert response.status_code == 200 |
|||
assert b"color: green;" in response.content |
|||
shutil.rmtree("./templates") |
|||
shutil.rmtree("./static") |
Loading…
Reference in new issue