File size: 2,426 Bytes
a8d9eab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# cli.py
import argparse
import json
import sys
import uuid
from pathlib import Path
from rich.console import Console
from rich.panel import Panel
from pipeline.graph import build_graph
from models.state import AdWorkflowState
import config

console = Console()

def main():
    parser = argparse.ArgumentParser(description="Generate static Meta ads from a brand URL.")
    parser.add_argument("url", help="Brand website URL to scrape")
    parser.add_argument("--brief", default="", help="Optional freeform brief for the campaign")
    parser.add_argument("--output", default=config.OUTPUT_DIR, help="Output directory for ad PNGs")
    args = parser.parse_args()

    config.OUTPUT_DIR = args.output
    Path(args.output).mkdir(parents=True, exist_ok=True)

    console.print(Panel(
        f"[bold]URL:[/bold] {args.url}\n[bold]Brief:[/bold] {args.brief or '(none)'}",
        title="[cyan]Static Ad Generation Pipeline[/cyan]"
    ))

    initial_state: AdWorkflowState = {
        "url": args.url,
        "brief": args.brief,
        "raw_scrape": "",
        "brand_dna": None,
        "ad_angles": [],
        "copy_concepts": [],
        "image_prompts": [],
        "generated_images": [],
        "final_ads": [],
        "current_gate": 0,
        "human_feedback": "",
    }

    try:
        graph = build_graph()
        thread_config = {"configurable": {"thread_id": uuid.uuid4().hex}}
        final_state = graph.invoke(initial_state, config=thread_config)
    except Exception:
        console.print_exception()
        sys.exit(1)

    ads = final_state["final_ads"]
    console.print(f"\n[green]Done! Generated {len(ads)} ads.[/green]")
    for ad in ads:
        console.print(f"\n[bold]{ad.angle_name}[/bold]")
        console.print(f"  Headline: {ad.copy_concept.headline}")
        console.print(f"  Files: {ad.image_paths}")

    summary_path = Path(args.output) / "summary.json"
    try:
        summary_path.write_text(json.dumps(
            [{"angle": a.angle_name, "headline": a.copy_concept.headline,
              "body": a.copy_concept.body_copy, "cta": a.copy_concept.cta_text,
              "images": a.image_paths, "prompt": a.image_prompt}
             for a in ads],
            indent=2
        ))
        console.print(f"\nSummary written to [cyan]{summary_path}[/cyan]")
    except Exception:
        console.print_exception()
        sys.exit(1)

if __name__ == "__main__":
    main()