Reflex FastAPI Custom Endpoints
This skill covers building custom FastAPI endpoints within a Reflex application. Use it for logic that lives outside the Reflex state/event system: webhooks, external integrations, JWT auth, REST APIs for third-party consumers, etc.
For Reflex core (state, components, routing) → see skill reflex-core.
For visual design and aesthetics → see skill reflex-design.
FastAPI Custom Endpoints
Reflex exposes the underlying FastAPI server. Use it for custom endpoints outside of the Reflex state/event system (webhooks, external integrations, JWT auth, etc.).
Integration Pattern
app = rx.App()
# Access the underlying FastAPI server
fastapi_app = app.api
@fastapi_app.get("/api/health")
async def health_check():
return {"status": "ok"}
@fastapi_app.post("/api/webhook")
async def webhook(payload: MyPydanticModel):
return {"received": True}
Core Workflow
- Analyze requirements — Identify endpoints, data models, auth needs
- Design schemas — Create Pydantic V2 models for validation
- Implement — Write async endpoints with proper dependency injection
- Secure — Add authentication, authorization, rate limiting
- Test — Write async tests with pytest and httpx
Reference Guide
| Topic |
Load When |
| Pydantic V2 |
Creating schemas, validation, model_config |
| Async DB drivers |
asyncpg, aiomysql, models, CRUD operations using Raw SQL |
| Endpoints & Routing |
APIRouter, dependencies, routing |
| Authentication |
JWT, OAuth2, get_current_user |
| Testing |
pytest-asyncio, httpx, fixtures |
MUST DO
- Use type hints everywhere (FastAPI requires them)
- Use Pydantic V2 syntax (
field_validator, model_validator, model_config)
- Use
Annotated pattern for dependency injection
- Use
async/await for all I/O operations
- Use
X | None instead of Optional[X]
- Return proper HTTP status codes
- Document endpoints (auto-generated OpenAPI)
MUST NOT DO
- Use synchronous database operations
- Skip Pydantic validation
- Store passwords in plain text
- Expose sensitive data in responses
- Use Pydantic V1 syntax (
@validator, class Config)
- Mix sync and async code improperly
- Hardcode configuration values
Pydantic V2 Schema Example
from pydantic import BaseModel, field_validator, ConfigDict
from typing import Annotated
class UserCreate(BaseModel):
model_config = ConfigDict(str_strip_whitespace=True)
name: str
email: str
age: int | None = None
@field_validator("email")
@classmethod
def validate_email(cls, v: str) -> str:
if "@" not in v:
raise ValueError("Invalid email")
return v.lower()
Output Templates
When implementing FastAPI features, provide:
- Schema file (Pydantic models)
- Endpoint file (router with endpoints)
- CRUD operations if database involved
- Brief explanation of key decisions
Testing FastAPI Endpoints (httpx)
import pytest
from httpx import AsyncClient, ASGITransport
from my_app.my_app import app
@pytest.mark.asyncio
async def test_health_check():
async with AsyncClient(
transport=ASGITransport(app=app.api), base_url="http://test"
) as client:
response = await client.get("/api/health")
assert response.status_code == 200
assert response.json()["status"] == "ok"
@pytest.mark.asyncio
async def test_endpoint_validation_error():
async with AsyncClient(
transport=ASGITransport(app=app.api), base_url="http://test"
) as client:
response = await client.post("/api/users", json={"name": ""})
assert response.status_code == 422
References
1---2name: reflex-fastapi3description: Guide for building custom FastAPI endpoints within Reflex applications. Use when creating webhooks, external API integrations, JWT authentication, or any endpoint that lives outside the Reflex state/event system. Covers integration pattern, Pydantic V2 schemas, async endpoints, dependency injection, security rules, and endpoint testing with httpx.4---5
6# Reflex FastAPI Custom Endpoints
7
8This skill covers building custom FastAPI endpoints within a Reflex application. Use it for logic that lives outside the Reflex state/event system: webhooks, external integrations, JWT auth, REST APIs for third-party consumers, etc.
9
10For Reflex core (state, components, routing) → see skill `reflex-core`.
11For visual design and aesthetics → see skill `reflex-design`.
12
13---
14
15## FastAPI Custom Endpoints
16
17Reflex exposes the underlying FastAPI server. Use it for custom endpoints outside of the Reflex state/event system (webhooks, external integrations, JWT auth, etc.).
18
19### Integration Pattern
20
21```python
22app = rx.App()
23
24# Access the underlying FastAPI server
25fastapi_app = app.api
26
27@fastapi_app.get("/api/health")
28async def health_check():
29 return {"status": "ok"}
30
31@fastapi_app.post("/api/webhook")
32async def webhook(payload: MyPydanticModel):
33 return {"received": True}
34```
35
36### Core Workflow
37
381. **Analyze requirements** — Identify endpoints, data models, auth needs
392. **Design schemas** — Create Pydantic V2 models for validation
403. **Implement** — Write async endpoints with proper dependency injection
414. **Secure** — Add authentication, authorization, rate limiting
425. **Test** — Write async tests with pytest and httpx
43
44### Reference Guide
45
46| Topic | Load When |
47|-------|-----------|
48| Pydantic V2 | Creating schemas, validation, model_config |
49| Async DB drivers | asyncpg, aiomysql, models, CRUD operations using Raw SQL |
50| Endpoints & Routing | APIRouter, dependencies, routing |
51| Authentication | JWT, OAuth2, get_current_user |
52| Testing | pytest-asyncio, httpx, fixtures |
53
54### MUST DO
55- Use type hints everywhere (FastAPI requires them)
56- Use Pydantic V2 syntax (`field_validator`, `model_validator`, `model_config`)
57- Use `Annotated` pattern for dependency injection
58- Use `async/await` for all I/O operations
59- Use `X | None` instead of `Optional[X]`
60- Return proper HTTP status codes
61- Document endpoints (auto-generated OpenAPI)
62
63### MUST NOT DO
64- Use synchronous database operations
65- Skip Pydantic validation
66- Store passwords in plain text
67- Expose sensitive data in responses
68- Use Pydantic V1 syntax (`@validator`, `class Config`)
69- Mix sync and async code improperly
70- Hardcode configuration values
71
72### Pydantic V2 Schema Example
73
74```python
75from pydantic import BaseModel, field_validator, ConfigDict
76from typing import Annotated
77
78class UserCreate(BaseModel):
79 model_config = ConfigDict(str_strip_whitespace=True)
80
81 name: str
82 email: str
83 age: int | None = None
84
85 @field_validator("email")
86 @classmethod
87 def validate_email(cls, v: str) -> str:
88 if "@" not in v:
89 raise ValueError("Invalid email")
90 return v.lower()
91```
92
93### Output Templates
94
95When implementing FastAPI features, provide:
961. Schema file (Pydantic models)
972. Endpoint file (router with endpoints)
983. CRUD operations if database involved
994. Brief explanation of key decisions
100
101---
102
103## Testing FastAPI Endpoints (httpx)
104
105```python
106import pytest
107from httpx import AsyncClient, ASGITransport
108from my_app.my_app import app
109
110@pytest.mark.asyncio
111async def test_health_check():
112 async with AsyncClient(
113 transport=ASGITransport(app=app.api), base_url="http://test"
114 ) as client:
115 response = await client.get("/api/health")
116 assert response.status_code == 200
117 assert response.json()["status"] == "ok"
118
119@pytest.mark.asyncio
120async def test_endpoint_validation_error():
121 async with AsyncClient(
122 transport=ASGITransport(app=app.api), base_url="http://test"
123 ) as client:
124 response = await client.post("/api/users", json={"name": ""})
125 assert response.status_code == 422
126```
127
128---
129
130## References
131
132- FastAPI Docs: https://fastapi.tiangolo.com/
133- Pydantic V2 Docs: https://docs.pydantic.dev/latest/