Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/AI_Brain_backend / main.py |
| Date | Not specified in source |
| Repository | Janady13/AI_Brain_backend |
| Revision | 829ca9d7ab37c117e0a3fa6bef8ae7b168ec9a83 |
| Branch | main |
| Path or archive member | main.py |
| Original SHA-256 | 60497210045fbe6ac9235c3b3e7af2e10f1dbd4b4d912b37df42a5d2045f90b9 |
| Git blob SHA | 723426acb1748a65f982f24f62e3a1910abedf75 |
| Reading-copy SHA-256 | 60497210045fbe6ac9235c3b3e7af2e10f1dbd4b4d912b37df42a5d2045f90b9 |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/AI_Brain_backend / main.py | main | 829ca9d7ab37c117e0a3fa6bef8ae7b168ec9a83 | Open original |
| Janady13/AI_Brain_backend / main.py | codex/create-a-plan | 9d138024d285d68964e939aa3799010089883aa3 | Open original |
Recovered source transcript
Download complete source text ↓179 lines · 6.0 KB
import os, uuid, asyncpg, stripe, httpx
from fastapi import FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
app = FastAPI()
def _parse_cors_allowlist(env_value: str | None) -> list[str]:
if not env_value:
return []
return [origin.strip() for origin in env_value.split(",") if origin.strip()]
CORS_ALLOWED_ORIGINS = _parse_cors_allowlist(os.getenv("CORS_ALLOWED_ORIGINS"))
app.add_middleware(
CORSMiddleware,
allow_origins=CORS_ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# --- ENV ---
DATABASE_URL = os.getenv("DATABASE_URL")
# Stripe
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
STRIPE_PRICE_ID_PRO = os.getenv("STRIPE_PRICE_ID_PRO")
STRIPE_PRICE_ID_STUDIO = os.getenv("STRIPE_PRICE_ID_STUDIO")
# PayPal
PAYPAL_ENV = os.getenv("PAYPAL_ENV", "sandbox")
PAYPAL_CLIENT_ID = os.getenv("PAYPAL_CLIENT_ID")
PAYPAL_CLIENT_SECRET = os.getenv("PAYPAL_CLIENT_SECRET")
PAYPAL_BASE = "https://api-m.paypal.com" if PAYPAL_ENV == "live" else "https://api-m.sandbox.paypal.com"
# Square
SQUARE_ENV = os.getenv("SQUARE_ENV", "sandbox")
SQUARE_ACCESS_TOKEN = os.getenv("SQUARE_ACCESS_TOKEN")
SQUARE_LOCATION_ID = os.getenv("SQUARE_LOCATION_ID")
SQUARE_API = "https://connect.squareup.com" if SQUARE_ENV=="production" else "https://connect.squareupsandbox.com"
SQUARE_VERSION = "2025-05-15"
# --- Startup/shutdown DB pool ---
@app.on_event("startup")
async def startup():
if DATABASE_URL:
app.state.pool = await asyncpg.create_pool(DATABASE_URL)
@app.on_event("shutdown")
async def shutdown():
if hasattr(app.state, "pool"):
await app.state.pool.close()
# --- Models ---
class MusicRequest(BaseModel):
prompt: str
class PlanBody(BaseModel):
plan: str
amount: float | None = None
class CaptureBody(BaseModel):
order_id: str
# --- Helpers ---
async def paypal_access_token():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{PAYPAL_BASE}/v1/oauth2/token",
data={"grant_type":"client_credentials"},
auth=(PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET),
timeout=15
)
if r.status_code != 200:
raise HTTPException(500, f"PayPal token error: {r.text}")
return r.json()["access_token"]
PLAN_AMOUNTS = {
"pro": "19.00",
"studio": "49.00",
}
def _validate_plan(plan: str) -> str:
if plan in PLAN_AMOUNTS:
return plan
raise HTTPException(400, f"Unsupported plan '{plan}'")
def plan_amount_usd(plan: str, override: float | None) -> str:
_validate_plan(plan)
if override is not None:
return f"{override:.2f}"
return PLAN_AMOUNTS[plan]
# --- API ---
@app.get("/api/status")
async def status():
return {
"ok": True,
"db": bool(DATABASE_URL),
"stripe": bool(stripe.api_key),
"paypal": bool(PAYPAL_CLIENT_ID),
"square": bool(SQUARE_ACCESS_TOKEN),
}
@app.post("/api/music/generate")
async def generate_music(req: MusicRequest):
if not hasattr(app.state,"pool"): return {"error":"no DB"}
async with app.state.pool.acquire() as conn:
track_id = await conn.fetchval("INSERT INTO tracks(prompt,status) VALUES($1,$2) RETURNING id", req.prompt,"processing")
return {"track_id": track_id, "status": "processing"}
@app.get("/tracks")
async def list_tracks():
if not hasattr(app.state,"pool"): return []
async with app.state.pool.acquire() as conn:
rows = await conn.fetch("SELECT id,prompt,status,created_at FROM tracks ORDER BY id DESC LIMIT 100")
return [dict(r) for r in rows]
# --- Stripe ---
@app.post("/checkout")
async def checkout(body: PlanBody):
plan = _validate_plan(body.plan)
price_id_map = {
"pro": STRIPE_PRICE_ID_PRO,
"studio": STRIPE_PRICE_ID_STUDIO,
}
price_id = price_id_map.get(plan)
if not price_id:
raise HTTPException(500, f"Stripe price ID missing for plan '{plan}'")
session = stripe.checkout.Session.create(
mode="subscription",
line_items=[{"price": price_id,"quantity":1}],
success_url="http://localhost:3000/success",
cancel_url="http://localhost:3000/cancel"
)
return {"url": session.url}
# --- PayPal (Venmo) ---
@app.post("/paypal/create-order")
async def paypal_create_order(body: PlanBody):
amount = plan_amount_usd(body.plan, body.amount)
token = await paypal_access_token()
payload = {"intent":"CAPTURE","purchase_units":[{"amount":{"currency_code":"USD","value":amount}}]}
async with httpx.AsyncClient() as client:
r = await client.post(f"{PAYPAL_BASE}/v2/checkout/orders",json=payload,headers={"Authorization":f"Bearer {token}"},timeout=15)
if r.status_code not in (200,201): raise HTTPException(500,r.text)
return r.json()
@app.post("/paypal/capture-order")
async def paypal_capture_order(body: CaptureBody):
token = await paypal_access_token()
async with httpx.AsyncClient() as client:
r = await client.post(f"{PAYPAL_BASE}/v2/checkout/orders/{body.order_id}/capture",headers={"Authorization":f"Bearer {token}"},timeout=15)
if r.status_code not in (200,201): raise HTTPException(500,r.text)
return r.json()
# --- Square (Cash App Pay) ---
@app.post("/square/create-payment-link")
async def square_create_payment_link(body: PlanBody):
import httpx
amount = plan_amount_usd(body.plan, body.amount)
payload = {
"idempotency_key": str(uuid.uuid4()),
"quick_pay": {
"name": f"AI Music {body.plan.capitalize()}",
"price_money": {"amount": int(float(amount)*100), "currency": "USD"},
"location_id": SQUARE_LOCATION_ID,
}
}
headers = {"Authorization":f"Bearer {SQUARE_ACCESS_TOKEN}","Square-Version":SQUARE_VERSION}
async with httpx.AsyncClient() as client:
r = await client.post(f"{SQUARE_API}/v2/online-checkout/payment-links",json=payload,headers=headers,timeout=15)
if r.status_code not in (200,201): raise HTTPException(500,r.text)
return r.json()