|  | 
| 2 | 2 | 
 | 
| 3 | 3 | ## Introduction | 
| 4 | 4 | 
 | 
| 5 |  | -This section includes a complete example showing how to integrate Redis OM with FastAPI. | 
|  | 5 | +Good news: Redis OM was specifically designed to integrate with FastAPI! | 
| 6 | 6 | 
 | 
| 7 |  | -Good news: Redis OM was **specifically designed to integrate with FastAPI**! | 
|  | 7 | +This section includes a complete example showing how to integrate Redis OM with FastAPI. | 
| 8 | 8 | 
 | 
| 9 | 9 | ## Concepts | 
| 10 | 10 | 
 | 
| @@ -131,4 +131,89 @@ Get a copy of the value for "pk" and make another request to get that customer: | 
| 131 | 131 | You can also get a list of all customer PKs: | 
| 132 | 132 | 
 | 
| 133 | 133 |     $ curl "http://localhost:8000/customers" | 
| 134 |  | -    {"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]} | 
|  | 134 | +    {"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]} | 
|  | 135 | + | 
|  | 136 | +## Redsi OM with Asyncio | 
|  | 137 | + | 
|  | 138 | +Redis OM is designed to work with asyncio, so you can use Redis OM models asynchronously within FastAPI applications. | 
|  | 139 | + | 
|  | 140 | +The only difference is that you import the Redis OM models from the `aredis_om` module instead of the `redis_om` module. | 
|  | 141 | + | 
|  | 142 | +Here is the previous FastAPI app, but using asyncio-compatible Redis OM code: | 
|  | 143 | + | 
|  | 144 | +```python | 
|  | 145 | +import datetime | 
|  | 146 | +from typing import Optional | 
|  | 147 | + | 
|  | 148 | +import aioredis | 
|  | 149 | + | 
|  | 150 | +from fastapi import FastAPI, HTTPException | 
|  | 151 | +from starlette.requests import Request | 
|  | 152 | +from starlette.responses import Response | 
|  | 153 | + | 
|  | 154 | +from fastapi_cache import FastAPICache | 
|  | 155 | +from fastapi_cache.backends.redis import RedisBackend | 
|  | 156 | +from fastapi_cache.decorator import cache | 
|  | 157 | + | 
|  | 158 | +from pydantic import EmailStr | 
|  | 159 | + | 
|  | 160 | +from aredis_om import HashModel, NotFoundError  # <- Notice, we import from aredis_om | 
|  | 161 | +from aredis_om import get_redis_connection | 
|  | 162 | + | 
|  | 163 | +# This Redis instance is tuned for durability. | 
|  | 164 | +REDIS_DATA_URL = "redis://localhost:6380" | 
|  | 165 | + | 
|  | 166 | +# This Redis instance is tuned for cache performance. | 
|  | 167 | +REDIS_CACHE_URL = "redis://localhost:6381" | 
|  | 168 | + | 
|  | 169 | + | 
|  | 170 | +class Customer(HashModel): | 
|  | 171 | +    first_name: str | 
|  | 172 | +    last_name: str | 
|  | 173 | +    email: EmailStr | 
|  | 174 | +    join_date: datetime.date | 
|  | 175 | +    age: int | 
|  | 176 | +    bio: Optional[str] | 
|  | 177 | + | 
|  | 178 | + | 
|  | 179 | +app = FastAPI() | 
|  | 180 | + | 
|  | 181 | + | 
|  | 182 | +@app.post("/customer") | 
|  | 183 | +async def save_customer(customer: Customer): | 
|  | 184 | +    # We can save the model to Redis by calling `save()`: | 
|  | 185 | +    return await customer.save()  # <- We use await here | 
|  | 186 | + | 
|  | 187 | + | 
|  | 188 | +@app.get("/customers") | 
|  | 189 | +async def list_customers(request: Request, response: Response): | 
|  | 190 | +    # To retrieve this customer with its primary key, we use `Customer.get()`: | 
|  | 191 | +    return {"customers": await Customer.all_pks()}  # <- We also use await here | 
|  | 192 | + | 
|  | 193 | + | 
|  | 194 | +@app.get("/customer/{pk}") | 
|  | 195 | +@cache(expire=10) | 
|  | 196 | +async def get_customer(pk: str, request: Request, response: Response): | 
|  | 197 | +    # To retrieve this customer with its primary key, we use `Customer.get()`: | 
|  | 198 | +    try: | 
|  | 199 | +        return await Customer.get(pk)  # <- And, finally, one more await! | 
|  | 200 | +    except NotFoundError: | 
|  | 201 | +        raise HTTPException(status_code=404, detail="Customer not found") | 
|  | 202 | + | 
|  | 203 | + | 
|  | 204 | +@app.on_event("startup") | 
|  | 205 | +async def startup(): | 
|  | 206 | +    r = aioredis.from_url(REDIS_CACHE_URL, encoding="utf8", | 
|  | 207 | +                          decode_responses=True) | 
|  | 208 | +    FastAPICache.init(RedisBackend(r), prefix="fastapi-cache") | 
|  | 209 | + | 
|  | 210 | +    # You can set the Redis OM URL using the REDIS_OM_URL environment | 
|  | 211 | +    # variable, or by manually creating the connection using your model's | 
|  | 212 | +    # Meta object. | 
|  | 213 | +    Customer.Meta.database = get_redis_connection(url=REDIS_DATA_URL, | 
|  | 214 | +                                                  decode_responses=True) | 
|  | 215 | +``` | 
|  | 216 | + | 
|  | 217 | +**NOTE:** The modules `redis_om` and `aredis_om` are identical in almost every | 
|  | 218 | +way. The only difference is that the `aredis_om` returns coroutines that you must | 
|  | 219 | +`await`. | 
0 commit comments