meme-backend / env.example
shaileshrv1432's picture
Upload 64 files
8deb9dd verified
Raw
History Blame Contribute Delete
5.53 kB
# =============================================================================
# env.example (committed template — copy to .env and fill in real values)
# Mirrors the keys used in production. See docs/ACCOUNTS_AND_SERVICES.md for
# where to obtain each value, and DEPLOYMENT.md for the deploy steps.
# =============================================================================
## OpenAI (meme caption suggestions) -- REQUIRED
OPENAI_API_KEY=your-openai-api-key
## Giphy (GIF search) -- REQUIRED
GIPHY_API_KEY=your-giphy-api-key
## Tenor (GIF search) -- OPTIONAL (leave blank; Giphy covers search)
TENOR_API_KEY=
# auto = use GPT-4o vision when OPENAI_API_KEY is set, else fall back to local BLIP.
# Options: auto | openai | huggingface
GIF_SUGGESTION_ENGINE=auto
# Local BLIP fallback model. Keep in sync with the checkpoint baked in the Dockerfile.
BLIP_MODEL=Salesforce/blip-image-captioning-base
## Freemium limits -- OPTIONAL (sensible defaults applied if unset)
# Master switch for monetization gates (daily meme cap + premium-only formats).
# Keep false until the app's subscription UI is enabled, or free users get capped
# with no way to upgrade. Abuse/cost rate limits below stay active regardless.
FREEMIUM_ENABLED=false
# Free users: max saved memes per day (premium = unlimited).
FREE_DAILY_MEMES=10
# Hourly cap on AI suggestion/caption calls, per user, by tier.
FREE_AI_PER_HOUR=30
PREMIUM_AI_PER_HOUR=200
# Per-minute cap on keyword GIF search / trending, per user.
GIF_SEARCH_PER_MINUTE=60
# Output formats reserved for paying users (comma-separated).
PREMIUM_ONLY_FORMATS=mp4
# Watermark free-tier exports (virality + upgrade incentive). Premium never watermarked.
WATERMARK_ENABLED=false
WATERMARK_TEXT=Meme Jockey
## GIF export performance -- OPTIONAL (tune if saves feel slow)
# Cap/subsample frames of long GIFs (0 = unlimited). ~48 keeps saves snappy.
MEME_MAX_FRAMES=0
# Cap the longest side in pixels before encoding (0 = no limit). e.g. 720.
MEME_MAX_DIM=0
# Floyd-Steinberg dithering on GIF frames. 0 = off (faster, slight banding).
MEME_GIF_DITHER=1
## POSTGRESQL -- REQUIRED
# Local dev (docker/podman compose):
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=memes_dev
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
# Managed Postgres (e.g. Neon) — use the asyncpg-compatible SSL param:
# DATABASE_URL=postgresql://user:pass@host/dbname?ssl=require
## Guest Account Configuration
GUEST_MODE_ENABLED=false
GUEST_PHONE_NUMBER=+10000000000
GUEST_OTP_CODE=000000
GUEST_TOKEN_TTL_SECONDS=3600
GUEST_DATA_QUOTA_MB=200
GUEST_DATA_RETENTION_HOURS=24
## Fast2SMS (OTP delivery via SMS) -- OPTIONAL
# Leave blank: OTP is printed to logs ([DEV SMS] to=… otp=…) instead of texted,
# so login still works in dev (read the code from the logs). If SET, the key must
# be valid AND the Fast2SMS wallet funded / account KYC-complete, or sends fail
# with HTTP 502 "Couldn't send the OTP" and login breaks. See auth/sms_provider.py.
FAST2SMS_API_KEY=
# Most Indian Fast2SMS accounts must use the DLT template route (the bare "otp"
# route returns HTTP 400 unless explicitly enabled). Set BOTH from your approved
# DLT template to send real OTP SMS; leave blank to try the plain otp route.
# FAST2SMS_SENDER_ID = your approved 3-6 char DLT header/sender ID
# FAST2SMS_DLT_TEMPLATE_ID = the numeric ID of your approved OTP template
# The template must have one variable for the code, e.g.
# "Your Meme Jockey OTP is {#var#}. Do not share it."
FAST2SMS_SENDER_ID=
FAST2SMS_DLT_TEMPLATE_ID=
# Debug aid: when true, /auth/request-otp returns the raw Fast2SMS error to the
# client (e.g. invalid key / no balance). Keep FALSE in production.
OTP_DEBUG=false
## Object storage — MinIO (local) or any S3-compatible (e.g. Backblaze B2) -- REQUIRED
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_SECURE=false
MINIO_BUCKET=memes-dev
# MinIO root creds (local dev only!)
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
## Auth / JWT -- REQUIRED (generate long random strings)
JWT_SECRET=change-me-256-bit-secret
JWT_REFRESH_SECRET=change-me-another-secret
JWT_ISS=meme-be
JWT_AUD=app
ACCESS_TTL_SECONDS=900
REFRESH_TTL_SECONDS=2592000
ARGON2_PEPPER=optional-static-pepper
## Google Sign-In -- OPTIONAL (OAuth 2.0 Web client ID; token audience)
GOOGLE_WEB_CLIENT_ID=
## Razorpay (subscriptions) -- REQUIRED for in-app purchases (optional otherwise)
# Test-mode keys look like rzp_test_...; live keys rzp_live_... (live needs a
# KYC-activated account). Both id + secret MUST come from the same key pair and
# the same mode, or Razorpay rejects them with "Authentication failed".
# Verify config without a full checkout: GET /subscriptions/config-check
# curl -H "X-Admin-Secret: <ADMIN_SECRET>" https://<host>/subscriptions/config-check
RAZORPAY_KEY_ID=
RAZORPAY_KEY_SECRET=
# Debug aid: when true, /subscriptions/order returns the raw Razorpay error to
# the client so payment failures can be diagnosed from the app. Keep FALSE in
# production (real users would see raw internals).
PAYMENTS_DEBUG=false
## Environment
APP_ENV=development
ADMIN_SECRET=change-me-admin-secret
# Set CONTAINER_ENV=true when running in Docker/HF Space if APP_ENV isn't
# "production" — switches the DB engine to the asyncpg driver. Optional.
CONTAINER_ENV=false
## API Configuration
API_BASE_URL=http://localhost:8000