| from fastapi import FastAPI, File, Form, UploadFile |
| |
| app = FastAPI() |
| |
| |
| @app.post("/files/") |
| async def create_file( |
| file: bytes = File(...), fileb: UploadFile = File(...), token: str = Form(...) |
| ): |
| return { |
| "file_size": len(file), |
| "token": token, |
| "fileb_content_type": fileb.content_type, |
| } |
| import time |
| |
| from fastapi import FastAPI, Request |
| |
| app = FastAPI() |
| |
| |
| @app.middleware("http") |
| async def add_process_time_header(request: Request, call_next): |
| start_time = time.time() |
| response = await call_next(request) |
| process_time = time.time() - start_time |
| response.headers["X-Process-Time"] = str(process_time) |
| return response |
| from fastapi import FastAPI |
| from pydantic import BaseSettings |
| |
| |
| class Settings(BaseSettings): |
| app_name: str = "Awesome API" |
| admin_email: str |
| items_per_user: int = 50 |
| |
| |
| settings = Settings() |
| app = FastAPI() |
| |
| |
| @app.get("/info") |
| async def info(): |
| return { |
| "app_name": settings.app_name, |
| "admin_email": settings.admin_email, |
| "items_per_user": settings.items_per_user, |
| } |
| from pydantic import BaseSettings |
| |
| |
| class Settings(BaseSettings): |
| app_name: str = "Awesome API" |
| admin_email: str |
| items_per_user: int = 50 |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/settings/app02/main.py
| from functools import lru_cache |
| |
| from fastapi import Depends, FastAPI |
| |
| from . import config |
| |
| app = FastAPI() |
| |
| |
| @lru_cache() |
| def get_settings(): |
| return config.Settings() |
| |
| |
| @app.get("/info") |
| async def info(settings: config.Settings = Depends(get_settings)): |
| return { |
| "app_name": settings.app_name, |
| "admin_email": settings.admin_email, |
| "items_per_user": settings.items_per_user, |
| } |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/settings/app02/test_main.py
| from fastapi.testclient import TestClient |
| |
| from . import config, main |
| |
| client = TestClient(main.app) |
| |
| |
| def get_settings_override(): |
| return config.Settings(admin_email="testing_admin@example.com") |
| |
| |
| main.app.dependency_overrides[main.get_settings] = get_settings_override |
| |
| |
| def test_app(): |
| |
| response = client.get("/info") |
| data = response.json() |
| assert data == { |
| "app_name": "Awesome API", |
| "admin_email": "testing_admin@example.com", |
| "items_per_user": 50, |
| } |
| from pydantic import BaseSettings |
| |
| |
| class Settings(BaseSettings): |
| app_name: str = "Awesome API" |
| admin_email: str |
| items_per_user: int = 50 |
| |
| class Config: |
| env_file = ".env" |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/settings/app03/main.py
| from functools import lru_cache |
| |
| from fastapi import Depends, FastAPI |
| |
| from . import config |
| |
| app = FastAPI() |
| |
| |
| @lru_cache() |
| def get_settings(): |
| return config.Settings() |
| |
| |
| @app.get("/info") |
| async def info(settings: config.Settings = Depends(get_settings)): |
| return { |
| "app_name": settings.app_name, |
| "admin_email": settings.admin_email, |
| "items_per_user": settings.items_per_user, |
| } |
| from pydantic import BaseSettings |
| |
| |
| class Settings(BaseSettings): |
| app_name: str = "Awesome API" |
| admin_email: str |
| items_per_user: int = 50 |
| |
| |
| settings = Settings() |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/settings/app01/main.py
| from fastapi import FastAPI |
| |
| from . import config |
| |
| app = FastAPI() |
| |
| |
| @app.get("/info") |
| async def info(): |
| return { |
| "app_name": config.settings.app_name, |
| "admin_email": config.settings.admin_email, |
| "items_per_user": config.settings.items_per_user, |
| } |
| from fastapi import FastAPI |
| from pydantic import BaseSettings |
| |
| |
| class Settings(BaseSettings): |
| openapi_url: str = "/openapi.json" |
| |
| |
| settings = Settings() |
| |
| app = FastAPI(openapi_url=settings.openapi_url) |
| |
| |
| @app.get("/") |
| def root(): |
| return {"message": "Hello World"} |
| from typing import List |
| |
| from fastapi import FastAPI, File, UploadFile |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| |
| @app.post("/files/") |
| async def create_files(files: List[bytes] = File(...)): |
| return {"file_sizes": [len(file) for file in files]} |
| |
| |
| @app.post("/uploadfiles/") |
| async def create_upload_files(files: List[UploadFile] = File(...)): |
| return {"filenames": [file.filename for file in files]} |
| |
| |
| @app.get("/") |
| async def main(): |
| content = """ |
| <body> |
| <form action="/files/" enctype="multipart/form-data" method="post"> |
| <input name="files" type="file" multiple> |
| <input type="submit"> |
| </form> |
| <form action="/uploadfiles/" enctype="multipart/form-data" method="post"> |
| <input name="files" type="file" multiple> |
| <input type="submit"> |
| </form> |
| </body> |
| """ |
| return HTMLResponse(content=content) |
| from fastapi import FastAPI, File, UploadFile |
| |
| app = FastAPI() |
| |
| |
| @app.post("/files/") |
| async def create_file(file: bytes = File(...)): |
| return {"file_size": len(file)} |
| |
| |
| @app.post("/uploadfile/") |
| async def create_upload_file(file: UploadFile = File(...)): |
| return {"filename": file.filename} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_multiple_params/tutorial002.py
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| class User(BaseModel): |
| username: str |
| full_name: Optional[str] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item, user: User): |
| results = {"item_id": item_id, "item": item, "user": user} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_multiple_params/tutorial003.py
| from typing import Optional |
| |
| from fastapi import Body, FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| class User(BaseModel): |
| username: str |
| full_name: Optional[str] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item( |
| item_id: int, item: Item, user: User, importance: int = Body(...) |
| ): |
| results = {"item_id": item_id, "item": item, "user": user, "importance": importance} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_multiple_params/tutorial004.py
| from typing import Optional |
| |
| from fastapi import Body, FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| class User(BaseModel): |
| username: str |
| full_name: Optional[str] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item( |
| *, |
| item_id: int, |
| item: Item, |
| user: User, |
| importance: int = Body(..., gt=0), |
| q: Optional[str] = None |
| ): |
| results = {"item_id": item_id, "item": item, "user": user, "importance": importance} |
| if q: |
| results.update({"q": q}) |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_multiple_params/tutorial005.py
| from typing import Optional |
| |
| from fastapi import Body, FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item = Body(..., embed=True)): |
| results = {"item_id": item_id, "item": item} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_multiple_params/tutorial001.py
| from typing import Optional |
| |
| from fastapi import FastAPI, Path |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item( |
| *, |
| item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000), |
| q: Optional[str] = None, |
| item: Optional[Item] = None, |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| if item: |
| results.update({"item": item}) |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial006.py
| from typing import List, Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, HttpUrl |
| |
| app = FastAPI() |
| |
| |
| class Image(BaseModel): |
| url: HttpUrl |
| name: str |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = set() |
| images: Optional[List[Image]] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial002.py
| from typing import List, Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: List[str] = [] |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial003.py
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = set() |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial007.py
| from typing import List, Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, HttpUrl |
| |
| app = FastAPI() |
| |
| |
| class Image(BaseModel): |
| url: HttpUrl |
| name: str |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = set() |
| images: Optional[List[Image]] = None |
| |
| |
| class Offer(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| items: List[Item] |
| |
| |
| @app.post("/offers/") |
| async def create_offer(offer: Offer): |
| return offer |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial008.py
| from typing import List |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, HttpUrl |
| |
| app = FastAPI() |
| |
| |
| class Image(BaseModel): |
| url: HttpUrl |
| name: str |
| |
| |
| @app.post("/images/multiple/") |
| async def create_multiple_images(images: List[Image]): |
| return images |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial009.py
| from typing import Dict |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.post("/index-weights/") |
| async def create_index_weights(weights: Dict[int, float]): |
| return weights |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial004.py
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Image(BaseModel): |
| url: str |
| name: str |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| image: Optional[Image] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial005.py
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, HttpUrl |
| |
| app = FastAPI() |
| |
| |
| class Image(BaseModel): |
| url: HttpUrl |
| name: str |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = set() |
| image: Optional[Image] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_nested_models/tutorial001.py
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: list = [] |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
| from typing import Optional |
| |
| from fastapi import APIRouter, FastAPI |
| from pydantic import BaseModel, HttpUrl |
| |
| app = FastAPI() |
| |
| |
| class Invoice(BaseModel): |
| id: str |
| title: Optional[str] = None |
| customer: str |
| total: float |
| |
| |
| class InvoiceEvent(BaseModel): |
| description: str |
| paid: bool |
| |
| |
| class InvoiceEventReceived(BaseModel): |
| ok: bool |
| |
| |
| invoices_callback_router = APIRouter() |
| |
| |
| @invoices_callback_router.post( |
| "{$callback_url}/invoices/{$request.body.id}", response_model=InvoiceEventReceived |
| ) |
| def invoice_notification(body: InvoiceEvent): |
| pass |
| |
| |
| @app.post("/invoices/", callbacks=invoices_callback_router.routes) |
| def create_invoice(invoice: Invoice, callback_url: Optional[HttpUrl] = None): |
| """ |
| Create an invoice. |
| |
| This will (let's imagine) let the API user (some external developer) create an |
| invoice. |
| |
| And this path operation will: |
| |
| * Send the invoice to the client. |
| * Collect the money from the client. |
| * Send a notification back to the API user (the external developer), as a callback. |
| * At this point is that the API will somehow send a POST request to the |
| external API with the notification of the invoice event |
| (e.g. "payment successful"). |
| """ |
| |
| return {"msg": "Invoice received"} |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: float = 10.5 |
| |
| |
| items = { |
| "foo": {"name": "Foo", "price": 50.2}, |
| "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2}, |
| "baz": { |
| "name": "Baz", |
| "description": "There goes my baz", |
| "price": 50.2, |
| "tax": 10.5, |
| }, |
| } |
| |
| |
| @app.get( |
| "/items/{item_id}/name", |
| response_model=Item, |
| response_model_include=["name", "description"], |
| ) |
| async def read_item_name(item_id: str): |
| return items[item_id] |
| |
| |
| @app.get("/items/{item_id}/public", response_model=Item, response_model_exclude=["tax"]) |
| async def read_item_public_data(item_id: str): |
| return items[item_id] |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, EmailStr |
| |
| app = FastAPI() |
| |
| |
| class UserIn(BaseModel): |
| username: str |
| password: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| |
| @app.post("/user/", response_model=UserIn) |
| async def create_user(user: UserIn): |
| return user |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, EmailStr |
| |
| app = FastAPI() |
| |
| |
| class UserIn(BaseModel): |
| username: str |
| password: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| class UserOut(BaseModel): |
| username: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| @app.post("/user/", response_model=UserOut) |
| async def create_user(user: UserIn): |
| return user |
| from typing import List, Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: float = 10.5 |
| tags: List[str] = [] |
| |
| |
| items = { |
| "foo": {"name": "Foo", "price": 50.2}, |
| "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, |
| "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, |
| } |
| |
| |
| @app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True) |
| async def read_item(item_id: str): |
| return items[item_id] |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: float = 10.5 |
| |
| |
| items = { |
| "foo": {"name": "Foo", "price": 50.2}, |
| "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2}, |
| "baz": { |
| "name": "Baz", |
| "description": "There goes my baz", |
| "price": 50.2, |
| "tax": 10.5, |
| }, |
| } |
| |
| |
| @app.get( |
| "/items/{item_id}/name", |
| response_model=Item, |
| response_model_include={"name", "description"}, |
| ) |
| async def read_item_name(item_id: str): |
| return items[item_id] |
| |
| |
| @app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"}) |
| async def read_item_public_data(item_id: str): |
| return items[item_id] |
| from typing import List, Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: List[str] = [] |
| |
| |
| @app.post("/items/", response_model=Item) |
| async def create_item(item: Item): |
| return item |
| from fastapi import FastAPI, status |
| |
| app = FastAPI() |
| |
| |
| @app.post("/items/", status_code=status.HTTP_201_CREATED) |
| async def create_item(name: str): |
| return {"name": name} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.post("/items/", status_code=201) |
| async def create_item(name: str): |
| return {"name": name} |
| from typing import List |
| |
| |
| def process_items(items: List[str]): |
| for item in items: |
| print(item) |
| def get_full_name(first_name: str, last_name: str): |
| full_name = first_name.title() + " " + last_name.title() |
| return full_name |
| |
| |
| print(get_full_name("john", "doe")) |
| def get_name_with_age(name: str, age: int): |
| name_with_age = name + " is this old: " + age |
| return name_with_age |
| from typing import Set, Tuple |
| |
| |
| def process_items(items_t: Tuple[int, int, str], items_s: Set[bytes]): |
| return items_t, items_s |
| from typing import Dict |
| |
| |
| def process_items(prices: Dict[str, float]): |
| for item_name, item_price in prices.items(): |
| print(item_name) |
| print(item_price) |
| from typing import Optional |
| |
| |
| def say_hi(name: Optional[str] = None): |
| if name is not None: |
| print(f"Hey {name}!") |
| else: |
| print("Hello World") |
| class Person: |
| def __init__(self, name: str): |
| self.name = name |
| |
| |
| def get_person_name(one_person: Person): |
| return one_person.name |
| def get_name_with_age(name: str, age: int): |
| name_with_age = name + " is this old: " + str(age) |
| return name_with_age |
| def get_items(item_a: str, item_b: int, item_c: float, item_d: bool, item_e: bytes): |
| return item_a, item_b, item_c, item_d, item_d, item_e |
| def get_full_name(first_name, last_name): |
| full_name = first_name.title() + " " + last_name.title() |
| return full_name |
| |
| |
| print(get_full_name("john", "doe")) |
| from datetime import datetime |
| from typing import List, Optional |
| |
| from pydantic import BaseModel |
| |
| |
| class User(BaseModel): |
| id: int |
| name = "John Doe" |
| signup_ts: Optional[datetime] = None |
| friends: List[int] = [] |
| |
| |
| external_data = { |
| "id": "123", |
| "signup_ts": "2017-06-01 12:22", |
| "friends": [1, "2", b"3"], |
| } |
| user = User(**external_data) |
| print(user) |
| |
| print(user.id) |
| |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI |
| from fastapi.testclient import TestClient |
| |
| app = FastAPI() |
| |
| |
| async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100): |
| return {"q": q, "skip": skip, "limit": limit} |
| |
| |
| @app.get("/items/") |
| async def read_items(commons: dict = Depends(common_parameters)): |
| return {"message": "Hello Items!", "params": commons} |
| |
| |
| @app.get("/users/") |
| async def read_users(commons: dict = Depends(common_parameters)): |
| return {"message": "Hello Users!", "params": commons} |
| |
| |
| client = TestClient(app) |
| |
| |
| async def override_dependency(q: Optional[str] = None): |
| return {"q": q, "skip": 5, "limit": 10} |
| |
| |
| app.dependency_overrides[common_parameters] = override_dependency |
| |
| |
| def test_override_in_items(): |
| response = client.get("/items/") |
| assert response.status_code == 200 |
| assert response.json() == { |
| "message": "Hello Items!", |
| "params": {"q": None, "skip": 5, "limit": 10}, |
| } |
| |
| |
| def test_override_in_items_with_q(): |
| response = client.get("/items/?q=foo") |
| assert response.status_code == 200 |
| assert response.json() == { |
| "message": "Hello Items!", |
| "params": {"q": "foo", "skip": 5, "limit": 10}, |
| } |
| |
| |
| def test_override_in_items_with_params(): |
| response = client.get("/items/?q=foo&skip=100&limit=200") |
| assert response.status_code == 200 |
| assert response.json() == { |
| "message": "Hello Items!", |
| "params": {"q": "foo", "skip": 5, "limit": 10}, |
| } |
| from fastapi import Depends, FastAPI |
| from fastapi.security import HTTPBasic, HTTPBasicCredentials |
| |
| app = FastAPI() |
| |
| security = HTTPBasic() |
| |
| |
| @app.get("/users/me") |
| def read_current_user(credentials: HTTPBasicCredentials = Depends(security)): |
| return {"username": credentials.username, "password": credentials.password} |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI |
| from fastapi.security import OAuth2PasswordBearer |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") |
| |
| |
| class User(BaseModel): |
| username: str |
| email: Optional[str] = None |
| full_name: Optional[str] = None |
| disabled: Optional[bool] = None |
| |
| |
| def fake_decode_token(token): |
| return User( |
| username=token + "fakedecoded", email="john@example.com", full_name="John Doe" |
| ) |
| |
| |
| async def get_current_user(token: str = Depends(oauth2_scheme)): |
| user = fake_decode_token(token) |
| return user |
| |
| |
| @app.get("/users/me") |
| async def read_users_me(current_user: User = Depends(get_current_user)): |
| return current_user |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI, HTTPException, status |
| from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm |
| from pydantic import BaseModel |
| |
| fake_users_db = { |
| "johndoe": { |
| "username": "johndoe", |
| "full_name": "John Doe", |
| "email": "johndoe@example.com", |
| "hashed_password": "fakehashedsecret", |
| "disabled": False, |
| }, |
| "alice": { |
| "username": "alice", |
| "full_name": "Alice Wonderson", |
| "email": "alice@example.com", |
| "hashed_password": "fakehashedsecret2", |
| "disabled": True, |
| }, |
| } |
| |
| app = FastAPI() |
| |
| |
| def fake_hash_password(password: str): |
| return "fakehashed" + password |
| |
| |
| oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") |
| |
| |
| class User(BaseModel): |
| username: str |
| email: Optional[str] = None |
| full_name: Optional[str] = None |
| disabled: Optional[bool] = None |
| |
| |
| class UserInDB(User): |
| hashed_password: str |
| |
| |
| def get_user(db, username: str): |
| if username in db: |
| user_dict = db[username] |
| return UserInDB(**user_dict) |
| |
| |
| def fake_decode_token(token): |
| |
| |
| user = get_user(fake_users_db, token) |
| return user |
| |
| |
| async def get_current_user(token: str = Depends(oauth2_scheme)): |
| user = fake_decode_token(token) |
| if not user: |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Invalid authentication credentials", |
| headers={"WWW-Authenticate": "Bearer"}, |
| ) |
| return user |
| |
| |
| async def get_current_active_user(current_user: User = Depends(get_current_user)): |
| if current_user.disabled: |
| raise HTTPException(status_code=400, detail="Inactive user") |
| return current_user |
| |
| |
| @app.post("/token") |
| async def login(form_data: OAuth2PasswordRequestForm = Depends()): |
| user_dict = fake_users_db.get(form_data.username) |
| if not user_dict: |
| raise HTTPException(status_code=400, detail="Incorrect username or password") |
| user = UserInDB(**user_dict) |
| hashed_password = fake_hash_password(form_data.password) |
| if not hashed_password == user.hashed_password: |
| raise HTTPException(status_code=400, detail="Incorrect username or password") |
| |
| return {"access_token": user.username, "token_type": "bearer"} |
| |
| |
| @app.get("/users/me") |
| async def read_users_me(current_user: User = Depends(get_current_active_user)): |
| return current_user |
| import secrets |
| |
| from fastapi import Depends, FastAPI, HTTPException, status |
| from fastapi.security import HTTPBasic, HTTPBasicCredentials |
| |
| app = FastAPI() |
| |
| security = HTTPBasic() |
| |
| |
| def get_current_username(credentials: HTTPBasicCredentials = Depends(security)): |
| correct_username = secrets.compare_digest(credentials.username, "stanleyjobson") |
| correct_password = secrets.compare_digest(credentials.password, "swordfish") |
| if not (correct_username and correct_password): |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Incorrect email or password", |
| headers={"WWW-Authenticate": "Basic"}, |
| ) |
| return credentials.username |
| |
| |
| @app.get("/users/me") |
| def read_current_user(username: str = Depends(get_current_username)): |
| return {"username": username} |
| from datetime import datetime, timedelta |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI, HTTPException, status |
| from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm |
| from jose import JWTError, jwt |
| from passlib.context import CryptContext |
| from pydantic import BaseModel |
| |
| |
| |
| SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" |
| ALGORITHM = "HS256" |
| ACCESS_TOKEN_EXPIRE_MINUTES = 30 |
| |
| |
| fake_users_db = { |
| "johndoe": { |
| "username": "johndoe", |
| "full_name": "John Doe", |
| "email": "johndoe@example.com", |
| "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", |
| "disabled": False, |
| } |
| } |
| |
| |
| class Token(BaseModel): |
| access_token: str |
| token_type: str |
| |
| |
| class TokenData(BaseModel): |
| username: Optional[str] = None |
| |
| |
| class User(BaseModel): |
| username: str |
| email: Optional[str] = None |
| full_name: Optional[str] = None |
| disabled: Optional[bool] = None |
| |
| |
| class UserInDB(User): |
| hashed_password: str |
| |
| |
| pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
| |
| oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") |
| |
| app = FastAPI() |
| |
| |
| def verify_password(plain_password, hashed_password): |
| return pwd_context.verify(plain_password, hashed_password) |
| |
| |
| def get_password_hash(password): |
| return pwd_context.hash(password) |
| |
| |
| def get_user(db, username: str): |
| if username in db: |
| user_dict = db[username] |
| return UserInDB(**user_dict) |
| |
| |
| def authenticate_user(fake_db, username: str, password: str): |
| user = get_user(fake_db, username) |
| if not user: |
| return False |
| if not verify_password(password, user.hashed_password): |
| return False |
| return user |
| |
| |
| def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): |
| to_encode = data.copy() |
| if expires_delta: |
| expire = datetime.utcnow() + expires_delta |
| else: |
| expire = datetime.utcnow() + timedelta(minutes=15) |
| to_encode.update({"exp": expire}) |
| encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) |
| return encoded_jwt |
| |
| |
| async def get_current_user(token: str = Depends(oauth2_scheme)): |
| credentials_exception = HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Could not validate credentials", |
| headers={"WWW-Authenticate": "Bearer"}, |
| ) |
| try: |
| payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) |
| username: str = payload.get("sub") |
| if username is None: |
| raise credentials_exception |
| token_data = TokenData(username=username) |
| except JWTError: |
| raise credentials_exception |
| user = get_user(fake_users_db, username=token_data.username) |
| if user is None: |
| raise credentials_exception |
| return user |
| |
| |
| async def get_current_active_user(current_user: User = Depends(get_current_user)): |
| if current_user.disabled: |
| raise HTTPException(status_code=400, detail="Inactive user") |
| return current_user |
| |
| |
| @app.post("/token", response_model=Token) |
| async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): |
| user = authenticate_user(fake_users_db, form_data.username, form_data.password) |
| if not user: |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Incorrect username or password", |
| headers={"WWW-Authenticate": "Bearer"}, |
| ) |
| access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) |
| access_token = create_access_token( |
| data={"sub": user.username}, expires_delta=access_token_expires |
| ) |
| return {"access_token": access_token, "token_type": "bearer"} |
| |
| |
| @app.get("/users/me/", response_model=User) |
| async def read_users_me(current_user: User = Depends(get_current_active_user)): |
| return current_user |
| |
| |
| @app.get("/users/me/items/") |
| async def read_own_items(current_user: User = Depends(get_current_active_user)): |
| return [{"item_id": "Foo", "owner": current_user.username}] |
| from datetime import datetime, timedelta |
| from typing import List, Optional |
| |
| from fastapi import Depends, FastAPI, HTTPException, Security, status |
| from fastapi.security import ( |
| OAuth2PasswordBearer, |
| OAuth2PasswordRequestForm, |
| SecurityScopes, |
| ) |
| from jose import JWTError, jwt |
| from passlib.context import CryptContext |
| from pydantic import BaseModel, ValidationError |
| |
| |
| |
| SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" |
| ALGORITHM = "HS256" |
| ACCESS_TOKEN_EXPIRE_MINUTES = 30 |
| |
| |
| fake_users_db = { |
| "johndoe": { |
| "username": "johndoe", |
| "full_name": "John Doe", |
| "email": "johndoe@example.com", |
| "hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW", |
| "disabled": False, |
| }, |
| "alice": { |
| "username": "alice", |
| "full_name": "Alice Chains", |
| "email": "alicechains@example.com", |
| "hashed_password": "$2b$12$gSvqqUPvlXP2tfVFaWK1Be7DlH.PKZbv5H8KnzzVgXXbVxpva.pFm", |
| "disabled": True, |
| }, |
| } |
| |
| |
| class Token(BaseModel): |
| access_token: str |
| token_type: str |
| |
| |
| class TokenData(BaseModel): |
| username: Optional[str] = None |
| scopes: List[str] = [] |
| |
| |
| class User(BaseModel): |
| username: str |
| email: Optional[str] = None |
| full_name: Optional[str] = None |
| disabled: Optional[bool] = None |
| |
| |
| class UserInDB(User): |
| hashed_password: str |
| |
| |
| pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
| |
| oauth2_scheme = OAuth2PasswordBearer( |
| tokenUrl="token", |
| scopes={"me": "Read information about the current user.", "items": "Read items."}, |
| ) |
| |
| app = FastAPI() |
| |
| |
| def verify_password(plain_password, hashed_password): |
| return pwd_context.verify(plain_password, hashed_password) |
| |
| |
| def get_password_hash(password): |
| return pwd_context.hash(password) |
| |
| |
| def get_user(db, username: str): |
| if username in db: |
| user_dict = db[username] |
| return UserInDB(**user_dict) |
| |
| |
| def authenticate_user(fake_db, username: str, password: str): |
| user = get_user(fake_db, username) |
| if not user: |
| return False |
| if not verify_password(password, user.hashed_password): |
| return False |
| return user |
| |
| |
| def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): |
| to_encode = data.copy() |
| if expires_delta: |
| expire = datetime.utcnow() + expires_delta |
| else: |
| expire = datetime.utcnow() + timedelta(minutes=15) |
| to_encode.update({"exp": expire}) |
| encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) |
| return encoded_jwt |
| |
| |
| async def get_current_user( |
| security_scopes: SecurityScopes, token: str = Depends(oauth2_scheme) |
| ): |
| if security_scopes.scopes: |
| authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' |
| else: |
| authenticate_value = f"Bearer" |
| credentials_exception = HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Could not validate credentials", |
| headers={"WWW-Authenticate": authenticate_value}, |
| ) |
| try: |
| payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) |
| username: str = payload.get("sub") |
| if username is None: |
| raise credentials_exception |
| token_scopes = payload.get("scopes", []) |
| token_data = TokenData(scopes=token_scopes, username=username) |
| except (JWTError, ValidationError): |
| raise credentials_exception |
| user = get_user(fake_users_db, username=token_data.username) |
| if user is None: |
| raise credentials_exception |
| for scope in security_scopes.scopes: |
| if scope not in token_data.scopes: |
| raise HTTPException( |
| status_code=status.HTTP_401_UNAUTHORIZED, |
| detail="Not enough permissions", |
| headers={"WWW-Authenticate": authenticate_value}, |
| ) |
| return user |
| |
| |
| async def get_current_active_user( |
| current_user: User = Security(get_current_user, scopes=["me"]) |
| ): |
| if current_user.disabled: |
| raise HTTPException(status_code=400, detail="Inactive user") |
| return current_user |
| |
| |
| @app.post("/token", response_model=Token) |
| async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): |
| user = authenticate_user(fake_users_db, form_data.username, form_data.password) |
| if not user: |
| raise HTTPException(status_code=400, detail="Incorrect username or password") |
| access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) |
| access_token = create_access_token( |
| data={"sub": user.username, "scopes": form_data.scopes}, |
| expires_delta=access_token_expires, |
| ) |
| return {"access_token": access_token, "token_type": "bearer"} |
| |
| |
| @app.get("/users/me/", response_model=User) |
| async def read_users_me(current_user: User = Depends(get_current_active_user)): |
| return current_user |
| |
| |
| @app.get("/users/me/items/") |
| async def read_own_items( |
| current_user: User = Security(get_current_active_user, scopes=["items"]) |
| ): |
| return [{"item_id": "Foo", "owner": current_user.username}] |
| |
| |
| @app.get("/status/") |
| async def read_system_status(current_user: User = Depends(get_current_user)): |
| return {"status": "ok"} |
| from fastapi import Depends, FastAPI |
| from fastapi.security import OAuth2PasswordBearer |
| |
| app = FastAPI() |
| |
| oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") |
| |
| |
| @app.get("/items/") |
| async def read_items(token: str = Depends(oauth2_scheme)): |
| return {"token": token} |
| from typing import Optional |
| |
| from fastapi import FastAPI, Header |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items( |
| strange_header: Optional[str] = Header(None, convert_underscores=False) |
| ): |
| return {"strange_header": strange_header} |
| from typing import List, Optional |
| |
| from fastapi import FastAPI, Header |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(x_token: Optional[List[str]] = Header(None)): |
| return {"X-Token values": x_token} |
| from typing import Optional |
| |
| from fastapi import FastAPI, Header |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(user_agent: Optional[str] = Header(None)): |
| return {"User-Agent": user_agent} |
| from typing import Optional |
| |
| from fastapi import BackgroundTasks, Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| def write_log(message: str): |
| with open("log.txt", mode="a") as log: |
| log.write(message) |
| |
| |
| def get_query(background_tasks: BackgroundTasks, q: Optional[str] = None): |
| if q: |
| message = f"found query: {q}\n" |
| background_tasks.add_task(write_log, message) |
| return q |
| |
| |
| @app.post("/send-notification/{email}") |
| async def send_notification( |
| email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query) |
| ): |
| message = f"message to {email}\n" |
| background_tasks.add_task(write_log, message) |
| return {"message": "Message sent"} |
| from fastapi import BackgroundTasks, FastAPI |
| |
| app = FastAPI() |
| |
| |
| def write_notification(email: str, message=""): |
| with open("log.txt", mode="w") as email_file: |
| content = f"notification for {email}: {message}" |
| email_file.write(content) |
| |
| |
| @app.post("/send-notification/{email}") |
| async def send_notification(email: str, background_tasks: BackgroundTasks): |
| background_tasks.add_task(write_notification, email, message="some notification") |
| return {"message": "Notification sent in the background"} |
| from sqlalchemy import Boolean, Column, ForeignKey, Integer, String |
| from sqlalchemy.orm import relationship |
| |
| from .database import Base |
| |
| |
| class User(Base): |
| __tablename__ = "users" |
| |
| id = Column(Integer, primary_key=True, index=True) |
| email = Column(String, unique=True, index=True) |
| hashed_password = Column(String) |
| is_active = Column(Boolean, default=True) |
| |
| items = relationship("Item", back_populates="owner") |
| |
| |
| class Item(Base): |
| __tablename__ = "items" |
| |
| id = Column(Integer, primary_key=True, index=True) |
| title = Column(String, index=True) |
| description = Column(String, index=True) |
| owner_id = Column(Integer, ForeignKey("users.id")) |
| |
| owner = relationship("User", back_populates="items") |
| from sqlalchemy import create_engine |
| from sqlalchemy.ext.declarative import declarative_base |
| from sqlalchemy.orm import sessionmaker |
| |
| SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db" |
| |
| |
| engine = create_engine( |
| SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False} |
| ) |
| SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) |
| |
| Base = declarative_base() |
| from typing import List, Optional |
| |
| from pydantic import BaseModel |
| |
| |
| class ItemBase(BaseModel): |
| title: str |
| description: Optional[str] = None |
| |
| |
| class ItemCreate(ItemBase): |
| pass |
| |
| |
| class Item(ItemBase): |
| id: int |
| owner_id: int |
| |
| class Config: |
| orm_mode = True |
| |
| |
| class UserBase(BaseModel): |
| email: str |
| |
| |
| class UserCreate(UserBase): |
| password: str |
| |
| |
| class User(UserBase): |
| id: int |
| is_active: bool |
| items: List[Item] = [] |
| |
| class Config: |
| orm_mode = True |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/sql_databases/sql_app/main.py
| from typing import List |
| |
| from fastapi import Depends, FastAPI, HTTPException |
| from sqlalchemy.orm import Session |
| |
| from . import crud, models, schemas |
| from .database import SessionLocal, engine |
| |
| models.Base.metadata.create_all(bind=engine) |
| |
| app = FastAPI() |
| |
| |
| |
| def get_db(): |
| db = SessionLocal() |
| try: |
| yield db |
| finally: |
| db.close() |
| |
| |
| @app.post("/users/", response_model=schemas.User) |
| def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): |
| db_user = crud.get_user_by_email(db, email=user.email) |
| if db_user: |
| raise HTTPException(status_code=400, detail="Email already registered") |
| return crud.create_user(db=db, user=user) |
| |
| |
| @app.get("/users/", response_model=List[schemas.User]) |
| def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): |
| users = crud.get_users(db, skip=skip, limit=limit) |
| return users |
| |
| |
| @app.get("/users/{user_id}", response_model=schemas.User) |
| def read_user(user_id: int, db: Session = Depends(get_db)): |
| db_user = crud.get_user(db, user_id=user_id) |
| if db_user is None: |
| raise HTTPException(status_code=404, detail="User not found") |
| return db_user |
| |
| |
| @app.post("/users/{user_id}/items/", response_model=schemas.Item) |
| def create_item_for_user( |
| user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db) |
| ): |
| return crud.create_user_item(db=db, item=item, user_id=user_id) |
| |
| |
| @app.get("/items/", response_model=List[schemas.Item]) |
| def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): |
| items = crud.get_items(db, skip=skip, limit=limit) |
| return items |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/sql_databases/sql_app/alt_main.py
| from typing import List |
| |
| from fastapi import Depends, FastAPI, HTTPException, Request, Response |
| from sqlalchemy.orm import Session |
| |
| from . import crud, models, schemas |
| from .database import SessionLocal, engine |
| |
| models.Base.metadata.create_all(bind=engine) |
| |
| app = FastAPI() |
| |
| |
| @app.middleware("http") |
| async def db_session_middleware(request: Request, call_next): |
| response = Response("Internal server error", status_code=500) |
| try: |
| request.state.db = SessionLocal() |
| response = await call_next(request) |
| finally: |
| request.state.db.close() |
| return response |
| |
| |
| |
| def get_db(request: Request): |
| return request.state.db |
| |
| |
| @app.post("/users/", response_model=schemas.User) |
| def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): |
| db_user = crud.get_user_by_email(db, email=user.email) |
| if db_user: |
| raise HTTPException(status_code=400, detail="Email already registered") |
| return crud.create_user(db=db, user=user) |
| |
| |
| @app.get("/users/", response_model=List[schemas.User]) |
| def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): |
| users = crud.get_users(db, skip=skip, limit=limit) |
| return users |
| |
| |
| @app.get("/users/{user_id}", response_model=schemas.User) |
| def read_user(user_id: int, db: Session = Depends(get_db)): |
| db_user = crud.get_user(db, user_id=user_id) |
| if db_user is None: |
| raise HTTPException(status_code=404, detail="User not found") |
| return db_user |
| |
| |
| @app.post("/users/{user_id}/items/", response_model=schemas.Item) |
| def create_item_for_user( |
| user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db) |
| ): |
| return crud.create_user_item(db=db, item=item, user_id=user_id) |
| |
| |
| @app.get("/items/", response_model=List[schemas.Item]) |
| def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): |
| items = crud.get_items(db, skip=skip, limit=limit) |
| return items |
| from sqlalchemy.orm import Session |
| |
| from . import models, schemas |
| |
| |
| def get_user(db: Session, user_id: int): |
| return db.query(models.User).filter(models.User.id == user_id).first() |
| |
| |
| def get_user_by_email(db: Session, email: str): |
| return db.query(models.User).filter(models.User.email == email).first() |
| |
| |
| def get_users(db: Session, skip: int = 0, limit: int = 100): |
| return db.query(models.User).offset(skip).limit(limit).all() |
| |
| |
| def create_user(db: Session, user: schemas.UserCreate): |
| fake_hashed_password = user.password + "notreallyhashed" |
| db_user = models.User(email=user.email, hashed_password=fake_hashed_password) |
| db.add(db_user) |
| db.commit() |
| db.refresh(db_user) |
| return db_user |
| |
| |
| def get_items(db: Session, skip: int = 0, limit: int = 100): |
| return db.query(models.Item).offset(skip).limit(limit).all() |
| |
| |
| def create_user_item(db: Session, item: schemas.ItemCreate, user_id: int): |
| db_item = models.Item(**item.dict(), owner_id=user_id) |
| db.add(db_item) |
| db.commit() |
| db.refresh(db_item) |
| return db_item |
| from fastapi.testclient import TestClient |
| from sqlalchemy import create_engine |
| from sqlalchemy.orm import sessionmaker |
| |
| from ..database import Base |
| from ..main import app, get_db |
| |
| SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db" |
| |
| engine = create_engine( |
| SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False} |
| ) |
| TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) |
| |
| |
| Base.metadata.create_all(bind=engine) |
| |
| |
| def override_get_db(): |
| try: |
| db = TestingSessionLocal() |
| yield db |
| finally: |
| db.close() |
| |
| |
| app.dependency_overrides[get_db] = override_get_db |
| |
| client = TestClient(app) |
| |
| |
| def test_create_user(): |
| response = client.post( |
| "/users/", |
| json={"email": "deadpool@example.com", "password": "chimichangas4life"}, |
| ) |
| assert response.status_code == 200, response.text |
| data = response.json() |
| assert data["email"] == "deadpool@example.com" |
| assert "id" in data |
| user_id = data["id"] |
| |
| response = client.get(f"/users/{user_id}") |
| assert response.status_code == 200, response.text |
| data = response.json() |
| assert data["email"] == "deadpool@example.com" |
| assert data["id"] == user_id |
| from datetime import datetime |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from fastapi.encoders import jsonable_encoder |
| from pydantic import BaseModel |
| |
| fake_db = {} |
| |
| |
| class Item(BaseModel): |
| title: str |
| timestamp: datetime |
| description: Optional[str] = None |
| |
| |
| app = FastAPI() |
| |
| |
| @app.put("/items/{id}") |
| def update_item(id: str, item: Item): |
| json_compatible_item_data = jsonable_encoder(item) |
| fake_db[id] = json_compatible_item_data |
| from fastapi import FastAPI |
| from fastapi.middleware.wsgi import WSGIMiddleware |
| from flask import Flask, escape, request |
| |
| flask_app = Flask(__name__) |
| |
| |
| @flask_app.route("/") |
| def flask_main(): |
| name = request.args.get("name", "World") |
| return f"Hello, {escape(name)} from Flask!" |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get("/v2") |
| def read_main(): |
| return {"message": "Hello World"} |
| |
| |
| app.mount("/v1", WSGIMiddleware(flask_app)) |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: str = Query(..., min_length=3)): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: Optional[str] = Query(None, max_length=50)): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import List |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: List[str] = Query(["foo", "bar"])): |
| query_items = {"q": q} |
| return query_items |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: Optional[str] = Query(None, min_length=3, max_length=50)): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: list = Query([])): |
| query_items = {"q": q} |
| return query_items |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items( |
| q: Optional[str] = Query(None, title="Query string", min_length=3) |
| ): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items( |
| q: Optional[str] = Query( |
| None, |
| title="Query string", |
| description="Query string for the items to search in the database that have a good match", |
| min_length=3, |
| ) |
| ): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: Optional[str] = Query(None, alias="item-query")): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items( |
| q: Optional[str] = Query( |
| None, |
| alias="item-query", |
| title="Query string", |
| description="Query string for the items to search in the database that have a good match", |
| min_length=3, |
| max_length=50, |
| regex="^fixedquery$", |
| deprecated=True, |
| ) |
| ): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items( |
| q: Optional[str] = Query(None, min_length=3, max_length=50, regex="^fixedquery$") |
| ): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: str = Query("fixedquery", min_length=3)): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: Optional[str] = None): |
| results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import List, Optional |
| |
| from fastapi import FastAPI, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(q: Optional[List[str]] = Query(None)): |
| query_items = {"q": q} |
| return query_items |
| import uvicorn |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| def root(): |
| a = "a" |
| b = "b" + a |
| return {"hello world": b} |
| |
| |
| if __name__ == "__main__": |
| uvicorn.run(app, host="0.0.0.0", port=8000) |
| 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")} |
| 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")} |
| 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")} |
| 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")} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_updates/tutorial002.py
| from typing import List, Optional |
| |
| from fastapi import FastAPI |
| from fastapi.encoders import jsonable_encoder |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: Optional[str] = None |
| description: Optional[str] = None |
| price: Optional[float] = None |
| tax: float = 10.5 |
| tags: List[str] = [] |
| |
| |
| items = { |
| "foo": {"name": "Foo", "price": 50.2}, |
| "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, |
| "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, |
| } |
| |
| |
| @app.get("/items/{item_id}", response_model=Item) |
| async def read_item(item_id: str): |
| return items[item_id] |
| |
| |
| @app.patch("/items/{item_id}", response_model=Item) |
| async def update_item(item_id: str, item: Item): |
| stored_item_data = items[item_id] |
| stored_item_model = Item(**stored_item_data) |
| update_data = item.dict(exclude_unset=True) |
| updated_item = stored_item_model.copy(update=update_data) |
| items[item_id] = jsonable_encoder(updated_item) |
| return updated_item |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_updates/tutorial001.py
| from typing import List, Optional |
| |
| from fastapi import FastAPI |
| from fastapi.encoders import jsonable_encoder |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: Optional[str] = None |
| description: Optional[str] = None |
| price: Optional[float] = None |
| tax: float = 10.5 |
| tags: List[str] = [] |
| |
| |
| items = { |
| "foo": {"name": "Foo", "price": 50.2}, |
| "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, |
| "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, |
| } |
| |
| |
| @app.get("/items/{item_id}", response_model=Item) |
| async def read_item(item_id: str): |
| return items[item_id] |
| |
| |
| @app.put("/items/{item_id}", response_model=Item) |
| async def update_item(item_id: str, item: Item): |
| update_item_encoded = jsonable_encoder(item) |
| items[item_id] = update_item_encoded |
| return update_item_encoded |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body/tutorial002.py
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| app = FastAPI() |
| |
| |
| @app.post("/items/") |
| async def create_item(item: Item): |
| item_dict = item.dict() |
| if item.tax: |
| price_with_tax = item.price + item.tax |
| item_dict.update({"price_with_tax": price_with_tax}) |
| return item_dict |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body/tutorial003.py
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| app = FastAPI() |
| |
| |
| @app.put("/items/{item_id}") |
| async def create_item(item_id: int, item: Item): |
| return {"item_id": item_id, **item.dict()} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body/tutorial004.py
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| app = FastAPI() |
| |
| |
| @app.put("/items/{item_id}") |
| async def create_item(item_id: int, item: Item, q: Optional[str] = None): |
| result = {"item_id": item_id, **item.dict()} |
| if q: |
| result.update({"q": q}) |
| return result |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body/tutorial001.py
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| app = FastAPI() |
| |
| |
| @app.post("/items/") |
| async def create_item(item: Item): |
| return item |
| from fastapi import FastAPI |
| from fastapi.routing import APIRoute |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"item_id": "Foo"}] |
| |
| |
| def use_route_names_as_operation_ids(app: FastAPI) -> None: |
| """ |
| Simplify operation IDs so that generated API clients have simpler function |
| names. |
| |
| Should be called only after all routes have been added. |
| """ |
| for route in app.routes: |
| if isinstance(route, APIRoute): |
| route.operation_id = route.name |
| |
| |
| use_route_names_as_operation_ids(app) |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/", include_in_schema=False) |
| async def read_items(): |
| return [{"item_id": "Foo"}] |
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| |
| |
| @app.post("/items/", response_model=Item, summary="Create an item") |
| async def create_item(item: Item): |
| """ |
| Create an item with all the information: |
| |
| - **name**: each item must have a name |
| - **description**: a long description |
| - **price**: required |
| - **tax**: if the item doesn't have tax, you can omit this |
| - **tags**: a set of unique tag strings for this item |
| \f |
| :param item: User input. |
| """ |
| return item |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/", operation_id="some_specific_id_you_define") |
| async def read_items(): |
| return [{"item_id": "Foo"}] |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id: int): |
| return {"item_id": item_id} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/users/me") |
| async def read_user_me(): |
| return {"user_id": "the current user"} |
| |
| |
| @app.get("/users/{user_id}") |
| async def read_user(user_id: str): |
| return {"user_id": user_id} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/files/{file_path:path}") |
| async def read_file(file_path: str): |
| return {"file_path": file_path} |
| from enum import Enum |
| |
| from fastapi import FastAPI |
| |
| |
| class ModelName(str, Enum): |
| alexnet = "alexnet" |
| resnet = "resnet" |
| lenet = "lenet" |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get("/models/{model_name}") |
| async def get_model(model_name: ModelName): |
| if model_name == ModelName.alexnet: |
| return {"model_name": model_name, "message": "Deep Learning FTW!"} |
| |
| if model_name.value == "lenet": |
| return {"model_name": model_name, "message": "LeCNN all the images"} |
| |
| return {"model_name": model_name, "message": "Have some residuals"} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id): |
| return {"item_id": item_id} |
| import peewee |
| |
| from .database import db |
| |
| |
| class User(peewee.Model): |
| email = peewee.CharField(unique=True, index=True) |
| hashed_password = peewee.CharField() |
| is_active = peewee.BooleanField(default=True) |
| |
| class Meta: |
| database = db |
| |
| |
| class Item(peewee.Model): |
| title = peewee.CharField(index=True) |
| description = peewee.CharField(index=True) |
| owner = peewee.ForeignKeyField(User, backref="items") |
| |
| class Meta: |
| database = db |
| from contextvars import ContextVar |
| |
| import peewee |
| |
| DATABASE_NAME = "test.db" |
| db_state_default = {"closed": None, "conn": None, "ctx": None, "transactions": None} |
| db_state = ContextVar("db_state", default=db_state_default.copy()) |
| |
| |
| class PeeweeConnectionState(peewee._ConnectionState): |
| def __init__(self, **kwargs): |
| super().__setattr__("_state", db_state) |
| super().__init__(**kwargs) |
| |
| def __setattr__(self, name, value): |
| self._state.get()[name] = value |
| |
| def __getattr__(self, name): |
| return self._state.get()[name] |
| |
| |
| db = peewee.SqliteDatabase(DATABASE_NAME, check_same_thread=False) |
| |
| db._state = PeeweeConnectionState() |
| from typing import Any, List, Optional |
| |
| import peewee |
| from pydantic import BaseModel |
| from pydantic.utils import GetterDict |
| |
| |
| class PeeweeGetterDict(GetterDict): |
| def get(self, key: Any, default: Any = None): |
| res = getattr(self._obj, key, default) |
| if isinstance(res, peewee.ModelSelect): |
| return list(res) |
| return res |
| |
| |
| class ItemBase(BaseModel): |
| title: str |
| description: Optional[str] = None |
| |
| |
| class ItemCreate(ItemBase): |
| pass |
| |
| |
| class Item(ItemBase): |
| id: int |
| owner_id: int |
| |
| class Config: |
| orm_mode = True |
| getter_dict = PeeweeGetterDict |
| |
| |
| class UserBase(BaseModel): |
| email: str |
| |
| |
| class UserCreate(UserBase): |
| password: str |
| |
| |
| class User(UserBase): |
| id: int |
| is_active: bool |
| items: List[Item] = [] |
| |
| class Config: |
| orm_mode = True |
| getter_dict = PeeweeGetterDict |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/sql_databases_peewee/sql_app/main.py
| import time |
| from typing import List |
| |
| from fastapi import Depends, FastAPI, HTTPException |
| |
| from . import crud, database, models, schemas |
| from .database import db_state_default |
| |
| database.db.connect() |
| database.db.create_tables([models.User, models.Item]) |
| database.db.close() |
| |
| app = FastAPI() |
| |
| sleep_time = 10 |
| |
| |
| async def reset_db_state(): |
| database.db._state._state.set(db_state_default.copy()) |
| database.db._state.reset() |
| |
| |
| def get_db(db_state=Depends(reset_db_state)): |
| try: |
| database.db.connect() |
| yield |
| finally: |
| if not database.db.is_closed(): |
| database.db.close() |
| |
| |
| @app.post("/users/", response_model=schemas.User, dependencies=[Depends(get_db)]) |
| def create_user(user: schemas.UserCreate): |
| db_user = crud.get_user_by_email(email=user.email) |
| if db_user: |
| raise HTTPException(status_code=400, detail="Email already registered") |
| return crud.create_user(user=user) |
| |
| |
| @app.get("/users/", response_model=List[schemas.User], dependencies=[Depends(get_db)]) |
| def read_users(skip: int = 0, limit: int = 100): |
| users = crud.get_users(skip=skip, limit=limit) |
| return users |
| |
| |
| @app.get( |
| "/users/{user_id}", response_model=schemas.User, dependencies=[Depends(get_db)] |
| ) |
| def read_user(user_id: int): |
| db_user = crud.get_user(user_id=user_id) |
| if db_user is None: |
| raise HTTPException(status_code=404, detail="User not found") |
| return db_user |
| |
| |
| @app.post( |
| "/users/{user_id}/items/", |
| response_model=schemas.Item, |
| dependencies=[Depends(get_db)], |
| ) |
| def create_item_for_user(user_id: int, item: schemas.ItemCreate): |
| return crud.create_user_item(item=item, user_id=user_id) |
| |
| |
| @app.get("/items/", response_model=List[schemas.Item], dependencies=[Depends(get_db)]) |
| def read_items(skip: int = 0, limit: int = 100): |
| items = crud.get_items(skip=skip, limit=limit) |
| return items |
| |
| |
| @app.get( |
| "/slowusers/", response_model=List[schemas.User], dependencies=[Depends(get_db)] |
| ) |
| def read_slow_users(skip: int = 0, limit: int = 100): |
| global sleep_time |
| sleep_time = max(0, sleep_time - 1) |
| time.sleep(sleep_time) |
| users = crud.get_users(skip=skip, limit=limit) |
| return users |
| from . import models, schemas |
| |
| |
| def get_user(user_id: int): |
| return models.User.filter(models.User.id == user_id).first() |
| |
| |
| def get_user_by_email(email: str): |
| return models.User.filter(models.User.email == email).first() |
| |
| |
| def get_users(skip: int = 0, limit: int = 100): |
| return list(models.User.select().offset(skip).limit(limit)) |
| |
| |
| def create_user(user: schemas.UserCreate): |
| fake_hashed_password = user.password + "notreallyhashed" |
| db_user = models.User(email=user.email, hashed_password=fake_hashed_password) |
| db_user.save() |
| return db_user |
| |
| |
| def get_items(skip: int = 0, limit: int = 100): |
| return list(models.Item.select().offset(skip).limit(limit)) |
| |
| |
| def create_user_item(item: schemas.ItemCreate, user_id: int): |
| db_item = models.Item(**item.dict(), owner_id=user_id) |
| db_item.save() |
| return db_item |
| from fastapi import Depends, FastAPI, Header, HTTPException |
| |
| app = FastAPI() |
| |
| |
| async def verify_token(x_token: str = Header(...)): |
| if x_token != "fake-super-secret-token": |
| raise HTTPException(status_code=400, detail="X-Token header invalid") |
| |
| |
| async def verify_key(x_key: str = Header(...)): |
| if x_key != "fake-super-secret-key": |
| raise HTTPException(status_code=400, detail="X-Key header invalid") |
| return x_key |
| |
| |
| @app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)]) |
| async def read_items(): |
| return [{"item": "Foo"}, {"item": "Bar"}] |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] |
| |
| |
| class CommonQueryParams: |
| def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100): |
| self.q = q |
| self.skip = skip |
| self.limit = limit |
| |
| |
| @app.get("/items/") |
| async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)): |
| response = {} |
| if commons.q: |
| response.update({"q": commons.q}) |
| items = fake_items_db[commons.skip : commons.skip + commons.limit] |
| response.update({"items": items}) |
| return response |
| from fastapi import Depends, FastAPI, Header, HTTPException |
| |
| |
| async def verify_token(x_token: str = Header(...)): |
| if x_token != "fake-super-secret-token": |
| raise HTTPException(status_code=400, detail="X-Token header invalid") |
| |
| |
| async def verify_key(x_key: str = Header(...)): |
| if x_key != "fake-super-secret-key": |
| raise HTTPException(status_code=400, detail="X-Key header invalid") |
| return x_key |
| |
| |
| app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)]) |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"item": "Portal Gun"}, {"item": "Plumbus"}] |
| |
| |
| @app.get("/users/") |
| async def read_users(): |
| return [{"username": "Rick"}, {"username": "Morty"}] |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] |
| |
| |
| class CommonQueryParams: |
| def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100): |
| self.q = q |
| self.skip = skip |
| self.limit = limit |
| |
| |
| @app.get("/items/") |
| async def read_items(commons=Depends(CommonQueryParams)): |
| response = {} |
| if commons.q: |
| response.update({"q": commons.q}) |
| items = fake_items_db[commons.skip : commons.skip + commons.limit] |
| response.update({"items": items}) |
| return response |
| async def get_db(): |
| db = DBSession() |
| try: |
| yield db |
| finally: |
| db.close() |
| from fastapi import Depends |
| |
| |
| async def dependency_a(): |
| dep_a = generate_dep_a() |
| try: |
| yield dep_a |
| finally: |
| dep_a.close() |
| |
| |
| async def dependency_b(dep_a=Depends(dependency_a)): |
| dep_b = generate_dep_b() |
| try: |
| yield dep_b |
| finally: |
| dep_b.close(dep_a) |
| |
| |
| async def dependency_c(dep_b=Depends(dependency_b)): |
| dep_c = generate_dep_c() |
| try: |
| yield dep_c |
| finally: |
| dep_c.close(dep_b) |
| from fastapi import Depends |
| |
| |
| async def dependency_a(): |
| dep_a = generate_dep_a() |
| try: |
| yield dep_a |
| finally: |
| dep_a.close() |
| |
| |
| async def dependency_b(dep_a=Depends(dependency_a)): |
| dep_b = generate_dep_b() |
| try: |
| yield dep_b |
| finally: |
| dep_b.close(dep_a) |
| |
| |
| async def dependency_c(dep_b=Depends(dependency_b)): |
| dep_c = generate_dep_c() |
| try: |
| yield dep_c |
| finally: |
| dep_c.close(dep_b) |
| class MySuperContextManager: |
| def __init__(self): |
| self.db = DBSession() |
| |
| def __enter__(self): |
| return self.db |
| |
| def __exit__(self, exc_type, exc_value, traceback): |
| self.db.close() |
| |
| |
| async def get_db(): |
| with MySuperContextManager() as db: |
| yield db |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] |
| |
| |
| class CommonQueryParams: |
| def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100): |
| self.q = q |
| self.skip = skip |
| self.limit = limit |
| |
| |
| @app.get("/items/") |
| async def read_items(commons: CommonQueryParams = Depends()): |
| response = {} |
| if commons.q: |
| response.update({"q": commons.q}) |
| items = fake_items_db[commons.skip : commons.skip + commons.limit] |
| response.update({"items": items}) |
| return response |
| from typing import Optional |
| |
| from fastapi import Cookie, Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| def query_extractor(q: Optional[str] = None): |
| return q |
| |
| |
| def query_or_cookie_extractor( |
| q: str = Depends(query_extractor), last_query: Optional[str] = Cookie(None) |
| ): |
| if not q: |
| return last_query |
| return q |
| |
| |
| @app.get("/items/") |
| async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)): |
| return {"q_or_cookie": query_or_default} |
| from typing import Optional |
| |
| from fastapi import Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100): |
| return {"q": q, "skip": skip, "limit": limit} |
| |
| |
| @app.get("/items/") |
| async def read_items(commons: dict = Depends(common_parameters)): |
| return commons |
| |
| |
| @app.get("/users/") |
| async def read_users(commons: dict = Depends(common_parameters)): |
| return commons |
| from fastapi import Depends, FastAPI |
| |
| app = FastAPI() |
| |
| |
| class FixedContentQueryChecker: |
| def __init__(self, fixed_content: str): |
| self.fixed_content = fixed_content |
| |
| def __call__(self, q: str = ""): |
| if q: |
| return self.fixed_content in q |
| return False |
| |
| |
| checker = FixedContentQueryChecker("bar") |
| |
| |
| @app.get("/query-checker/") |
| async def read_query_check(fixed_content_included: bool = Depends(checker)): |
| return {"fixed_content_in_query": fixed_content_included} |
| from fastapi import FastAPI, Request |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| def read_root(item_id: str, request: Request): |
| client_host = request.client.host |
| return {"client_host": client_host, "item_id": item_id} |
| from typing import Optional |
| |
| from fastapi import Cookie, Depends, FastAPI, Query, WebSocket, status |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| html = """ |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Chat</title> |
| </head> |
| <body> |
| <h1>WebSocket Chat</h1> |
| <form action="" onsubmit="sendMessage(event)"> |
| <label>Item ID: <input type="text" id="itemId" autocomplete="off" value="foo"/></label> |
| <label>Token: <input type="text" id="token" autocomplete="off" value="some-key-token"/></label> |
| <button onclick="connect(event)">Connect</button> |
| <hr> |
| <label>Message: <input type="text" id="messageText" autocomplete="off"/></label> |
| <button>Send</button> |
| </form> |
| <ul id='messages'> |
| </ul> |
| <script> |
| var ws = null; |
| function connect(event) { |
| var itemId = document.getElementById("itemId") |
| var token = document.getElementById("token") |
| ws = new WebSocket("ws://localhost:8000/items/" + itemId.value + "/ws?token=" + token.value); |
| ws.onmessage = function(event) { |
| var messages = document.getElementById('messages') |
| var message = document.createElement('li') |
| var content = document.createTextNode(event.data) |
| message.appendChild(content) |
| messages.appendChild(message) |
| }; |
| event.preventDefault() |
| } |
| function sendMessage(event) { |
| var input = document.getElementById("messageText") |
| ws.send(input.value) |
| input.value = '' |
| event.preventDefault() |
| } |
| </script> |
| </body> |
| </html> |
| """ |
| |
| |
| @app.get("/") |
| async def get(): |
| return HTMLResponse(html) |
| |
| |
| async def get_cookie_or_token( |
| websocket: WebSocket, |
| session: Optional[str] = Cookie(None), |
| token: Optional[str] = Query(None), |
| ): |
| if session is None and token is None: |
| await websocket.close(code=status.WS_1008_POLICY_VIOLATION) |
| return session or token |
| |
| |
| @app.websocket("/items/{item_id}/ws") |
| async def websocket_endpoint( |
| websocket: WebSocket, |
| item_id: str, |
| q: Optional[int] = None, |
| cookie_or_token: str = Depends(get_cookie_or_token), |
| ): |
| await websocket.accept() |
| while True: |
| data = await websocket.receive_text() |
| await websocket.send_text( |
| f"Session cookie or query token value is: {cookie_or_token}" |
| ) |
| if q is not None: |
| await websocket.send_text(f"Query parameter q is: {q}") |
| await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}") |
| from typing import List |
| |
| from fastapi import FastAPI, WebSocket, WebSocketDisconnect |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| html = """ |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Chat</title> |
| </head> |
| <body> |
| <h1>WebSocket Chat</h1> |
| <h2>Your ID: <span id="ws-id"></span></h2> |
| <form action="" onsubmit="sendMessage(event)"> |
| <input type="text" id="messageText" autocomplete="off"/> |
| <button>Send</button> |
| </form> |
| <ul id='messages'> |
| </ul> |
| <script> |
| var client_id = Date.now() |
| document.querySelector("#ws-id").textContent = client_id; |
| var ws = new WebSocket(`ws://localhost:8000/ws/${client_id}`); |
| ws.onmessage = function(event) { |
| var messages = document.getElementById('messages') |
| var message = document.createElement('li') |
| var content = document.createTextNode(event.data) |
| message.appendChild(content) |
| messages.appendChild(message) |
| }; |
| function sendMessage(event) { |
| var input = document.getElementById("messageText") |
| ws.send(input.value) |
| input.value = '' |
| event.preventDefault() |
| } |
| </script> |
| </body> |
| </html> |
| """ |
| |
| |
| class ConnectionManager: |
| def __init__(self): |
| self.active_connections: List[WebSocket] = [] |
| |
| async def connect(self, websocket: WebSocket): |
| await websocket.accept() |
| self.active_connections.append(websocket) |
| |
| def disconnect(self, websocket: WebSocket): |
| self.active_connections.remove(websocket) |
| |
| async def send_personal_message(self, message: str, websocket: WebSocket): |
| await websocket.send_text(message) |
| |
| async def broadcast(self, message: str): |
| for connection in self.active_connections: |
| await connection.send_text(message) |
| |
| |
| manager = ConnectionManager() |
| |
| |
| @app.get("/") |
| async def get(): |
| return HTMLResponse(html) |
| |
| |
| @app.websocket("/ws/{client_id}") |
| async def websocket_endpoint(websocket: WebSocket, client_id: int): |
| await manager.connect(websocket) |
| try: |
| while True: |
| data = await websocket.receive_text() |
| await manager.send_personal_message(f"You wrote: {data}", websocket) |
| await manager.broadcast(f"Client #{client_id} says: {data}") |
| except WebSocketDisconnect: |
| manager.disconnect(websocket) |
| await manager.broadcast(f"Client #{client_id} left the chat") |
| from fastapi import FastAPI, WebSocket |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| html = """ |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Chat</title> |
| </head> |
| <body> |
| <h1>WebSocket Chat</h1> |
| <form action="" onsubmit="sendMessage(event)"> |
| <input type="text" id="messageText" autocomplete="off"/> |
| <button>Send</button> |
| </form> |
| <ul id='messages'> |
| </ul> |
| <script> |
| var ws = new WebSocket("ws://localhost:8000/ws"); |
| ws.onmessage = function(event) { |
| var messages = document.getElementById('messages') |
| var message = document.createElement('li') |
| var content = document.createTextNode(event.data) |
| message.appendChild(content) |
| messages.appendChild(message) |
| }; |
| function sendMessage(event) { |
| var input = document.getElementById("messageText") |
| ws.send(input.value) |
| input.value = '' |
| event.preventDefault() |
| } |
| </script> |
| </body> |
| </html> |
| """ |
| |
| |
| @app.get("/") |
| async def get(): |
| return HTMLResponse(html) |
| |
| |
| @app.websocket("/ws") |
| async def websocket_endpoint(websocket: WebSocket): |
| await websocket.accept() |
| while True: |
| data = await websocket.receive_text() |
| await websocket.send_text(f"Message text was: {data}") |
| from datetime import datetime, time, timedelta |
| from typing import Optional |
| from uuid import UUID |
| |
| from fastapi import Body, FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.put("/items/{item_id}") |
| async def read_items( |
| item_id: UUID, |
| start_datetime: Optional[datetime] = Body(None), |
| end_datetime: Optional[datetime] = Body(None), |
| repeat_at: Optional[time] = Body(None), |
| process_after: Optional[timedelta] = Body(None), |
| ): |
| start_process = start_datetime + process_after |
| duration = end_datetime - start_process |
| return { |
| "item_id": item_id, |
| "start_datetime": start_datetime, |
| "end_datetime": end_datetime, |
| "repeat_at": repeat_at, |
| "process_after": process_after, |
| "start_process": start_process, |
| "duration": duration, |
| } |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from fastapi.responses import FileResponse |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| id: str |
| value: str |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get( |
| "/items/{item_id}", |
| response_model=Item, |
| responses={ |
| 200: { |
| "content": {"image/png": {}}, |
| "description": "Return the JSON item or an image.", |
| } |
| }, |
| ) |
| async def read_item(item_id: str, img: Optional[bool] = None): |
| if img: |
| return FileResponse("image.png", media_type="image/png") |
| else: |
| return {"id": "foo", "value": "there goes my hero"} |
| from fastapi import FastAPI |
| from fastapi.responses import JSONResponse |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| id: str |
| value: str |
| |
| |
| class Message(BaseModel): |
| message: str |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get( |
| "/items/{item_id}", |
| response_model=Item, |
| responses={ |
| 404: {"model": Message, "description": "The item was not found"}, |
| 200: { |
| "description": "Item requested by ID", |
| "content": { |
| "application/json": { |
| "example": {"id": "bar", "value": "The bar tenders"} |
| } |
| }, |
| }, |
| }, |
| ) |
| async def read_item(item_id: str): |
| if item_id == "foo": |
| return {"id": "foo", "value": "there goes my hero"} |
| else: |
| return JSONResponse(status_code=404, content={"message": "Item not found"}) |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from fastapi.responses import FileResponse |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| id: str |
| value: str |
| |
| |
| responses = { |
| 404: {"description": "Item not found"}, |
| 302: {"description": "The item was moved"}, |
| 403: {"description": "Not enough privileges"}, |
| } |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get( |
| "/items/{item_id}", |
| response_model=Item, |
| responses={**responses, 200: {"content": {"image/png": {}}}}, |
| ) |
| async def read_item(item_id: str, img: Optional[bool] = None): |
| if img: |
| return FileResponse("image.png", media_type="image/png") |
| else: |
| return {"id": "foo", "value": "there goes my hero"} |
| from fastapi import FastAPI |
| from fastapi.responses import JSONResponse |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| id: str |
| value: str |
| |
| |
| class Message(BaseModel): |
| message: str |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}", response_model=Item, responses={404: {"model": Message}}) |
| async def read_item(item_id: str): |
| if item_id == "foo": |
| return {"id": "foo", "value": "there goes my hero"} |
| else: |
| return JSONResponse(status_code=404, content={"message": "Item not found"}) |
| from fastapi import FastAPI, Form |
| |
| app = FastAPI() |
| |
| |
| @app.post("/login/") |
| async def login(username: str = Form(...), password: str = Form(...)): |
| return {"username": username} |
| from typing import Optional |
| |
| from fastapi import Body, FastAPI, status |
| from fastapi.responses import JSONResponse |
| |
| app = FastAPI() |
| |
| items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}} |
| |
| |
| @app.put("/items/{item_id}") |
| async def upsert_item( |
| item_id: str, name: Optional[str] = Body(None), size: Optional[int] = Body(None) |
| ): |
| if item_id in items: |
| item = items[item_id] |
| item["name"] = name |
| item["size"] = size |
| return item |
| else: |
| item = {"name": name, "size": size} |
| items[item_id] = item |
| return JSONResponse(status_code=status.HTTP_201_CREATED, content=item) |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/handling_errors/tutorial006.py
| from fastapi import FastAPI, HTTPException |
| from fastapi.exception_handlers import ( |
| http_exception_handler, |
| request_validation_exception_handler, |
| ) |
| from fastapi.exceptions import RequestValidationError |
| from starlette.exceptions import HTTPException as StarletteHTTPException |
| |
| app = FastAPI() |
| |
| |
| @app.exception_handler(StarletteHTTPException) |
| async def custom_http_exception_handler(request, exc): |
| print(f"OMG! An HTTP error!: {repr(exc)}") |
| return await http_exception_handler(request, exc) |
| |
| |
| @app.exception_handler(RequestValidationError) |
| async def validation_exception_handler(request, exc): |
| print(f"OMG! The client sent invalid data!: {exc}") |
| return await request_validation_exception_handler(request, exc) |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id: int): |
| if item_id == 3: |
| raise HTTPException(status_code=418, detail="Nope! I don't like 3.") |
| return {"item_id": item_id} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/handling_errors/tutorial002.py
| from fastapi import FastAPI, HTTPException |
| |
| app = FastAPI() |
| |
| items = {"foo": "The Foo Wrestlers"} |
| |
| |
| @app.get("/items-header/{item_id}") |
| async def read_item_header(item_id: str): |
| if item_id not in items: |
| raise HTTPException( |
| status_code=404, |
| detail="Item not found", |
| headers={"X-Error": "There goes my error"}, |
| ) |
| return {"item": items[item_id]} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/handling_errors/tutorial003.py
| from fastapi import FastAPI, Request |
| from fastapi.responses import JSONResponse |
| |
| |
| class UnicornException(Exception): |
| def __init__(self, name: str): |
| self.name = name |
| |
| |
| app = FastAPI() |
| |
| |
| @app.exception_handler(UnicornException) |
| async def unicorn_exception_handler(request: Request, exc: UnicornException): |
| return JSONResponse( |
| status_code=418, |
| content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."}, |
| ) |
| |
| |
| @app.get("/unicorns/{name}") |
| async def read_unicorn(name: str): |
| if name == "yolo": |
| raise UnicornException(name=name) |
| return {"unicorn_name": name} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/handling_errors/tutorial004.py
| from fastapi import FastAPI, HTTPException |
| from fastapi.exceptions import RequestValidationError |
| from fastapi.responses import PlainTextResponse |
| from starlette.exceptions import HTTPException as StarletteHTTPException |
| |
| app = FastAPI() |
| |
| |
| @app.exception_handler(StarletteHTTPException) |
| async def http_exception_handler(request, exc): |
| return PlainTextResponse(str(exc.detail), status_code=exc.status_code) |
| |
| |
| @app.exception_handler(RequestValidationError) |
| async def validation_exception_handler(request, exc): |
| return PlainTextResponse(str(exc), status_code=400) |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id: int): |
| if item_id == 3: |
| raise HTTPException(status_code=418, detail="Nope! I don't like 3.") |
| return {"item_id": item_id} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/handling_errors/tutorial005.py
| from fastapi import FastAPI, Request, status |
| from fastapi.encoders import jsonable_encoder |
| from fastapi.exceptions import RequestValidationError |
| from fastapi.responses import JSONResponse |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| @app.exception_handler(RequestValidationError) |
| async def validation_exception_handler(request: Request, exc: RequestValidationError): |
| return JSONResponse( |
| status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, |
| content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}), |
| ) |
| |
| |
| class Item(BaseModel): |
| title: str |
| size: int |
| |
| |
| @app.post("/items/") |
| async def create_item(item: Item): |
| return item |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/handling_errors/tutorial001.py
| from fastapi import FastAPI, HTTPException |
| |
| app = FastAPI() |
| |
| items = {"foo": "The Foo Wrestlers"} |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id: str): |
| if item_id not in items: |
| raise HTTPException(status_code=404, detail="Item not found") |
| return {"item": items[item_id]} |
| from fastapi import FastAPI |
| from fastapi.staticfiles import StaticFiles |
| |
| app = FastAPI() |
| |
| app.mount("/static", StaticFiles(directory="static"), name="static") |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/", tags=["items"]) |
| async def read_items(): |
| return [{"name": "Foo", "price": 42}] |
| |
| |
| @app.get("/users/", tags=["users"]) |
| async def read_users(): |
| return [{"username": "johndoe"}] |
| |
| |
| @app.get("/elements/", tags=["items"], deprecated=True) |
| async def read_elements(): |
| return [{"item_id": "Foo"}] |
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| |
| |
| @app.post("/items/", response_model=Item, tags=["items"]) |
| async def create_item(item: Item): |
| return item |
| |
| |
| @app.get("/items/", tags=["items"]) |
| async def read_items(): |
| return [{"name": "Foo", "price": 42}] |
| |
| |
| @app.get("/users/", tags=["users"]) |
| async def read_users(): |
| return [{"username": "johndoe"}] |
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| |
| |
| @app.post( |
| "/items/", |
| response_model=Item, |
| summary="Create an item", |
| description="Create an item with all the information, name, description, price, tax and a set of unique tags", |
| ) |
| async def create_item(item: Item): |
| return item |
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| |
| |
| @app.post("/items/", response_model=Item, summary="Create an item") |
| async def create_item(item: Item): |
| """ |
| Create an item with all the information: |
| |
| - **name**: each item must have a name |
| - **description**: a long description |
| - **price**: required |
| - **tax**: if the item doesn't have tax, you can omit this |
| - **tags**: a set of unique tag strings for this item |
| """ |
| return item |
| from typing import Optional, Set |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| |
| |
| @app.post( |
| "/items/", |
| response_model=Item, |
| summary="Create an item", |
| response_description="The created item", |
| ) |
| async def create_item(item: Item): |
| """ |
| Create an item with all the information: |
| |
| - **name**: each item must have a name |
| - **description**: a long description |
| - **price**: required |
| - **tax**: if the item doesn't have tax, you can omit this |
| - **tags**: a set of unique tag strings for this item |
| """ |
| return item |
| from typing import Optional, Set |
| |
| from fastapi import FastAPI, status |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| tags: Set[str] = [] |
| |
| |
| @app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED) |
| async def create_item(item: Item): |
| return item |
| from fastapi import FastAPI, Path, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items( |
| *, |
| item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000), |
| q: str, |
| size: float = Query(..., gt=0, lt=10.5) |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| return results |
| from fastapi import FastAPI, Path |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items( |
| q: str, item_id: int = Path(..., title="The ID of the item to get") |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| return results |
| from fastapi import FastAPI, Path |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items( |
| *, item_id: int = Path(..., title="The ID of the item to get"), q: str |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| return results |
| from fastapi import FastAPI, Path |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items( |
| *, item_id: int = Path(..., title="The ID of the item to get", ge=1), q: str |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| return results |
| from fastapi import FastAPI, Path |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items( |
| *, |
| item_id: int = Path(..., title="The ID of the item to get", gt=0, le=1000), |
| q: str, |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI, Path, Query |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items( |
| item_id: int = Path(..., title="The ID of the item to get"), |
| q: Optional[str] = Query(None, alias="item-query"), |
| ): |
| results = {"item_id": item_id} |
| if q: |
| results.update({"q": q}) |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_user_item( |
| item_id: str, needy: str, skip: int = 0, limit: Optional[int] = None |
| ): |
| item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit} |
| return item |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id: str, q: Optional[str] = None): |
| if q: |
| return {"item_id": item_id, "q": q} |
| return {"item_id": item_id} |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_item(item_id: str, q: Optional[str] = None, short: bool = False): |
| item = {"item_id": item_id} |
| if q: |
| item.update({"q": q}) |
| if not short: |
| item.update( |
| {"description": "This is an amazing item that has a long description"} |
| ) |
| return item |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/users/{user_id}/items/{item_id}") |
| async def read_user_item( |
| user_id: int, item_id: str, q: Optional[str] = None, short: bool = False |
| ): |
| item = {"item_id": item_id, "owner_id": user_id} |
| if q: |
| item.update({"q": q}) |
| if not short: |
| item.update( |
| {"description": "This is an amazing item that has a long description"} |
| ) |
| return item |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_user_item(item_id: str, needy: str): |
| item = {"item_id": item_id, "needy": needy} |
| return item |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}] |
| |
| |
| @app.get("/items/") |
| async def read_item(skip: int = 0, limit: int = 10): |
| return fake_items_db[skip : skip + limit] |
| import graphene |
| from fastapi import FastAPI |
| from starlette.graphql import GraphQLApp |
| |
| |
| class Query(graphene.ObjectType): |
| hello = graphene.String(name=graphene.String(default_value="stranger")) |
| |
| def resolve_hello(self, info, name): |
| return "Hello " + name |
| |
| |
| app = FastAPI() |
| app.add_route("/", GraphQLApp(schema=graphene.Schema(query=Query))) |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, Field |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str = Field(..., example="Foo") |
| description: Optional[str] = Field(None, example="A very nice Item") |
| price: float = Field(..., example=35.4) |
| tax: Optional[float] = Field(None, example=3.2) |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
| from typing import Optional |
| |
| from fastapi import Body, FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item( |
| item_id: int, |
| item: Item = Body( |
| ..., |
| example={ |
| "name": "Foo", |
| "description": "A very nice Item", |
| "price": 35.4, |
| "tax": 3.2, |
| }, |
| ), |
| ): |
| results = {"item_id": item_id, "item": item} |
| return results |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = None |
| price: float |
| tax: Optional[float] = None |
| |
| class Config: |
| schema_extra = { |
| "example": { |
| "name": "Foo", |
| "description": "A very nice Item", |
| "price": 35.4, |
| "tax": 3.2, |
| } |
| } |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item): |
| results = {"item_id": item_id, "item": item} |
| return results |
| from typing import Optional |
| |
| from fastapi import Cookie, FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(ads_id: Optional[str] = Cookie(None)): |
| return {"ads_id": ads_id} |
| from fastapi import FastAPI |
| from fastapi.middleware.cors import CORSMiddleware |
| |
| app = FastAPI() |
| |
| origins = [ |
| "http://localhost.tiangolo.com", |
| "https://localhost.tiangolo.com", |
| "http://localhost", |
| "http://localhost:8080", |
| ] |
| |
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=origins, |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
| |
| |
| @app.get("/") |
| async def main(): |
| return {"message": "Hello World"} |
| from fastapi import FastAPI, Response |
| |
| app = FastAPI() |
| |
| |
| @app.get("/headers-and-object/") |
| def get_headers(response: Response): |
| response.headers["X-Cat-Dog"] = "alone in the world" |
| return {"message": "Hello World"} |
| from fastapi import FastAPI |
| from fastapi.responses import JSONResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/headers/") |
| def get_headers(): |
| content = {"message": "Hello World"} |
| headers = {"X-Cat-Dog": "alone in the world", "Content-Language": "en-US"} |
| return JSONResponse(content=content, headers=headers) |
| from fastapi import FastAPI, Response, status |
| |
| app = FastAPI() |
| |
| tasks = {"foo": "Listen to the Bar Fighters"} |
| |
| |
| @app.put("/get-or-create-task/{task_id}", status_code=200) |
| def get_or_create_task(task_id: str, response: Response): |
| if task_id not in tasks: |
| tasks[task_id] = "This didn't exist before" |
| response.status_code = status.HTTP_201_CREATED |
| return tasks[task_id] |
| from fastapi import FastAPI, Request |
| from fastapi.responses import HTMLResponse |
| from fastapi.staticfiles import StaticFiles |
| from fastapi.templating import Jinja2Templates |
| |
| app = FastAPI() |
| |
| app.mount("/static", StaticFiles(directory="static"), name="static") |
| |
| |
| templates = Jinja2Templates(directory="templates") |
| |
| |
| @app.get("/items/{id}", response_class=HTMLResponse) |
| async def read_item(request: Request, id: str): |
| return templates.TemplateResponse("item.html", {"request": request, "id": id}) |
| <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> |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/custom_request_and_route/tutorial002.py
| from typing import Callable, List |
| |
| from fastapi import Body, FastAPI, HTTPException, Request, Response |
| from fastapi.exceptions import RequestValidationError |
| from fastapi.routing import APIRoute |
| |
| |
| class ValidationErrorLoggingRoute(APIRoute): |
| def get_route_handler(self) -> Callable: |
| original_route_handler = super().get_route_handler() |
| |
| async def custom_route_handler(request: Request) -> Response: |
| try: |
| return await original_route_handler(request) |
| except RequestValidationError as exc: |
| body = await request.body() |
| detail = {"errors": exc.errors(), "body": body.decode()} |
| raise HTTPException(status_code=422, detail=detail) |
| |
| return custom_route_handler |
| |
| |
| app = FastAPI() |
| app.router.route_class = ValidationErrorLoggingRoute |
| |
| |
| @app.post("/") |
| async def sum_numbers(numbers: List[int] = Body(...)): |
| return sum(numbers) |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/custom_request_and_route/tutorial003.py
| import time |
| from typing import Callable |
| |
| from fastapi import APIRouter, FastAPI, Request, Response |
| from fastapi.routing import APIRoute |
| |
| |
| class TimedRoute(APIRoute): |
| def get_route_handler(self) -> Callable: |
| original_route_handler = super().get_route_handler() |
| |
| async def custom_route_handler(request: Request) -> Response: |
| before = time.time() |
| response: Response = await original_route_handler(request) |
| duration = time.time() - before |
| response.headers["X-Response-Time"] = str(duration) |
| print(f"route duration: {duration}") |
| print(f"route response: {response}") |
| print(f"route response headers: {response.headers}") |
| return response |
| |
| return custom_route_handler |
| |
| |
| app = FastAPI() |
| router = APIRouter(route_class=TimedRoute) |
| |
| |
| @app.get("/") |
| async def not_timed(): |
| return {"message": "Not timed"} |
| |
| |
| @router.get("/timed") |
| async def timed(): |
| return {"message": "It's the time of my life"} |
| |
| |
| app.include_router(router) |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/custom_request_and_route/tutorial001.py
| import gzip |
| from typing import Callable, List |
| |
| from fastapi import Body, FastAPI, Request, Response |
| from fastapi.routing import APIRoute |
| |
| |
| class GzipRequest(Request): |
| async def body(self) -> bytes: |
| if not hasattr(self, "_body"): |
| body = await super().body() |
| if "gzip" in self.headers.getlist("Content-Encoding"): |
| body = gzip.decompress(body) |
| self._body = body |
| return self._body |
| |
| |
| class GzipRoute(APIRoute): |
| def get_route_handler(self) -> Callable: |
| original_route_handler = super().get_route_handler() |
| |
| async def custom_route_handler(request: Request) -> Response: |
| request = GzipRequest(request.scope, request.receive) |
| return await original_route_handler(request) |
| |
| return custom_route_handler |
| |
| |
| app = FastAPI() |
| app.router.route_class = GzipRoute |
| |
| |
| @app.post("/sum") |
| async def sum_numbers(numbers: List[int] = Body(...)): |
| return {"sum": sum(numbers)} |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, EmailStr |
| |
| app = FastAPI() |
| |
| |
| class UserBase(BaseModel): |
| username: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| class UserIn(UserBase): |
| password: str |
| |
| |
| class UserOut(UserBase): |
| pass |
| |
| |
| class UserInDB(UserBase): |
| hashed_password: str |
| |
| |
| def fake_password_hasher(raw_password: str): |
| return "supersecret" + raw_password |
| |
| |
| def fake_save_user(user_in: UserIn): |
| hashed_password = fake_password_hasher(user_in.password) |
| user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password) |
| print("User saved! ..not really") |
| return user_in_db |
| |
| |
| @app.post("/user/", response_model=UserOut) |
| async def create_user(user_in: UserIn): |
| user_saved = fake_save_user(user_in) |
| return user_saved |
| from typing import Union |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class BaseItem(BaseModel): |
| description: str |
| type: str |
| |
| |
| class CarItem(BaseItem): |
| type = "car" |
| |
| |
| class PlaneItem(BaseItem): |
| type = "plane" |
| size: int |
| |
| |
| items = { |
| "item1": {"description": "All my friends drive a low rider", "type": "car"}, |
| "item2": { |
| "description": "Music is my aeroplane, it's my aeroplane", |
| "type": "plane", |
| "size": 5, |
| }, |
| } |
| |
| |
| @app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem]) |
| async def read_item(item_id: str): |
| return items[item_id] |
| from typing import List |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: str |
| |
| |
| items = [ |
| {"name": "Foo", "description": "There comes my hero"}, |
| {"name": "Red", "description": "It's my aeroplane"}, |
| ] |
| |
| |
| @app.get("/items/", response_model=List[Item]) |
| async def read_items(): |
| return items |
| from typing import Dict |
| |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/keyword-weights/", response_model=Dict[str, float]) |
| async def read_keyword_weights(): |
| return {"foo": 2.3, "bar": 3.4} |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from pydantic import BaseModel, EmailStr |
| |
| app = FastAPI() |
| |
| |
| class UserIn(BaseModel): |
| username: str |
| password: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| class UserOut(BaseModel): |
| username: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| class UserInDB(BaseModel): |
| username: str |
| hashed_password: str |
| email: EmailStr |
| full_name: Optional[str] = None |
| |
| |
| def fake_password_hasher(raw_password: str): |
| return "supersecret" + raw_password |
| |
| |
| def fake_save_user(user_in: UserIn): |
| hashed_password = fake_password_hasher(user_in.password) |
| user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password) |
| print("User saved! ..not really") |
| return user_in_db |
| |
| |
| @app.post("/user/", response_model=UserOut) |
| async def create_user(user_in: UserIn): |
| user_saved = fake_save_user(user_in) |
| return user_saved |
| from fastapi import FastAPI |
| from fastapi.testclient import TestClient |
| from fastapi.websockets import WebSocket |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| async def read_main(): |
| return {"msg": "Hello World"} |
| |
| |
| @app.websocket_route("/ws") |
| async def websocket(websocket: WebSocket): |
| await websocket.accept() |
| await websocket.send_json({"msg": "Hello WebSocket"}) |
| await websocket.close() |
| |
| |
| def test_read_main(): |
| client = TestClient(app) |
| response = client.get("/") |
| assert response.status_code == 200 |
| assert response.json() == {"msg": "Hello World"} |
| |
| |
| def test_websocket(): |
| client = TestClient(app) |
| with client.websocket_connect("/ws") as websocket: |
| data = websocket.receive_json() |
| assert data == {"msg": "Hello WebSocket"} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/app_testing/main_b.py
| from typing import Optional |
| |
| from fastapi import FastAPI, Header, HTTPException |
| from pydantic import BaseModel |
| |
| fake_secret_token = "coneofsilence" |
| |
| fake_db = { |
| "foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"}, |
| "bar": {"id": "bar", "title": "Bar", "description": "The bartenders"}, |
| } |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| id: str |
| title: str |
| description: Optional[str] = None |
| |
| |
| @app.get("/items/{item_id}", response_model=Item) |
| async def read_main(item_id: str, x_token: str = Header(...)): |
| if x_token != fake_secret_token: |
| raise HTTPException(status_code=400, detail="Invalid X-Token header") |
| if item_id not in fake_db: |
| raise HTTPException(status_code=404, detail="Item not found") |
| return fake_db[item_id] |
| |
| |
| @app.post("/items/", response_model=Item) |
| async def create_item(item: Item, x_token: str = Header(...)): |
| if x_token != fake_secret_token: |
| raise HTTPException(status_code=400, detail="Invalid X-Token header") |
| if item.id in fake_db: |
| raise HTTPException(status_code=400, detail="Item already exists") |
| fake_db[item.id] = item |
| return item |
| from fastapi import FastAPI |
| from fastapi.testclient import TestClient |
| |
| app = FastAPI() |
| |
| items = {} |
| |
| |
| @app.on_event("startup") |
| async def startup_event(): |
| items["foo"] = {"name": "Fighters"} |
| items["bar"] = {"name": "Tenders"} |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items(item_id: str): |
| return items[item_id] |
| |
| |
| def test_read_items(): |
| with TestClient(app) as client: |
| response = client.get("/items/foo") |
| assert response.status_code == 200 |
| assert response.json() == {"name": "Fighters"} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/app_testing/test_main_b.py
| from fastapi.testclient import TestClient |
| |
| from .main_b import app |
| |
| client = TestClient(app) |
| |
| |
| def test_read_item(): |
| response = client.get("/items/foo", headers={"X-Token": "coneofsilence"}) |
| assert response.status_code == 200 |
| assert response.json() == { |
| "id": "foo", |
| "title": "Foo", |
| "description": "There goes my hero", |
| } |
| |
| |
| def test_read_item_bad_token(): |
| response = client.get("/items/foo", headers={"X-Token": "hailhydra"}) |
| assert response.status_code == 400 |
| assert response.json() == {"detail": "Invalid X-Token header"} |
| |
| |
| def test_read_inexistent_item(): |
| response = client.get("/items/baz", headers={"X-Token": "coneofsilence"}) |
| assert response.status_code == 404 |
| assert response.json() == {"detail": "Item not found"} |
| |
| |
| def test_create_item(): |
| response = client.post( |
| "/items/", |
| headers={"X-Token": "coneofsilence"}, |
| json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"}, |
| ) |
| assert response.status_code == 200 |
| assert response.json() == { |
| "id": "foobar", |
| "title": "Foo Bar", |
| "description": "The Foo Barters", |
| } |
| |
| |
| def test_create_item_bad_token(): |
| response = client.post( |
| "/items/", |
| headers={"X-Token": "hailhydra"}, |
| json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"}, |
| ) |
| assert response.status_code == 400 |
| assert response.json() == {"detail": "Invalid X-Token header"} |
| |
| |
| def test_create_existing_item(): |
| response = client.post( |
| "/items/", |
| headers={"X-Token": "coneofsilence"}, |
| json={ |
| "id": "foo", |
| "title": "The Foo ID Stealers", |
| "description": "There goes my stealer", |
| }, |
| ) |
| assert response.status_code == 400 |
| assert response.json() == {"detail": "Item already exists"} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/app_testing/main.py
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| async def read_main(): |
| return {"msg": "Hello World"} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/app_testing/test_main.py
| from fastapi.testclient import TestClient |
| |
| from .main import app |
| |
| client = TestClient(app) |
| |
| |
| def test_read_main(): |
| response = client.get("/") |
| assert response.status_code == 200 |
| assert response.json() == {"msg": "Hello World"} |
| from fastapi import FastAPI |
| from fastapi.testclient import TestClient |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| async def read_main(): |
| return {"msg": "Hello World"} |
| |
| |
| client = TestClient(app) |
| |
| |
| def test_read_main(): |
| response = client.get("/") |
| assert response.status_code == 200 |
| assert response.json() == {"msg": "Hello World"} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/bigger_applications/app/main.py
| from fastapi import Depends, FastAPI |
| |
| from .dependencies import get_query_token, get_token_header |
| from .internal import admin |
| from .routers import items, users |
| |
| app = FastAPI(dependencies=[Depends(get_query_token)]) |
| |
| |
| app.include_router(users.router) |
| app.include_router(items.router) |
| app.include_router( |
| admin.router, |
| prefix="/admin", |
| tags=["admin"], |
| dependencies=[Depends(get_token_header)], |
| responses={418: {"description": "I'm a teapot"}}, |
| ) |
| |
| |
| @app.get("/") |
| async def root(): |
| return {"message": "Hello Bigger Applications!"} |
| from fastapi import Header, HTTPException |
| |
| |
| async def get_token_header(x_token: str = Header(...)): |
| if x_token != "fake-super-secret-token": |
| raise HTTPException(status_code=400, detail="X-Token header invalid") |
| |
| |
| async def get_query_token(token: str): |
| if token != "jessica": |
| raise HTTPException(status_code=400, detail="No Jessica token provided") |
| from fastapi import APIRouter |
| |
| router = APIRouter() |
| |
| |
| @router.get("/users/", tags=["users"]) |
| async def read_users(): |
| return [{"username": "Rick"}, {"username": "Morty"}] |
| |
| |
| @router.get("/users/me", tags=["users"]) |
| async def read_user_me(): |
| return {"username": "fakecurrentuser"} |
| |
| |
| @router.get("/users/{username}", tags=["users"]) |
| async def read_user(username: str): |
| return {"username": username} |
| from fastapi import APIRouter, Depends, HTTPException |
| |
| from ..dependencies import get_token_header |
| |
| router = APIRouter( |
| prefix="/items", |
| tags=["items"], |
| dependencies=[Depends(get_token_header)], |
| responses={404: {"description": "Not found"}}, |
| ) |
| |
| |
| fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}} |
| |
| |
| @router.get("/") |
| async def read_items(): |
| return fake_items_db |
| |
| |
| @router.get("/{item_id}") |
| async def read_item(item_id: str): |
| if item_id not in fake_items_db: |
| raise HTTPException(status_code=404, detail="Item not found") |
| return {"name": fake_items_db[item_id]["name"], "item_id": item_id} |
| |
| |
| @router.put( |
| "/{item_id}", |
| tags=["custom"], |
| responses={403: {"description": "Operation forbidden"}}, |
| ) |
| async def update_item(item_id: str): |
| if item_id != "plumbus": |
| raise HTTPException( |
| status_code=403, detail="You can only update the item: plumbus" |
| ) |
| return {"item_id": item_id, "name": "The great Plumbus"} |
| from fastapi import APIRouter |
| |
| router = APIRouter() |
| |
| |
| @router.post("/") |
| async def update_admin(): |
| return {"message": "Admin getting schwifty"} |
| from fastapi import FastAPI |
| |
| my_awesome_api = FastAPI() |
| |
| |
| @my_awesome_api.get("/") |
| async def root(): |
| return {"message": "Hello World"} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| def root(): |
| return {"message": "Hello World"} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| async def root(): |
| return {"message": "Hello World"} |
| from typing import List |
| |
| import databases |
| import sqlalchemy |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| |
| DATABASE_URL = "sqlite:///./test.db" |
| |
| |
| database = databases.Database(DATABASE_URL) |
| |
| metadata = sqlalchemy.MetaData() |
| |
| notes = sqlalchemy.Table( |
| "notes", |
| metadata, |
| sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True), |
| sqlalchemy.Column("text", sqlalchemy.String), |
| sqlalchemy.Column("completed", sqlalchemy.Boolean), |
| ) |
| |
| |
| engine = sqlalchemy.create_engine( |
| DATABASE_URL, connect_args={"check_same_thread": False} |
| ) |
| metadata.create_all(engine) |
| |
| |
| class NoteIn(BaseModel): |
| text: str |
| completed: bool |
| |
| |
| class Note(BaseModel): |
| id: int |
| text: str |
| completed: bool |
| |
| |
| app = FastAPI() |
| |
| |
| @app.on_event("startup") |
| async def startup(): |
| await database.connect() |
| |
| |
| @app.on_event("shutdown") |
| async def shutdown(): |
| await database.disconnect() |
| |
| |
| @app.get("/notes/", response_model=List[Note]) |
| async def read_notes(): |
| query = notes.select() |
| return await database.fetch_all(query) |
| |
| |
| @app.post("/notes/", response_model=Note) |
| async def create_note(note: NoteIn): |
| query = notes.insert().values(text=note.text, completed=note.completed) |
| last_record_id = await database.execute(query) |
| return {**note.dict(), "id": last_record_id} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/body_fields/tutorial001.py
| from typing import Optional |
| |
| from fastapi import Body, FastAPI |
| from pydantic import BaseModel, Field |
| |
| app = FastAPI() |
| |
| |
| class Item(BaseModel): |
| name: str |
| description: Optional[str] = Field( |
| None, title="The description of the item", max_length=300 |
| ) |
| price: float = Field(..., gt=0, description="The price must be greater than zero") |
| tax: Optional[float] = None |
| |
| |
| @app.put("/items/{item_id}") |
| async def update_item(item_id: int, item: Item = Body(..., embed=True)): |
| results = {"item_id": item_id, "item": item} |
| return results |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.on_event("shutdown") |
| def shutdown_event(): |
| with open("log.txt", mode="a") as log: |
| log.write("Application shutdown") |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"name": "Foo"}] |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| items = {} |
| |
| |
| @app.on_event("startup") |
| async def startup_event(): |
| items["foo"] = {"name": "Fighters"} |
| items["bar"] = {"name": "Tenders"} |
| |
| |
| @app.get("/items/{item_id}") |
| async def read_items(item_id: str): |
| return items[item_id] |
| from fastapi import FastAPI, Response |
| |
| app = FastAPI() |
| |
| |
| @app.post("/cookie-and-object/") |
| def create_cookie(response: Response): |
| response.set_cookie(key="fakesession", value="fake-cookie-session-value") |
| return {"message": "Come to the dark side, we have cookies"} |
| from fastapi import FastAPI |
| from fastapi.responses import JSONResponse |
| |
| app = FastAPI() |
| |
| |
| @app.post("/cookie/") |
| def create_cookie(): |
| content = {"message": "Come to the dark side, we have cookies"} |
| response = JSONResponse(content=content) |
| response.set_cookie(key="fakesession", value="fake-cookie-session-value") |
| return response |
| from fastapi import FastAPI |
| from fastapi.responses import RedirectResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/typer") |
| async def read_typer(): |
| return RedirectResponse("https://typer.tiangolo.com") |
| from fastapi import FastAPI |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/", response_class=HTMLResponse) |
| async def read_items(): |
| return """ |
| <html> |
| <head> |
| <title>Some HTML in here</title> |
| </head> |
| <body> |
| <h1>Look ma! HTML!</h1> |
| </body> |
| </html> |
| """ |
| from fastapi import FastAPI |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| html_content = """ |
| <html> |
| <head> |
| <title>Some HTML in here</title> |
| </head> |
| <body> |
| <h1>Look ma! HTML!</h1> |
| </body> |
| </html> |
| """ |
| return HTMLResponse(content=html_content, status_code=200) |
| from fastapi import FastAPI |
| from fastapi.responses import StreamingResponse |
| |
| app = FastAPI() |
| |
| |
| async def fake_video_streamer(): |
| for i in range(10): |
| yield b"some fake video bytes" |
| |
| |
| @app.get("/") |
| async def main(): |
| return StreamingResponse(fake_video_streamer()) |
| from fastapi import FastAPI |
| from fastapi.responses import StreamingResponse |
| |
| some_file_path = "large-video-file.mp4" |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| def main(): |
| file_like = open(some_file_path, mode="rb") |
| return StreamingResponse(file_like, media_type="video/mp4") |
| from fastapi import FastAPI |
| from fastapi.responses import FileResponse |
| |
| some_file_path = "large-video-file.mp4" |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| async def main(): |
| return FileResponse(some_file_path) |
| from fastapi import FastAPI |
| from fastapi.responses import ORJSONResponse |
| |
| app = FastAPI(default_response_class=ORJSONResponse) |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"item_id": "Foo"}] |
| from fastapi import FastAPI |
| from fastapi.responses import HTMLResponse |
| |
| app = FastAPI() |
| |
| |
| def generate_html_response(): |
| html_content = """ |
| <html> |
| <head> |
| <title>Some HTML in here</title> |
| </head> |
| <body> |
| <h1>Look ma! HTML!</h1> |
| </body> |
| </html> |
| """ |
| return HTMLResponse(content=html_content, status_code=200) |
| |
| |
| @app.get("/items/", response_class=HTMLResponse) |
| async def read_items(): |
| return generate_html_response() |
| from fastapi import FastAPI |
| from fastapi.responses import ORJSONResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/", response_class=ORJSONResponse) |
| async def read_items(): |
| return [{"item_id": "Foo"}] |
| from fastapi import FastAPI |
| from fastapi.responses import PlainTextResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/", response_class=PlainTextResponse) |
| async def main(): |
| return "Hello World" |
| from fastapi import FastAPI |
| from fastapi.responses import UJSONResponse |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/", response_class=UJSONResponse) |
| async def read_items(): |
| return [{"item_id": "Foo"}] |
| from fastapi import FastAPI |
| |
| app = FastAPI(openapi_url="/api/v1/openapi.json") |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"name": "Foo"}] |
| from fastapi import FastAPI |
| |
| app = FastAPI(docs_url="/documentation", redoc_url=None) |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"name": "Foo"}] |
| from fastapi import FastAPI |
| |
| tags_metadata = [ |
| { |
| "name": "users", |
| "description": "Operations with users. The **login** logic is also here.", |
| }, |
| { |
| "name": "items", |
| "description": "Manage items. So _fancy_ they have their own docs.", |
| "externalDocs": { |
| "description": "Items external docs", |
| "url": "https://fastapi.tiangolo.com/", |
| }, |
| }, |
| ] |
| |
| app = FastAPI(openapi_tags=tags_metadata) |
| |
| |
| @app.get("/users/", tags=["users"]) |
| async def get_users(): |
| return [{"name": "Harry"}, {"name": "Ron"}] |
| |
| |
| @app.get("/items/", tags=["items"]) |
| async def get_items(): |
| return [{"name": "wand"}, {"name": "flying broom"}] |
| from fastapi import FastAPI |
| |
| app = FastAPI( |
| title="My Super Project", |
| description="This is a very fancy project, with auto docs for the API and everything", |
| version="2.5.0", |
| ) |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"name": "Foo"}] |
| from fastapi import FastAPI |
| from fastapi.middleware.trustedhost import TrustedHostMiddleware |
| |
| app = FastAPI() |
| |
| app.add_middleware( |
| TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"] |
| ) |
| |
| |
| @app.get("/") |
| async def main(): |
| return {"message": "Hello World"} |
| from fastapi import FastAPI |
| from fastapi.middleware.gzip import GZipMiddleware |
| |
| app = FastAPI() |
| |
| app.add_middleware(GZipMiddleware, minimum_size=1000) |
| |
| |
| @app.get("/") |
| async def main(): |
| return "somebigcontent" |
| from fastapi import FastAPI |
| from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware |
| |
| app = FastAPI() |
| |
| app.add_middleware(HTTPSRedirectMiddleware) |
| |
| |
| @app.get("/") |
| async def main(): |
| return {"message": "Hello World"} |
| from fastapi import FastAPI |
| from fastapi.openapi.docs import ( |
| get_redoc_html, |
| get_swagger_ui_html, |
| get_swagger_ui_oauth2_redirect_html, |
| ) |
| from fastapi.staticfiles import StaticFiles |
| |
| app = FastAPI(docs_url=None, redoc_url=None) |
| |
| app.mount("/static", StaticFiles(directory="static"), name="static") |
| |
| |
| @app.get("/docs", include_in_schema=False) |
| async def custom_swagger_ui_html(): |
| return get_swagger_ui_html( |
| openapi_url=app.openapi_url, |
| title=app.title + " - Swagger UI", |
| oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url, |
| swagger_js_url="/static/swagger-ui-bundle.js", |
| swagger_css_url="/static/swagger-ui.css", |
| ) |
| |
| |
| @app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False) |
| async def swagger_ui_redirect(): |
| return get_swagger_ui_oauth2_redirect_html() |
| |
| |
| @app.get("/redoc", include_in_schema=False) |
| async def redoc_html(): |
| return get_redoc_html( |
| openapi_url=app.openapi_url, |
| title=app.title + " - ReDoc", |
| redoc_js_url="/static/redoc.standalone.js", |
| ) |
| |
| |
| @app.get("/users/{username}") |
| async def read_user(username: str): |
| return {"message": f"Hello {username}"} |
| from fastapi import FastAPI |
| from fastapi.openapi.utils import get_openapi |
| |
| app = FastAPI() |
| |
| |
| @app.get("/items/") |
| async def read_items(): |
| return [{"name": "Foo"}] |
| |
| |
| def custom_openapi(): |
| if app.openapi_schema: |
| return app.openapi_schema |
| openapi_schema = get_openapi( |
| title="Custom title", |
| version="2.5.0", |
| description="This is a very custom OpenAPI schema", |
| routes=app.routes, |
| ) |
| openapi_schema["info"]["x-logo"] = { |
| "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" |
| } |
| app.openapi_schema = openapi_schema |
| return app.openapi_schema |
| |
| |
| app.openapi = custom_openapi |
| from typing import Optional |
| |
| from couchbase import LOCKMODE_WAIT |
| from couchbase.bucket import Bucket |
| from couchbase.cluster import Cluster, PasswordAuthenticator |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| |
| USERPROFILE_DOC_TYPE = "userprofile" |
| |
| |
| def get_bucket(): |
| cluster = Cluster( |
| "couchbase://couchbasehost:8091?fetch_mutation_tokens=1&operation_timeout=30&n1ql_timeout=300" |
| ) |
| authenticator = PasswordAuthenticator("username", "password") |
| cluster.authenticate(authenticator) |
| bucket: Bucket = cluster.open_bucket("bucket_name", lockmode=LOCKMODE_WAIT) |
| bucket.timeout = 30 |
| bucket.n1ql_timeout = 300 |
| return bucket |
| |
| |
| class User(BaseModel): |
| username: str |
| email: Optional[str] = None |
| full_name: Optional[str] = None |
| disabled: Optional[bool] = None |
| |
| |
| class UserInDB(User): |
| type: str = USERPROFILE_DOC_TYPE |
| hashed_password: str |
| |
| |
| def get_user(bucket: Bucket, username: str): |
| doc_id = f"userprofile::{username}" |
| result = bucket.get(doc_id, quiet=True) |
| if not result.value: |
| return None |
| user = UserInDB(**result.value) |
| return user |
| |
| |
| |
| app = FastAPI() |
| |
| |
| @app.get("/users/{username}", response_model=User) |
| def read_user(username: str): |
| bucket = get_bucket() |
| user = get_user(bucket=bucket, username=username) |
| return user |
| from fastapi import FastAPI, Response |
| |
| app = FastAPI() |
| |
| |
| @app.get("/legacy/") |
| def get_legacy_data(): |
| data = """<?xml version="1.0"?> |
| <shampoo> |
| <Header> |
| Apply shampoo here. |
| </Header> |
| <Body> |
| You'll have to use soap here. |
| </Body> |
| </shampoo> |
| """ |
| return Response(content=data, media_type="application/xml") |
| from datetime import datetime |
| from typing import Optional |
| |
| from fastapi import FastAPI |
| from fastapi.encoders import jsonable_encoder |
| from fastapi.responses import JSONResponse |
| from pydantic import BaseModel |
| |
| |
| class Item(BaseModel): |
| title: str |
| timestamp: datetime |
| description: Optional[str] = None |
| |
| |
| app = FastAPI() |
| |
| |
| @app.put("/items/{id}") |
| def update_item(id: str, item: Item): |
| json_compatible_item_data = jsonable_encoder(item) |
| return JSONResponse(content=json_compatible_item_data) |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/async_tests/main.py
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/") |
| async def root(): |
| return {"message": "Tomato"} |
/Users/song/Code/fastapi_docs_src_教程/fastapi/docs_src/async_tests/test_main.py
| import pytest |
| from httpx import AsyncClient |
| |
| from .main import app |
| |
| |
| @pytest.mark.asyncio |
| async def test_root(): |
| async with AsyncClient(app=app, base_url="http://test") as ac: |
| response = await ac.get("/") |
| assert response.status_code == 200 |
| assert response.json() == {"message": "Tomato"} |
| from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| |
| @app.get("/app") |
| def read_main(): |
| return {"message": "Hello World from main app"} |
| |
| |
| subapi = FastAPI() |
| |
| |
| @subapi.get("/sub") |
| def read_sub(): |
| return {"message": "Hello World from sub API"} |
| |
| |
| app.mount("/subapi", subapi) |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
2022-02-12 css 四种基本选择器
2022-02-12 四种基本选择器
2022-02-12 css的三种引入方式
2022-02-12 html中元素之间的关系
2022-02-12 块级元素 行内元素
2022-02-12 代码提示 thisArg argArray
2022-02-12 如何监听一个对象