--Jinja2
für die Vorlagenfunktion erfordert die zusätzliche Installation von aiofiles
, um statische Dateien zu liefern
pyproject.toml
hinzugefügtpyproject.toml(Ergänzungen)
[tool.poetry.dependencies]
#Die folgenden zwei wurden hinzugefügt
jinja2 = "*"
aiofiles = "*"
Insgesamt zum Beispiel:
pyproject.toml
[tool.poetry]
name = "test_fastapi_app"
version = "0.1.0"
description = "just for test"
authors = ["Your Name <[email protected]>"]
[tool.poetry.dependencies]
python = "^3.8"
uvicorn = "*"
fastapi = "*"
jinja2 = "*"
aiofiles = "*"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
app
hinzuapp
)$ tree
.
├── app
│ ├── Dockerfile
│ ├── app
│ │ ├── __init__.py
│ │ ├── main.py
│ │ ├── routers
│ │ │ ├── __init__.py
│ │ │ └── subpage.py
│ │ ├── static
│ │ │ ├── layout.css
│ │ │ └── subpage
│ │ │ ├── test.css
│ │ │ └── test.js
│ │ └── templates
│ │ ├── layout.html
│ │ └── subpage
│ │ └── index.html
│ ├── poetry.lock
│ └── pyproject.toml
├── docker-compose.yml
└── web
Da die Dateien in app / app
geändert / hinzugefügt wurden, werden wir uns die Details unten ansehen.
main.py
main.py
"""
app main
"""
import pathlib
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import RedirectResponse
from .routers import subpage
# pathlib.Ermitteln Sie den absoluten Pfad eines statischen Verzeichnisses mithilfe von Pfad
PATH_STATIC = str(pathlib.Path(__file__).resolve().parent / "static")
def create_app():
"""
create app
-Es wird ein wenig kompliziert, also ist es funktionalisiert
"""
_app = FastAPI()
#Unter-App des Routermoduls`subpage`URL"/subpage/"Unten montieren
_app.include_router(
subpage.router,
prefix="/subpage",
tags=["subpage"],
responses={404: {"description": "not found"}},
)
# static
# URL`/static"Hängen Sie die statische Datei unten ein
_app.mount(
"/static",
StaticFiles(directory=PATH_STATIC, html=False),
name="static",
)
return _app
app = create_app()
@app.get('/')
async def redirect_subpage():
"""redirect webpage"""
return RedirectResponse( #Weiterleiten zu einer Webseite, die mit einer Unterseiten-Unter-App erstellt wurde
"/subpage",
)
Die Anzahl der Zeilen hat sich etwas erhöht, aber ich mache hauptsächlich
--Zusatz von "statisch"
--Sub-App: Subpage
einbinden und umleiten
routers/subpage.py
__Init __. Py
am selben Ort ist eine leere Dateirouters/subpage.py
"""
test subpage
"""
import pathlib
from fastapi import (
APIRouter,
Request,
)
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
#Rufen Sie den absoluten Pfad des Vorlagenverzeichnisses ab
PATH_TEMPLATES = str(
pathlib.Path(__file__).resolve() \
.parent.parent / "templates"
)
#Jinja2-Objekterzeugung
templates = Jinja2Templates(directory=PATH_TEMPLATES)
#Unter-App
router = APIRouter()
@router.get("/", response_class=HTMLResponse)
async def site_root(
request: Request,
):
"""test subpage"""
title = "test subpage"
return templates.TemplateResponse(
"subpage/index.html", # `templates`Relativer Pfad im Verzeichnis
context={ #Variablen können im Diktatformat übergeben werden
"request": request,
"title": title,
}
)
templates
Verzeichnislayout.html
layout.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta name="apple-mobile-web-app-capable" content="yes">
{% if title %}
<title>{{ title }}</title>
{% else %}
<title>Template</title>
{% endif %}
<!-- jQuery & Bootstrap4 -->
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous">
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<!-- jQuery UI -->
<script
src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
crossorigin="anonymous"></script>
<link
rel="stylesheet"
type="text/css"
href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.min.css">
<!-- CUSTOM STYLE -->
<link rel="stylesheet" type="text/css" href="{{url_for('static', path='/layout.css')}}">
{% block head %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
title
wird als Parameter empfangenlayout.css
aus einem statischen Verzeichnis unter Verwendung von Jinja2s url_for
zum Testensubpage/index.html
subpage/index.html
{% extends "layout.html" %}
{% block head %}
<link
rel="stylesheet"
type="text/css"
href="{{ url_for('static', path='/subpage/test.css') }}">
<script
type="text/javascript"
src="{{ url_for('static', path='subpage/test.js') }}"></script>
{% endblock %}
{% block content %}
<h2>Test Subpage</h2>
<br>
<h3>
Hello, World.
</h3>
{% endblock %}
erweitert``layout.html
und empfangen Sie die erforderlichen Parameter von der FastAPI-Seite.
--Laden von test.css
und test.js
aus dem statischen Verzeichnis zum Testenstatisches
Verzeichnis--Details werden weggelassen, da sie nur zum Testen dienen und praktisch kein Inhalt vorhanden ist. ――Wir werden später bestätigen, dass der Inhalt zur Laufzeit ordnungsgemäß gelesen werden kann.
Mach Folgendes
#Paket hinzugefügt, Quelle geändert / hinzugefügt, also neu erstellen
docker-compose build
#Dienststart
docker-compose up -d
Wenn Sie in einer lokalen Umgebung ausgeführt werden, sehen Sie sich http: // localhost an
Auf den ersten Blick scheint es zu funktionieren, aber wenn Sie genau hinschauen, können Sie die statische Datei nicht aus HTML lesen:
<link rel="stylesheet" type="text/css" href="http://backend/static/layout.css">
<link
rel="stylesheet"
type="text/css"
href="http://backend/static/subpage/test.css">
<script
type="text/javascript"
src="http://backend/static/subpage/test.js"></script>
src
und href
in diesem Fallhttp: // localhost / <url>
lautet, aber wie ↑,http: // backend / <url>
einbiegen in**url_for
für eine HTML-Datei zu verwendenDa es in diesem Bereich ein Proxy-Problem gibt, müssen die Startoption von "uvicorn" und die Einstellung von "nginx" geändert werden, um dieses Problem zu beheben.
4-1. uvicorn
Ändern Sie abschließend die "CMD" der Docker-Datei wie folgt, um die Startoption von "uvicorn" zu korrigieren
Dockerfile (Korrektur)
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--proxy-headers", "--forwarded-allow-ips", "*"]
4-2. Nginx
Ändern Sie als Nächstes die Nginx-Konfigurationsdatei (web / conf.d / app.conf
).
(Ein Beispiel für Nginx finden Sie unter uvicorns Bereitstellung.)
$ tree
.
├── app
├── docker-compose.yml
└── web
└── conf.d
└── app.conf
-Modifizieren Sie app.conf
in ↑ wie folgt
location /
hinzugefügt:conf:conf.d/app.conf
upstream backend {
server app:8000;
}
server {
listen 80;
# server_name localhost;
# index index.html index.htm;
location / {
#Die folgenden 5 Elemente wurden hinzugefügt
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://backend;
}
# log
# access_log /var/log/nginx/access.log;
# error_log /var/log/nginx/error.log;
}
# server_tokens off;
Wenn Sie dies bisher tun, wird die erwartete URL korrekt wie "http: // localhost /
--FastAPI + uvicorn + Nginx (Docker-Compose) -Konfiguration zum Erstellen einer Webfunktion mit der Atmosphäre von Flask --Flask ist einfacher zu verwenden, wenn Webfunktionen mit der Vorlagenfunktion usw. erstellt werden, und ich fand es einfacher, weil es viele Dokumente gibt. --FastAPI ist auf RestAPI-Funktionen spezialisiert und eignet sich möglicherweise nicht für Webfunktionen. Wenn Sie jedoch die asynchrone Verarbeitung beherrschen, besteht möglicherweise Leistungspotenzial.
Recommended Posts