AI-powered women's health companion backend for the AmaniCare AI hackathon. Built with FastAPI, SQLAlchemy 2.0, and Deepseek AI, with Africa's Talking USSD webhook support.
- User registration and profile management
- AI health advice via Deepseek (personalized by age, life stage, language)
- Africa's Talking USSD session flow (register + ask health questions)
- Mock SMS reminder scheduler (period, medication, pregnancy, menopause)
- Clean architecture: routes → services → repositories
- Async endpoints, Pydantic v2 validation, Loguru logging
- OpenAPI docs at
/docs - Docker-ready deployment
| Layer | Technology |
|---|---|
| Framework | FastAPI + Uvicorn |
| Python | 3.12 |
| ORM | SQLAlchemy 2.0 (async) |
| Migrations | Alembic |
| Database | PostgreSQL (production) / SQLite (dev) |
| AI | Deepseek API (httpx) |
| Logging | Loguru |
| Testing | pytest + pytest-asyncio |
backend/
├── app/
│ ├── main.py # FastAPI app, CORS, exception handlers
│ ├── core/ # Config, database, security
│ ├── models/ # SQLAlchemy ORM models
│ ├── schemas/ # Pydantic request/response models
│ ├── api/ # Route handlers (thin layer)
│ ├── services/ # Business logic
│ ├── repositories/ # Data access
│ └── utils/ # Prompt builder
├── alembic/ # Database migrations
├── tests/ # pytest test suite
├── requirements.txt
├── Dockerfile
└── .env.example
cd backendpython3.12 -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windowspip install -r requirements.txtcp .env.example .envEdit .env with your values:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL or SQLite connection string |
DEEPSEEK_API_KEY |
Deepseek API key |
DEEPSEEK_MODEL |
Deepseek model identifier |
DEEPSEEK_API_URL |
Deepseek API endpoint |
AFRICAS_TALKING_USERNAME |
Africa's Talking username |
AFRICAS_TALKING_API_KEY |
Africa's Talking API key |
AFRICAS_TALKING_SENDER_ID |
Africa's Talking SMS sender ID |
SECRET_KEY |
Application secret (change in production) |
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000- API: http://localhost:8000
- Swagger docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
For PostgreSQL or when you want explicit schema control:
# Apply migrations
alembic upgrade head
# Create a new migration after model changes
alembic revision --autogenerate -m "describe change"SQLite development uses auto-create on startup; Alembic is recommended for production.
- Get an API key from Deepseek.
- Set
DEEPSEEK_API_KEYin your.env - Optional: set
DEEPSEEK_MODEL(default:deepseek-default) - Optional: set
DEEPSEEK_API_URLif your Deepseek endpoint differs from the default.
The DeepseekService sends personalized prompts built from the user profile. It never diagnoses or prescribes — educational guidance only.
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check |
| POST | /api/users/register |
Register a user |
| GET | /api/users/{phone_number} |
Get user profile |
| PUT | /api/users/{phone_number} |
Update user profile |
| POST | /api/advice |
Ask AI health question |
| POST | /api/ussd |
Africa's Talking USSD webhook |
| POST | /api/reminders |
Schedule mock reminder |
| GET | /api/reminders/{phone_number} |
List user reminders |
curl http://localhost:8000/healthcurl -X POST http://localhost:8000/api/users/register \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+256700000000",
"name": "Grace",
"age": 23,
"life_stage": "Regular",
"language": "English"
}'curl http://localhost:8000/api/users/+256700000000curl -X POST http://localhost:8000/api/advice \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+256700000000",
"question": "I have severe period cramps."
}'# Welcome menu
curl -X POST http://localhost:8000/api/ussd \
-d "sessionId=abc123" \
-d "phoneNumber=+256700000000" \
-d "text=" \
-d "serviceCode=*384*123#"
# Start registration
curl -X POST http://localhost:8000/api/ussd \
-d "sessionId=abc123" \
-d "phoneNumber=+256700000000" \
-d "text=1" \
-d "serviceCode=*384*123#"curl -X POST http://localhost:8000/api/reminders \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+256700000000",
"type": "period",
"next_date": "2026-07-15"
}'Dial *384*123#
│
├─ 1 Register
│ ├─ Enter name
│ ├─ Enter age
│ ├─ Choose life stage (1–7)
│ └─ END: Registration complete
│
└─ 2 Ask Health Question
├─ Enter question
└─ END: AI advice
Life stages: Teen, Regular, TryingToConceive, Pregnant, Postpartum, Perimenopause, Menopause.
pytest -vTests cover health check, user registration, advice endpoint (Deepseek mocked), USSD flow, and reminders.
docker build -t mamacare-api .
docker run -p 8000:8000 \
-e DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/mamacare \
-e GOOGLE_API_KEY=your_key \
-e SECRET_KEY=your_secret \
mamacare-apiThe Next.js frontend at http://localhost:3000 is allowed by default. Configure additional origins via the cors_origins setting in app/core/config.py.
All errors return consistent JSON:
{
"success": false,
"message": "Human-readable error message"
}Hackathon MVP — MamaCare AI.