⛅ 🗳¶
⚠, 👆 5️⃣📆 💪 ⚙️ 🗳 💽 💖 Traefik ⚖️ 👌 ⏮️ 📳 👈 🚮 ➕ ➡ 🔡 👈 🚫 👀 👆 🈸.
👫 💼 👆 💪 ⚙️ root_path
🔗 👆 🈸.
root_path
🛠️ 🚚 🔫 🔧 (👈 FastAPI 🏗 🔛, 🔘 💃).
root_path
⚙️ 🍵 👫 🎯 💼.
& ⚫️ ⚙️ 🔘 🕐❔ 🗜 🎧-🈸.
🗳 ⏮️ 🎞 ➡ 🔡¶
✔️ 🗳 ⏮️ 🎞 ➡ 🔡, 👉 💼, ⛓ 👈 👆 💪 📣 ➡ /app
👆 📟, ✋️ ⤴️, 👆 🚮 🧽 🔛 🔝 (🗳) 👈 🔜 🚮 👆 FastAPI 🈸 🔽 ➡ 💖 /api/v1
.
👉 💼, ⏮️ ➡ /app
🔜 🤙 🍦 /api/v1/app
.
✋️ 🌐 👆 📟 ✍ 🤔 📤 /app
.
& 🗳 🔜 "❎" ➡ 🔡 🔛 ✈ ⏭ 📶 📨 Uvicorn, 🚧 👆 🈸 🤔 👈 ⚫️ 🍦 /app
, 👈 👆 🚫 ✔️ ℹ 🌐 👆 📟 🔌 🔡 /api/v1
.
🆙 📥, 🌐 🔜 👷 🛎.
✋️ ⤴️, 🕐❔ 👆 📂 🛠️ 🩺 🎚 (🕸), ⚫️ 🔜 ⌛ 🤚 🗄 🔗 /openapi.json
, ↩️ /api/v1/openapi.json
.
, 🕸 (👈 🏃 🖥) 🔜 🔄 🏆 /openapi.json
& 🚫🔜 💪 🤚 🗄 🔗.
↩️ 👥 ✔️ 🗳 ⏮️ ➡ 🔡 /api/v1
👆 📱, 🕸 💪 ☕ 🗄 🔗 /api/v1/openapi.json
.
graph LR
browser("Browser")
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
server["Server on http://127.0.0.1:8000/app"]
browser --> proxy
proxy --> server
Tip
📢 0.0.0.0
🛎 ⚙️ ⛓ 👈 📋 👂 🔛 🌐 📢 💪 👈 🎰/💽.
🩺 🎚 🔜 💪 🗄 🔗 📣 👈 👉 🛠️ server
🔎 /api/v1
(⛅ 🗳). 🖼:
{
"openapi": "3.0.2",
// More stuff here
"servers": [
{
"url": "/api/v1"
}
],
"paths": {
// More stuff here
}
}
👉 🖼, "🗳" 💪 🕳 💖 Traefik. & 💽 🔜 🕳 💖 Uvicorn, 🏃♂ 👆 FastAPI 🈸.
🚚 root_path
¶
🏆 👉, 👆 💪 ⚙️ 📋 ⏸ 🎛 --root-path
💖:
$ uvicorn main:app --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
🚥 👆 ⚙️ Hypercorn, ⚫️ ✔️ 🎛 --root-path
.
📡 ℹ
🔫 🔧 🔬 root_path
👉 ⚙️ 💼.
& --root-path
📋 ⏸ 🎛 🚚 👈 root_path
.
✅ ⏮️ root_path
¶
👆 💪 🤚 ⏮️ root_path
⚙️ 👆 🈸 🔠 📨, ⚫️ 🍕 scope
📖 (👈 🍕 🔫 🔌).
📥 👥 ✅ ⚫️ 📧 🎦 🎯.
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}
⤴️, 🚥 👆 ▶️ Uvicorn ⏮️:
$ uvicorn main:app --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
📨 🔜 🕳 💖:
{
"message": "Hello World",
"root_path": "/api/v1"
}
⚒ root_path
FastAPI 📱¶
👐, 🚥 👆 🚫 ✔️ 🌌 🚚 📋 ⏸ 🎛 💖 --root-path
⚖️ 🌓, 👆 💪 ⚒ root_path
🔢 🕐❔ 🏗 👆 FastAPI 📱:
from fastapi import FastAPI, Request
app = FastAPI(root_path="/api/v1")
@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}
🚶♀️ root_path
FastAPI
🔜 🌓 🚶♀️ --root-path
📋 ⏸ 🎛 Uvicorn ⚖️ Hypercorn.
🔃 root_path
¶
✔️ 🤯 👈 💽 (Uvicorn) 🏆 🚫 ⚙️ 👈 root_path
🕳 🙆 🌘 🚶♀️ ⚫️ 📱.
✋️ 🚥 👆 🚶 ⏮️ 👆 🖥 http://127.0.0.1:8000/app 👆 🔜 👀 😐 📨:
{
"message": "Hello World",
"root_path": "/api/v1"
}
, ⚫️ 🏆 🚫 ⌛ 🔐 http://127.0.0.1:8000/api/v1/app
.
Uvicorn 🔜 ⌛ 🗳 🔐 Uvicorn http://127.0.0.1:8000/app
, & ⤴️ ⚫️ 🔜 🗳 🎯 🚮 ➕ /api/v1
🔡 🔛 🔝.
🔃 🗳 ⏮️ 🎞 ➡ 🔡¶
✔️ 🤯 👈 🗳 ⏮️ 🎞 ➡ 🔡 🕴 1️⃣ 🌌 🔗 ⚫️.
🎲 📚 💼 🔢 🔜 👈 🗳 🚫 ✔️ 🏚 ➡ 🔡.
💼 💖 👈 (🍵 🎞 ➡ 🔡), 🗳 🔜 👂 🔛 🕳 💖 https://myawesomeapp.com
, & ⤴️ 🚥 🖥 🚶 https://myawesomeapp.com/api/v1/app
& 👆 💽 (✅ Uvicorn) 👂 🔛 http://127.0.0.1:8000
🗳 (🍵 🎞 ➡ 🔡) 🔜 🔐 Uvicorn 🎏 ➡: http://127.0.0.1:8000/api/v1/app
.
🔬 🌐 ⏮️ Traefik¶
👆 💪 💪 🏃 🥼 🌐 ⏮️ 🎞 ➡ 🔡 ⚙️ Traefik.
⏬ Traefik, ⚫️ 👁 💱, 👆 💪 ⚗ 🗜 📁 & 🏃 ⚫️ 🔗 ⚪️➡️ 📶.
⤴️ ✍ 📁 traefik.toml
⏮️:
[entryPoints]
[entryPoints.http]
address = ":9999"
[providers]
[providers.file]
filename = "routes.toml"
👉 💬 Traefik 👂 🔛 ⛴ 9️⃣9️⃣9️⃣9️⃣ & ⚙️ ➕1️⃣ 📁 routes.toml
.
Tip
👥 ⚙️ ⛴ 9️⃣9️⃣9️⃣9️⃣ ↩️ 🐩 🇺🇸🔍 ⛴ 8️⃣0️⃣ 👈 👆 🚫 ✔️ 🏃 ⚫️ ⏮️ 📡 (sudo
) 😌.
🔜 ✍ 👈 🎏 📁 routes.toml
:
[http]
[http.middlewares]
[http.middlewares.api-stripprefix.stripPrefix]
prefixes = ["/api/v1"]
[http.routers]
[http.routers.app-http]
entryPoints = ["http"]
service = "app"
rule = "PathPrefix(`/api/v1`)"
middlewares = ["api-stripprefix"]
[http.services]
[http.services.app]
[http.services.app.loadBalancer]
[[http.services.app.loadBalancer.servers]]
url = "http://127.0.0.1:8000"
👉 📁 🔗 Traefik ⚙️ ➡ 🔡 /api/v1
.
& ⤴️ ⚫️ 🔜 ❎ 🚮 📨 👆 Uvicorn 🏃♂ 🔛 http://127.0.0.1:8000
.
🔜 ▶️ Traefik:
$ ./traefik --configFile=traefik.toml
INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
& 🔜 ▶️ 👆 📱 ⏮️ Uvicorn, ⚙️ --root-path
🎛:
$ uvicorn main:app --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
✅ 📨¶
🔜, 🚥 👆 🚶 📛 ⏮️ ⛴ Uvicorn: http://127.0.0.1:8000/app, 👆 🔜 👀 😐 📨:
{
"message": "Hello World",
"root_path": "/api/v1"
}
Tip
👀 👈 ✋️ 👆 🔐 ⚫️ http://127.0.0.1:8000/app
⚫️ 🎦 root_path
/api/v1
, ✊ ⚪️➡️ 🎛 --root-path
.
& 🔜 📂 📛 ⏮️ ⛴ Traefik, ✅ ➡ 🔡: http://127.0.0.1:9999/api/v1/app.
👥 🤚 🎏 📨:
{
"message": "Hello World",
"root_path": "/api/v1"
}
✋️ 👉 🕰 📛 ⏮️ 🔡 ➡ 🚚 🗳: /api/v1
.
↗️, 💭 📥 👈 👱 🔜 🔐 📱 🔘 🗳, ⏬ ⏮️ ➡ 🔡 /app/v1
"☑" 1️⃣.
& ⏬ 🍵 ➡ 🔡 (http://127.0.0.1:8000/app
), 🚚 Uvicorn 🔗, 🔜 🎯 🗳 (Traefik) 🔐 ⚫️.
👈 🎦 ❔ 🗳 (Traefik) ⚙️ ➡ 🔡 & ❔ 💽 (Uvicorn) ⚙️ root_path
⚪️➡️ 🎛 --root-path
.
✅ 🩺 🎚¶
✋️ 📥 🎊 🍕. 👶
"🛂" 🌌 🔐 📱 🔜 🔘 🗳 ⏮️ ➡ 🔡 👈 👥 🔬. , 👥 🔜 ⌛, 🚥 👆 🔄 🩺 🎚 🍦 Uvicorn 🔗, 🍵 ➡ 🔡 📛, ⚫️ 🏆 🚫 👷, ↩️ ⚫️ ⌛ 🔐 🔘 🗳.
👆 💪 ✅ ⚫️ http://127.0.0.1:8000/docs:
✋️ 🚥 👥 🔐 🩺 🎚 "🛂" 📛 ⚙️ 🗳 ⏮️ ⛴ 9999
, /api/v1/docs
, ⚫️ 👷 ☑ ❗ 👶
👆 💪 ✅ ⚫️ http://127.0.0.1:9999/api/v1/docs:
▶️️ 👥 💚 ⚫️. 👶 👶
👉 ↩️ FastAPI ⚙️ 👉 root_path
✍ 🔢 server
🗄 ⏮️ 📛 🚚 root_path
.
🌖 💽¶
Warning
👉 🌅 🏧 ⚙️ 💼. 💭 🆓 🚶 ⚫️.
🔢, FastAPI 🔜 ✍ server
🗄 🔗 ⏮️ 📛 root_path
.
✋️ 👆 💪 🚚 🎏 🎛 servers
, 🖼 🚥 👆 💚 🎏 🩺 🎚 🔗 ⏮️ 🏗 & 🏭 🌐.
🚥 👆 🚶♀️ 🛃 📇 servers
& 📤 root_path
(↩️ 👆 🛠️ 👨❤👨 ⛅ 🗳), FastAPI 🔜 📩 "💽" ⏮️ 👉 root_path
▶️ 📇.
🖼:
from fastapi import FastAPI, Request
app = FastAPI(
servers=[
{"url": "https://stag.example.com", "description": "Staging environment"},
{"url": "https://prod.example.com", "description": "Production environment"},
],
root_path="/api/v1",
)
@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}
🔜 🏗 🗄 🔗 💖:
{
"openapi": "3.0.2",
// More stuff here
"servers": [
{
"url": "/api/v1"
},
{
"url": "https://stag.example.com",
"description": "Staging environment"
},
{
"url": "https://prod.example.com",
"description": "Production environment"
}
],
"paths": {
// More stuff here
}
}
Tip
👀 🚘-🏗 💽 ⏮️ url
💲 /api/v1
, ✊ ⚪️➡️ root_path
.
🩺 🎚 http://127.0.0.1:9999/api/v1/docs ⚫️ 🔜 👀 💖:
Tip
🩺 🎚 🔜 🔗 ⏮️ 💽 👈 👆 🖊.
❎ 🏧 💽 ⚪️➡️ root_path
¶
🚥 👆 🚫 💚 FastAPI 🔌 🏧 💽 ⚙️ root_path
, 👆 💪 ⚙️ 🔢 root_path_in_servers=False
:
from fastapi import FastAPI, Request
app = FastAPI(
servers=[
{"url": "https://stag.example.com", "description": "Staging environment"},
{"url": "https://prod.example.com", "description": "Production environment"},
],
root_path="/api/v1",
root_path_in_servers=False,
)
@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}
& ⤴️ ⚫️ 🏆 🚫 🔌 ⚫️ 🗄 🔗.
🗜 🎧-🈸¶
🚥 👆 💪 🗻 🎧-🈸 (🔬 🎧 🈸 - 🗻) ⏪ ⚙️ 🗳 ⏮️ root_path
, 👆 💪 ⚫️ 🛎, 👆 🔜 ⌛.
FastAPI 🔜 🔘 ⚙️ root_path
🎆, ⚫️ 🔜 👷. 👶