sushilideaclan01's picture
Restore changes from lost commit (excluding creativity_examples binaries for HF)
7067477
metadata
title: Amalfa Ad Creative Studio
emoji: 
colorFrom: pink
colorTo: yellow
sdk: docker
app_port: 7860

Amalfa Ad Creative Studio

Full-stack app: paste an Amalfa product page URL → scrape product data → run a deep marketing analysis (OpenAI) → generate 20 ad creative packages (product-focused + no-product) for Meta (Facebook/Instagram).

What it does

  1. Scrape – Fetches the product page and extracts name, description, price, images, brand, category (JSON-LD, meta tags, fallbacks).
  2. Analyze – GPT-based analysis: positioning, taglines, ideal customer, emotional triggers, price framing, ad angles, USPs, copy direction.
  3. Creatives – Generates 20 ad concepts (17 product-focused, 3 no-product) with headlines, body copy, image prompts, and layout notes.
  4. Generate ad images – Select any of the 50 creatives, pick a Replicate image model, and generate actual ad images from the prompts (via Replicate).

Setup

Backend (Python)

cd backend
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Create a .env file (copy from .env.example):

cp .env.example .env

Set your API keys in .env:

OPENAI_API_KEY=sk-your-key-here
REPLICATE_API_TOKEN=r8_your-replicate-token   # optional; for generating ad images
KIE_API_KEY=your-kie-key                      # optional; Kie.ai for nano-banana-pro (kie.ai/nano-banana-pro)

Get a Replicate token at https://replicate.com/account/api-tokens (needed only for the “Generate ads” feature).

Optional – save generated creatives to Cloudflare R2:
Set R2_ENDPOINT, R2_BUCKET_NAME, R2_ACCESS_KEY, and R2_SECRET_KEY in .env. When set, each generated ad image is uploaded to R2 and the API returns the R2 presigned URL (7-day expiry) instead of the temporary Replicate URL.

Run the API:

uvicorn app.main:app --reload --host 0.0.0.0 --port 8002

API docs: http://127.0.0.1:8002/docs

Frontend (React + Vite)

cd frontend
npm install
npm run dev

App: http://localhost:5174

The frontend is configured to proxy /api to http://127.0.0.1:8002, so run the backend first.

Creating a user (script only)

The app requires login. Create users with the script (no signup UI). Use the backend venv so dependencies are available:

# From repo root (use backend venv)
backend/.venv/bin/python backend/scripts/create_user.py --username admin --password yourpassword

Or from the backend directory (after activating the venv):

cd backend
source .venv/bin/activate   # Windows: .venv\Scripts\activate
python scripts/create_user.py -u admin -p yourpassword

Users are stored in backend/data/users.json. For production, set JWT_SECRET in .env to a long random string.

Usage

  1. Open http://localhost:5174 and sign in with a user created via the script above.
  2. Paste an Amalfa product URL (e.g. https://amalfa.in/products/amor-infinity-heart-ring-for-women)
  3. Click Generate
  4. Wait for scrape → analysis → creatives (about 1–2 minutes)
  5. Browse Product card, Marketing Analysis, and Ad Creatives (click a creative to expand copy + image prompt).
  6. Generate ad images: tick the checkboxes for the creatives you want, choose an image model (e.g. nano-banana, flux-2-max), click Generate ads. Generated images appear in a grid below (Replicate URLs may expire after a while).

API

  • POST /api/run – Body: { "url": "https://amalfa.in/products/..." }
    Returns: { product_data, analysis, creatives }
  • POST /api/scrape – Body: { "url": "..." }
    Returns: product data only
  • GET /api/image-models – Returns list of Replicate image models for ad generation
  • POST /api/generate-ads – Body: { "creatives": [ full creative JSON per item (id, concept_name, scene_prompt, ad_copy, etc.) ], "model_key": "nano-banana" }. The whole creative object is sent to the image model as the prompt.
    Returns: { "results": [{ "creative_id", "image_url", "error" }] }

Project layout

amalfa fr/
├── backend/
│   ├── app/
│   │   ├── main.py      # FastAPI app, /api/run, /api/scrape
│   │   ├── scraper.py   # Amalfa product page scraper
│   │   ├── llm.py       # OpenAI client, call_llm, extract_json
│   │   ├── analysis.py  # Deep product analysis prompt
│   │   ├── creatives.py        # Ad creative generation prompt
│   │   └── replicate_image.py  # Replicate image generation for selected creatives
│   ├── requirements.txt
│   └── .env.example
├── frontend/
│   ├── src/
│   │   ├── App.jsx      # URL input, run pipeline, Product / Analysis / Creatives UI
│   │   ├── main.jsx
│   │   └── index.css
│   ├── index.html
│   ├── package.json
│   └── vite.config.js   # proxy /api → backend
├── my_repo.md           # Original backend script (reference)
└── README.md

Deploy on Hugging Face

  1. Create a new Space at huggingface.co/new-space. Choose Docker as the SDK.
  2. Push this repo (or copy Dockerfile, README.md, and the backend/ and frontend/ folders) into the Space.
  3. Secrets (required for full features): In the Space → Settings → Repository secrets, add:
    • OPENAI_API_KEY – required for analysis and creatives
    • REPLICATE_API_TOKEN – required for “Generate ads” (Replicate image generation)
    • JWT_SECRET – optional; set a long random string for production
    • R2 (optional): R2_ACCESS_KEY, R2_SECRET_KEY, R2_BUCKET_NAME, R2_ENDPOINT – to store generated images in Cloudflare R2; also used to persist the gallery index so your gallery survives Space rebuilds/redeploys
  4. Reference images: Uploaded reference image URLs must be reachable by Replicate. Use the app URL (e.g. https://your-username-amalfa-creative-studio.hf.space), not the hub page (https://huggingface.co/spaces/...). You can set secret BASE_URL to that URL, or leave it unset — the app will use the request host when you open the Space via its .hf.space link. Reference files are stored under DATA_DIR (e.g. /tmp on Spaces), so they are lost if the Space restarts; upload again after a restart if needed.

The Docker image builds the React frontend and serves it from FastAPI. Default user is created from backend/data/users.json (e.g. admin – set its password via the create-user script before pushing, or change it in the repo).

Notes

  • OPENAI_API_KEY is required for analysis and creatives; scraping works without it.
  • REPLICATE_API_TOKEN is required only for “Generate ads” (image generation from selected creatives).
  • The backend uses gpt-4o-mini by default (set in llm.py). You can change the model there.
  • For production, set CORS allow_origins in backend/app/main.py to your frontend origin.