Spaces:
Running
Running
Architecture
Overview
Meme Jockey is a two-part system: a FastAPI backend that does image/GIF processing + auth + storage, and a React Native mobile app.
βββββββββββββββββββββββ HTTPS / JSON Β· form-encoded ββββββββββββββββββββββββββββ
β Mobile app (RN) β ββββββββββββββββββββββββββββββββββββββββΆ β FastAPI backend β
β Android (0.80) β Bearer JWT on every protected call β (Hugging Face Space, β
β β ββββββββββββββββββββββββββββββββββββββββ β Docker, port 8000) β
βββββββββββββββββββββββ ββββββββββββββ¬ββββββββββββββ
β
βββββββββββββββββββββββββ¬βββββββββββββββΌββββββββββββββββ
βΌ βΌ βΌ βΌ
ββββββββββββββ ββββββββββββββββ βββββββββββββ ββββββββββββββ
β PostgreSQL β β Object store β β OpenAI β β Giphy β
β (Neon) β β (Backblaze β β (captions)β β (GIF search)β
β users, β β B2 / MinIO) β βββββββββββββ ββββββββββββββ
β otps, β β uploads + β
β media, β β generated β
β subs β β memes β
ββββββββββββββ ββββββββββββββββ
Backend layout (backend/)
| Path | Responsibility |
|---|---|
main.py |
App wiring, middleware, meme/media/profile/admin endpoints |
routers/auth.py |
OTP, PIN, refresh, Google login, profile (/auth/*) |
routers/subscriptions.py |
Razorpay order/verify/status, receipts, history, PDF, config-check (/subscriptions/*) |
utils/receipt.py |
Renders a payment receipt as a PDF (Pillow-only) |
auth/security.py |
JWT mint/verify, phone normalize, hashing, guest config |
auth/deps.py |
current_user_id dependency (Bearer β user id) |
auth/sms_provider.py, utils/sms_fast2sms.py |
OTP delivery (Fast2SMS, or log) |
utils/ai_overlay.py |
OpenAI suggestions + Giphy/Tenor search |
utils/storage_minio.py |
S3-compatible put/get/presign |
db/postgres_client.py |
All DB access (asyncpg + SQLAlchemy), per-request session |
db/database.py |
Engine/driver selection from env |
db/models.py |
SQLAlchemy models (users, otps, media_assets, β¦) |
db/init.sql |
Schema bootstrap (run in Neon SQL editor) |
db/supabase_client.pyis legacy/unused β the app usespostgres_client.
Data model (key tables)
- users β
id,phone_e164(unique key; Google users keyedgoogle:<sub>),name,email,avatar_url,pin_hash,is_active,is_guest,account_type, and subscription fields:subscription_plan(defaultfree),subscription_status(defaultinactive),subscription_expires_at. - otps β hashed OTPs with
expires_at/consumed. - media_assets β
object_key,content_type,kind(upload|meme), owner. - memes β links inputβoutput assets +
format; drives daily-quota counts. - payments β one row per successful Razorpay payment (
plan,amountpaise,currency,status,method,razorpay_order_id,razorpay_payment_id,expires_at). Powers the receipt PDF and transaction history.
Request auth flow
- App calls
/auth/request-otpβ/auth/verify-otpβ getsaccess+refresh. - App stores tokens; an axios interceptor adds
Authorization: Bearer <access>. - On
401, the interceptor calls/auth/refreshonce and retries; if that fails, the session-expired handler logs the user out. - Returning users can
/auth/set-pinthen/auth/login-pinto skip OTP. - Guests (
GUEST_MODE_ENABLED) get a short-lived guest session and skip PIN.
Meme generation flow
POST /upload(image) β stored in object storage + initial suggestions.- App opens the editor; user places GIF/image overlays.
POST /compose/layoutwith the JSON layout β server renders the meme, stores it (kind=meme), returnsobject_key+ URL.GET /memeslists creations;GET /memes/{object_key}serves them via a permanent cached proxy URL.
Deployment
- Backend β Hugging Face Space (Docker,
app_port: 8000). Push to the Space repo to rebuild. Secrets/Variables set in Space settings. - Database β Neon (run
db/init.sqlonce; re-run after schema changes β it's idempotentadd column if not exists). - Object storage β Backblaze B2 (S3-compatible) with a bucket-scoped Read+Write app key.
- See DEPLOYMENT.md and ACCOUNTS_AND_SERVICES.md.