Skip to content

JavierPachas/fastapi4ai

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fastapi4ai

A minimal FastAPI service backed by Google Gemini (google-genai).

It exposes a /chat endpoint that forwards prompts to Gemini, with the AI provider hidden behind a small abstraction (AIPlatform) so other backends can be added later.

Project structure

src/
├── main.py              # FastAPI app and routes
├── ai/
│   ├── base.py          # AIPlatform abstract base class
│   └── gemini.py        # Gemini implementation (google-genai Client)
├── auth/
│   ├── dependencies.py  # JWT-based user identification (optional Bearer token)
│   └── throttling.py    # in-memory per-user rate limiting
└── prompts/
    └── system_prompt.md # system prompt prepended to every request

Setup

Requires Python 3.11+.

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Dependency versions are pinned in requirements.txt for reproducible installs.

Configuration

Required. A .env file is mandatory — the app reads its configuration from it on startup and will refuse to start if the required variables are missing (it raises ValueError for an unset GEMINI_API_KEY or JWT_SECRET_KEY). The .env file is gitignored, so every clone must create its own:

cp .env.example .env
# then edit .env and fill in the required values (see the table below)

Get a Gemini API key from https://aistudio.google.com/apikey

Variable Required Default Description
GEMINI_API_KEY yes Google Gemini API key.
GEMINI_MODEL no gemini-2.5-flash Model used for generation.
JWT_SECRET_KEY yes Secret used to verify JWTs on /chat.
JWT_ALGORITHM no HS256 Signing algorithm for JWT verification.

Without a valid .env (or the equivalent environment variables exported), the server will not start. The two yes variables above have no defaults by design.

Run

Run from the project root so uvicorn can import the src package. The app loads .env and the system prompt by paths relative to its own source, so they resolve regardless of the current directory — and no manual environment export is needed (python-dotenv handles it on startup):

source .venv/bin/activate
uvicorn src.main:app --reload

The API is then available at http://127.0.0.1:8000 (interactive docs at /docs).

Endpoints

GET /

Liveness check.

curl http://127.0.0.1:8000/
# {"message":"API is running."}

POST /chat

Send a prompt to Gemini and get the generated text back. The system prompt in src/prompts/system_prompt.md is prepended automatically.

Request body

{ "prompt": "Say hello in three languages." }

Response body

{ "response": "..." }

Authentication & rate limiting

The Authorization header is optional:

  • No token — requests are treated as a shared anonymous user, limited to 3 requests / 60s across all callers.
  • Valid JWT (HS256) — requests are limited per user (the token's sub claim) to 5 requests / 60s.
  • Invalid token401 Unauthorized.

Exceeding the limit returns 429 Too Many Requests.

Example (anonymous)

curl -X POST http://127.0.0.1:8000/chat \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Say hello in three languages."}'

Example (authenticated)

Pass a JWT in the Authorization: Bearer header. For testing you can generate a token at https://www.jwt.io/ — use the HS256 algorithm with the secret from your JWT_SECRET_KEY env var and a payload with a sub claim (the user id). Only sub is read by the app; other claims are ignored. Example payload used for testing:

{
  "sub": "testuser",
  "name": "Santa Claus",
  "iat": 1516239022
}
curl -X POST "http://127.0.0.1:8000/chat" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer *****************************************" \
  -d '{"prompt": "Why is the ocean blue?"}'

Sample response

{
  "response": "The ocean is blue because of how water absorbs and scatters sunlight ☀️🌊. Water absorbs red and yellow light more than blue light 🔴🟡. So, the blue light bounces around and gets scattered back to our eyes ✨💙!"
}

The emoji-rich, plaintext style comes from the system prompt in src/prompts/system_prompt.md.

Returns 503 if Gemini is temporarily unavailable.

About

Minimal FastAPI service exposing a /chat endpoint backed by Google Gemini, with a pluggable AI-provider abstraction, optional JWT auth, and per-user rate limiting.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages