FastAPI¶
The FastAPI adapter wraps an SEOConfig and builds payloads per route.
Prerequisites¶
- Python 3.10 or newer.
- FastAPI 0.100 or newer.
Install¶
Quick start¶
from fastapi import FastAPI
from easeo import SEOConfig
from easeo.adapters.fastapi import EaseoSEO
app = FastAPI()
seo = EaseoSEO(
SEOConfig(
canonical_host="example.com",
public_base_url="https://example.com",
)
)
class Product:
entity_type = "product"
title = "Widget"
description = "A widget."
@app.get("/products/widget")
def product():
return seo.for_entity(Product(), "/products/widget")
for_entity(entity, route) returns a plain dict, ready for a JSON response or
a template.
API¶
| Member | Description |
|---|---|
EaseoSEO(config) |
Wrap a config. Raises ValueError when it is None |
seo.config |
The wrapped config, for use with build_seo_payload |
seo.for_entity(entity, route) |
Build a payload and return it as a dict |
The adapter reads entity_type (defaulting to page), title, and
excerpt or description from the object it is given.
Async endpoints¶
The payload build is fast and releases the GIL. If you build many payloads in a request, or want to keep the event loop free, use the async builder:
from easeo import build_seo_payload_async
@app.get("/products/{slug}")
async def product(slug: str):
return (await build_seo_payload_async(product, f"/products/{slug}", config)).to_dict()
Patterns¶
Templates¶
Build the payload and pass render_html() to the template. See the
Jinja2 example.
ETag caching¶
Every payload has a deterministic hash, so it makes a perfect ETag. Return
304 when the client already has the current payload. See the
ETag example.
Troubleshooting¶
| Symptom | Cause |
|---|---|
ValueError: SEOConfig is required |
EaseoSEO was constructed with None |
for_entity cannot find a title |
The object lacks title or description attributes |
| Social preview has no image | No default_og_image and no entity image; see EASEO108 |