Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import openai | |
| from openai import OpenAI | |
| import os | |
| # Initialize OpenAI client - for Hugging Face Spaces | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| if not api_key: | |
| raise ValueError("OPENAI_API_KEY not found in environment variables. Please set it in the Space secrets.") | |
| # Debug: Print first few characters to verify format (remove this after testing) | |
| print(f"API Key format check: {api_key[:10]}...") | |
| client = OpenAI(api_key=api_key) | |
| def generate_business_concept(item1, item2, market1, market2): | |
| """ | |
| Generate a business concept using two items and two target markets | |
| """ | |
| # Validate inputs | |
| if not all([item1, item2, market1, market2]): | |
| return "Please provide all four inputs: two items and two target markets." | |
| # System prompt that defines the GPT's behavior | |
| system_prompt = """1. Generate three distinct business ideas.\n | |
| 2. For each idea:\n" | |
| a. Write exactly two sentences describing a business that uses or sells both items as a coherent product or service.\n" | |
| b. Write exactly one sentence describing a hybrid target market that merges the needs and interests of both customer segments.\n" | |
| 3. Provide no additional commentary, explanations, or text beyond this.\n" | |
| 4. Use the following output format for each idea:\n" | |
| - First two sentences: The business concept\n" | |
| - Third sentence: The hybrid target market" | |
| Provide no additional commentary, explanations, or text beyond this.""" | |
| # User message with the inputs | |
| user_message = f"Items: {item1}, {item2}\nTarget Markets: {market1}, {market2}" | |
| try: | |
| # Call OpenAI API | |
| response = client.chat.completions.create( | |
| model="gpt-3.5-turbo", | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_message} | |
| ], | |
| temperature=0.7, | |
| max_tokens=200 | |
| ) | |
| return response.choices[0].message.content.strip() | |
| except Exception as e: | |
| return f"Error generating concept: {str(e)}" | |
| # Create Gradio interface with mobile-first design | |
| def create_interface(): | |
| with gr.Blocks( | |
| title="Business Concept Generator", | |
| theme=gr.themes.Default(), | |
| css=""" | |
| /* Fix viewport and scrolling */ | |
| body { | |
| overflow-x: hidden !important; | |
| -webkit-overflow-scrolling: touch !important; | |
| } | |
| /* Main container should be scrollable */ | |
| .gradio-container { | |
| max-width: 100% !important; | |
| padding: 10px !important; | |
| min-height: 100vh !important; | |
| overflow-y: auto !important; | |
| overflow-x: hidden !important; | |
| } | |
| /* Ensure the app container is scrollable */ | |
| #root, .app { | |
| height: auto !important; | |
| min-height: 100vh !important; | |
| overflow-y: auto !important; | |
| } | |
| /* Compact header */ | |
| h1 { | |
| font-size: 20px !important; | |
| margin: 5px 0 10px 0 !important; | |
| line-height: 1.2 !important; | |
| } | |
| /* Make inputs touch-friendly but compact */ | |
| input[type="text"], textarea { | |
| font-size: 16px !important; /* Prevents zoom on iOS */ | |
| padding: 8px !important; | |
| width: 100% !important; | |
| box-sizing: border-box !important; | |
| } | |
| /* Compact form spacing */ | |
| .gr-form { | |
| gap: 5px !important; | |
| } | |
| .gr-textbox { | |
| margin-bottom: 8px !important; | |
| } | |
| /* Smaller labels */ | |
| label { | |
| font-size: 14px !important; | |
| margin-bottom: 2px !important; | |
| } | |
| /* Style the button for mobile */ | |
| .gr-button { | |
| width: 100% !important; | |
| min-height: 44px !important; | |
| font-size: 16px !important; | |
| font-weight: bold !important; | |
| -webkit-appearance: none !important; | |
| appearance: none !important; | |
| touch-action: manipulation !important; | |
| margin: 10px 0 !important; | |
| position: relative !important; | |
| z-index: 10 !important; | |
| } | |
| /* Output box styling */ | |
| #output-box { | |
| margin-top: 10px !important; | |
| margin-bottom: 20px !important; | |
| } | |
| /* Ensure content doesn't get cut off */ | |
| .contain { | |
| overflow: visible !important; | |
| } | |
| /* Add padding at bottom for scrolling */ | |
| .gradio-container > :last-child { | |
| padding-bottom: 100px !important; | |
| } | |
| /* Force single column on mobile */ | |
| @media (max-width: 768px) { | |
| .gr-row { | |
| flex-direction: column !important; | |
| } | |
| .gr-column { | |
| width: 100% !important; | |
| } | |
| } | |
| /* Hide examples on very small screens */ | |
| @media (max-width: 375px) { | |
| .gr-accordion { | |
| display: none !important; | |
| } | |
| } | |
| """ | |
| ) as demo: | |
| # Add viewport meta tag for proper mobile rendering | |
| gr.HTML(""" | |
| <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"> | |
| """) | |
| gr.Markdown("# Business Concept Generator") | |
| # All inputs in a single column | |
| item1 = gr.Textbox( | |
| label="Item 1", | |
| placeholder="First item", | |
| lines=1 | |
| ) | |
| item2 = gr.Textbox( | |
| label="Item 2", | |
| placeholder="Second item", | |
| lines=1 | |
| ) | |
| market1 = gr.Textbox( | |
| label="Target Market 1", | |
| placeholder="First market", | |
| lines=1 | |
| ) | |
| market2 = gr.Textbox( | |
| label="Target Market 2", | |
| placeholder="Second market", | |
| lines=1 | |
| ) | |
| generate_btn = gr.Button( | |
| "Generate Concept", | |
| variant="primary" | |
| ) | |
| output = gr.Textbox( | |
| label="Business Concept", | |
| lines=4, | |
| interactive=False, | |
| elem_id="output-box" | |
| ) | |
| # Handle button click | |
| generate_btn.click( | |
| fn=generate_business_concept, | |
| inputs=[item1, item2, market1, market2], | |
| outputs=output, | |
| scroll_to_output=True # This helps scroll to output on mobile | |
| ) | |
| # Add some space at the bottom | |
| gr.HTML("<div style='height: 50px;'></div>") | |
| return demo | |
| # Main execution | |
| if __name__ == "__main__": | |
| # Create and launch the interface | |
| demo = create_interface() | |
| demo.launch() |