import gradio as gr import nexaapi import requests import json from io import BytesIO from PIL import Image def generate_journey_diagram( api_key: str, journey_title: str, steps_json: str, model: str, width: int, height: int ): """ Generate a user journey diagram using NexaAPI. Args: api_key: NexaAPI key from nexa-api.com journey_title: Title for the journey diagram steps_json: JSON string with steps data model: AI model to use width: Image width height: Image height Returns: PIL Image of the generated diagram """ if not api_key or api_key.strip() == "": return None, "❌ Please enter your NexaAPI key. Get one free at https://nexa-api.com" try: steps = json.loads(steps_json) except json.JSONDecodeError as e: return None, f"❌ Invalid JSON format: {e}" if not steps or len(steps) < 2: return None, "❌ Please provide at least 2 journey steps" # Build prompt steps_desc = " → ".join([ f"{s.get('name', 'Step')} ({s.get('users', 0):,} users)" for s in steps ]) drop_offs = [ f"{s.get('name', 'Step')}: {int(s.get('drop_off', 0) * 100)}% drop-off" for s in steps if s.get("drop_off", 0) > 0 ] prompt = ( f"Professional user journey funnel diagram titled '{journey_title}'. " f"Sequential steps: {steps_desc}. " f"Drop-off rates: {', '.join(drop_offs) if drop_offs else 'not specified'}. " "Clean modern flat design, gradient blue-to-green color scheme, " "white background, clear typography, directional arrows, " "user count labels, professional business style." ) try: client = nexaapi.Client(api_key=api_key.strip()) response = client.images.generate( model=model, prompt=prompt, width=width, height=height, num_images=1 ) image_url = response.data[0].url # Download image img_response = requests.get(image_url, timeout=30) img_response.raise_for_status() image = Image.open(BytesIO(img_response.content)) return image, f"✅ Generated successfully!\n🔗 URL: {image_url}" except Exception as e: return None, f"❌ Generation failed: {str(e)}\n\nMake sure your API key is valid at https://nexa-api.com" # Example journey data EXAMPLE_STEPS = json.dumps([ {"name": "Landing Page", "users": 10000, "drop_off": 0.35}, {"name": "Sign Up", "users": 6500, "drop_off": 0.20}, {"name": "Email Verified", "users": 5200, "drop_off": 0.15}, {"name": "First Action", "users": 4420, "drop_off": 0.10}, {"name": "Paid Conversion", "users": 3978, "drop_off": 0.00} ], indent=2) ECOMMERCE_STEPS = json.dumps([ {"name": "Homepage", "users": 50000, "drop_off": 0.60}, {"name": "Product Page", "users": 20000, "drop_off": 0.40}, {"name": "Add to Cart", "users": 12000, "drop_off": 0.50}, {"name": "Checkout", "users": 6000, "drop_off": 0.30}, {"name": "Purchase", "users": 4200, "drop_off": 0.00} ], indent=2) MOBILE_STEPS = json.dumps([ {"name": "App Install", "users": 5000, "drop_off": 0.20}, {"name": "Permissions", "users": 4000, "drop_off": 0.15}, {"name": "Account Setup","users": 3400, "drop_off": 0.10}, {"name": "Tutorial", "users": 3060, "drop_off": 0.08}, {"name": "First Use", "users": 2815, "drop_off": 0.00} ], indent=2) # Build Gradio interface with gr.Blocks( title="AI User Journey Generator", theme=gr.themes.Soft(), css=""" .header { text-align: center; padding: 20px; } .links { text-align: center; font-size: 14px; } """ ) as demo: gr.HTML("""
Generate beautiful user journey diagrams from your analytics data using AI
Inspired by Breadcrumb.ai on Product Hunt 🚀
🌐 nexa-api.com | 📦 PyPI | 📦 npm | 🔗 RapidAPI
Powered by NexaAPI — 38+ AI models, one API key