arpit13 commited on
Commit
dd0b18e
·
verified ·
1 Parent(s): c56c2a0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +488 -0
app.py ADDED
@@ -0,0 +1,488 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AI Image Creator: Enhanced UI and UX
2
+ # Part 3: Processing Logic, Prompt Enhancement, and Application Flow
3
+
4
+ # =============== PROMPT ENHANCEMENT LOGIC ===============
5
+
6
+ # Function to enhance prompt with Llama 4 with improved logical understanding
7
+ def enhance_prompt_with_llama(user_input, creation_type, art_style, mood):
8
+ """
9
+ Enhance user input with Llama 4 model to create detailed image generation prompts
10
+
11
+ Args:
12
+ user_input (str): User's original description
13
+ creation_type (str): Selected creation type (e.g., "Digital Art")
14
+ art_style (str): Selected art style (e.g., "Photorealistic")
15
+ mood (str): Selected mood (e.g., "Peaceful")
16
+
17
+ Returns:
18
+ str: Enhanced prompt optimized for image generation
19
+ """
20
+ try:
21
+ if not use_llama or llama_client is None:
22
+ logger.warning("Llama enhancement not available, using fallback")
23
+ return enhance_prompt_fallback(user_input, creation_type, art_style, mood)
24
+
25
+ logger.info(f"Enhancing prompt with Llama 4 for creation type: {creation_type}, art style: {art_style}")
26
+
27
+ # Enhanced Llama 4 system prompt with detailed instructions
28
+ system_prompt = """You are a world-class prompt engineer who specializes in creating detailed, effective prompts for text-to-image AI models.
29
+
30
+ Your task is to transform a user's simple description into a comprehensive, detailed image generation prompt that will create stunning visuals. Consider all the provided elements (description, creation type, art style, mood) and combine them into a cohesive, detailed prompt.
31
+
32
+ MOST IMPORTANTLY - ADD LOGICAL DETAILS:
33
+ - Analyze what the user wants and add logical details that would make the scene realistic or coherent
34
+ - If describing something fantastical (e.g., "flying cat"), add logical details about how this could work (e.g., "a cat with majestic feathered wings spread wide")
35
+ - Think about environment, lighting, perspective, time of day, weather, and other contextual elements
36
+ - Create a vivid, imaginable scene with spatial relationships clearly defined
37
+
38
+ PROMPT STRUCTURE GUIDELINES:
39
+ 1. Start with the core subject and its primary characteristics
40
+ 2. Add environment and setting details
41
+ 3. Describe lighting, atmosphere, and mood
42
+ 4. Include specific visual style and artistic technique references
43
+ 5. Add technical quality terms (8K, detailed, masterful, etc.)
44
+
45
+ FORMAT YOUR RESPONSE AS A SINGLE PARAGRAPH with no additional comments, explanations, or bullet points. Use natural language without awkward comma separations. Aim for 75-150 words.
46
+
47
+ AVOID:
48
+ - Do not include quotation marks in your response
49
+ - Do not preface with "here's a prompt" or similar text
50
+ - Do not use placeholders
51
+ - Do not add negative prompts
52
+ - Do not write in list format or use bullet points
53
+
54
+ Respond only with the enhanced prompt and nothing else."""
55
+
56
+ # Get creation type description
57
+ creation_info = CREATION_TYPES.get(creation_type, {"description": "Create a detailed image", "icon": "🎨"})
58
+ creation_description = creation_info["description"]
59
+
60
+ # Get art style description
61
+ style_info = ART_STYLES.get(art_style, {"description": "with detailed and professional quality", "icon": "🖌️"})
62
+ style_description = style_info["description"]
63
+
64
+ # Get mood description
65
+ mood_info = MOODS.get(mood, {"description": "atmospheric", "icon": "✨"})
66
+ mood_description = mood_info["description"]
67
+
68
+ # Prepare the user prompt for Llama
69
+ user_prompt = f"""Description: {user_input}
70
+ Creation Type: {creation_type} - {creation_description}
71
+ Art Style: {art_style} - {style_description}
72
+ Mood: {mood} - {mood_description}
73
+
74
+ Please create a comprehensive, detailed image generation prompt that combines all these elements."""
75
+
76
+ try:
77
+ # Request enhancement from Llama 4
78
+ completion = llama_client.chat.completions.create(
79
+ model="meta-llama/Llama-4-Scout-17B-16E-Instruct",
80
+ messages=[
81
+ {"role": "system", "content": system_prompt},
82
+ {"role": "user", "content": user_prompt}
83
+ ],
84
+ max_tokens=500,
85
+ temperature=0.7, # Slight creativity while maintaining coherence
86
+ )
87
+ enhanced = completion.choices[0].message.content
88
+ logger.info(f"Llama 4 enhanced prompt: {enhanced[:100]}...")
89
+ return enhanced if enhanced else user_input
90
+ except Exception as e:
91
+ logger.error(f"Error during Llama enhancement: {str(e)}")
92
+ return enhance_prompt_fallback(user_input, creation_type, art_style, mood)
93
+ except Exception as e:
94
+ logger.error(f"Error in Llama enhancement: {str(e)}")
95
+ return enhance_prompt_fallback(user_input, creation_type, art_style, mood)
96
+
97
+ # Fallback prompt enhancement without Llama
98
+ def enhance_prompt_fallback(user_input, creation_type, art_style, mood):
99
+ """
100
+ Enhance user input without requiring Llama API using rule-based enhancement
101
+
102
+ Args:
103
+ user_input (str): User's original description
104
+ creation_type (str): Selected creation type (e.g., "Digital Art")
105
+ art_style (str): Selected art style (e.g., "Photorealistic")
106
+ mood (str): Selected mood (e.g., "Peaceful")
107
+
108
+ Returns:
109
+ str: Enhanced prompt using predefined rules and templates
110
+ """
111
+ logger.info(f"Using fallback enhancement for: {user_input[:50]}...")
112
+
113
+ # Quality terms by creation type
114
+ quality_terms = {
115
+ "Realistic Photo": [
116
+ "photorealistic", "high resolution", "detailed",
117
+ "natural lighting", "sharp focus", "professional photography",
118
+ "crisp details", "realistic textures", "DSLR photo"
119
+ ],
120
+ "Digital Art": [
121
+ "vibrant colors", "clean lines", "digital illustration",
122
+ "polished", "professional digital art", "detailed rendering",
123
+ "digital painting", "colorful", "vector-like precision"
124
+ ],
125
+ "Fantasy Illustration": [
126
+ "magical atmosphere", "fantasy art", "detailed illustration",
127
+ "epic", "otherworldly", "imaginative scene",
128
+ "fantasy environment", "magical lighting", "mythical qualities"
129
+ ],
130
+ "Concept Art": [
131
+ "professional concept art", "detailed design", "conceptual illustration",
132
+ "industry standard", "visual development", "production artwork",
133
+ "concept design", "detailed environment", "character design"
134
+ ],
135
+ "Anime/Manga": [
136
+ "anime style", "manga illustration", "cel shaded",
137
+ "Japanese animation", "2D character art", "anime aesthetic",
138
+ "clean linework", "anime proportions", "stylized features"
139
+ ],
140
+ "Oil Painting": [
141
+ "oil on canvas", "textured brushwork", "rich colors",
142
+ "traditional painting", "artistic brushstrokes", "gallery quality",
143
+ "glazed layers", "impasto technique", "classical painting style"
144
+ ],
145
+ "Watercolor": [
146
+ "watercolor painting", "soft color bleeding", "delicate washes",
147
+ "transparent layers", "loose brushwork", "gentle transitions",
148
+ "watercolor paper texture", "wet-on-wet technique", "fluid color blending"
149
+ ],
150
+ "Sketch": [
151
+ "detailed sketch", "pencil drawing", "line art",
152
+ "hand-drawn", "fine details", "shading techniques",
153
+ "graphite", "charcoal texture", "gestural lines"
154
+ ],
155
+ "3D Rendering": [
156
+ "3D render", "volumetric lighting", "ray tracing",
157
+ "3D modeling", "realistic textures", "computer graphics",
158
+ "physically based rendering", "global illumination", "ambient occlusion"
159
+ ],
160
+ "Pixel Art": [
161
+ "pixel art", "8-bit style", "retro game aesthetic",
162
+ "limited color palette", "pixelated", "nostalgic game art",
163
+ "16-bit look", "pixel perfect", "dithering effects"
164
+ ]
165
+ }
166
+
167
+ # Style modifiers for different art styles - more detailed descriptions
168
+ style_modifiers = {
169
+ "Photorealistic": "highly detailed photorealistic style with perfect lighting, natural shadows, and lifelike textures",
170
+ "Impressionist": "impressionist style with visible brushstrokes capturing light and atmosphere over precise details, reminiscent of Claude Monet",
171
+ "Surrealist": "surrealist style with dreamlike and impossible elements, juxtaposed reality, inspired by Salvador Dali",
172
+ "Pop Art": "pop art style with bold colors, sharp lines, halftone patterns and cultural references, like Andy Warhol",
173
+ "Minimalist": "minimalist style with simplified forms, limited color palette, clean composition, and essential elements only",
174
+ "Abstract": "abstract style using non-representational shapes, colors, and forms to express emotion rather than reality",
175
+ "Cubist": "cubist style with geometric forms, multiple perspectives shown simultaneously, fractured surfaces, like Pablo Picasso",
176
+ "Art Nouveau": "art nouveau style with ornate flowing lines inspired by natural forms, decorative elegance, and organic shapes",
177
+ "Gothic": "gothic style with dark atmosphere, dramatic elements, pointed arches, and medieval-inspired architecture",
178
+ "Cyberpunk": "cyberpunk style with neon colors, high tech low life aesthetic, futuristic technology, and urban decay",
179
+ "Steampunk": "steampunk style with Victorian aesthetics, brass machinery, steam-powered technology, and retrofuturistic design",
180
+ "Retro/Vintage": "retro style with nostalgic elements from past decades, aged texture, and period-appropriate colors and design",
181
+ "Art Deco": "art deco style with geometric patterns, bold colors, symmetry, luxurious materials, and streamlined forms",
182
+ "Baroque": "baroque style with dramatic lighting, rich details, contrast, dynamic composition, and ornate decorations",
183
+ "Ukiyo-e": "ukiyo-e style Japanese woodblock print aesthetic with flat areas of color, strong outlines, and traditional subjects",
184
+ "Comic Book": "comic book style with bold outlines, vibrant colors, dynamic action poses, and expressive characters",
185
+ "Psychedelic": "psychedelic style with vibrant swirling colors, abstract patterns, distorted perspective, and 1960s-inspired visuals",
186
+ "Vaporwave": "vaporwave aesthetic with glitch art, pastel colors, 80s/90s nostalgia, ancient statues, and digital elements",
187
+ "Studio Ghibli": "Studio Ghibli anime style with whimsical detailed environments, soft colors, and charming character design",
188
+ "Hyperrealism": "hyperrealistic style with extreme detail beyond photography, perfect textures, and meticulous precision"
189
+ }
190
+
191
+ # Mood modifiers for different moods - enhanced descriptions
192
+ mood_modifiers = {
193
+ "Happy": "bright cheerful atmosphere with warm golden lighting, vibrant colors, and uplifting elements",
194
+ "Sad": "melancholic atmosphere with muted colors, soft shadows, and somber emotional tone",
195
+ "Mysterious": "enigmatic atmosphere with shadows, fog, hidden elements, and dramatic lighting contrasts",
196
+ "Peaceful": "serene calm atmosphere with gentle lighting, soft colors, and tranquil composition",
197
+ "Tense": "suspenseful atmosphere with dramatic lighting, stark contrasts, and unsettling composition",
198
+ "Whimsical": "playful whimsical atmosphere with imaginative elements, saturated colors, and fantastical details",
199
+ "Dark": "dark gloomy atmosphere with deep shadows, limited lighting, and ominous elements",
200
+ "Energetic": "dynamic vibrant atmosphere with strong colors, motion effects, and active composition",
201
+ "Romantic": "soft romantic atmosphere with dreamy lighting, gentle colors, and intimate ambiance",
202
+ "Epic": "grand epic atmosphere with dramatic scale, sweeping vistas, and majestic lighting"
203
+ }
204
+
205
+ # Get terms for the specific creation type, or use generic terms
206
+ type_terms = quality_terms.get(creation_type, [
207
+ "high quality", "detailed", "professional", "masterful", "high resolution", "sharp details"
208
+ ])
209
+
210
+ # Common quality terms enhanced with trending and technical terms
211
+ common_terms = [
212
+ "8K resolution", "highly detailed", "professional", "masterpiece",
213
+ "trending on artstation", "award winning", "stunning", "intricate details",
214
+ "perfect composition", "cinematic lighting"
215
+ ]
216
+
217
+ # Get style modifier
218
+ style_modifier = style_modifiers.get(art_style, "detailed professional style")
219
+
220
+ # Get mood modifier
221
+ mood_modifier = mood_modifiers.get(mood, "atmospheric")
222
+
223
+ # Basic prompt structure - core subject and style elements
224
+ prompt_parts = [
225
+ user_input,
226
+ style_modifier,
227
+ mood_modifier
228
+ ]
229
+
230
+ # Add randomly selected quality terms for variety
231
+ selected_type_terms = random.sample(type_terms, min(3, len(type_terms)))
232
+ selected_common_terms = random.sample(common_terms, min(3, len(common_terms)))
233
+
234
+ # Combine terms
235
+ quality_description = ", ".join(selected_type_terms + selected_common_terms)
236
+
237
+ # Final enhanced prompt
238
+ enhanced_prompt = f"{', '.join(prompt_parts)}, {quality_description}"
239
+
240
+ logger.info(f"Fallback enhanced prompt: {enhanced_prompt[:100]}...")
241
+ return enhanced_prompt
242
+
243
+ # =============== IMAGE GENERATION FUNCTIONS ===============
244
+
245
+ # Generate image function with loading state handling and retry mechanism
246
+ def generate_image(description, creation_type, art_style, mood, model_name, retries=1):
247
+ """
248
+ Generate image based on user inputs by enhancing prompt and calling image model API
249
+
250
+ Args:
251
+ description (str): User's original description
252
+ creation_type (str): Selected creation type
253
+ art_style (str): Selected art style
254
+ mood (str): Selected mood
255
+ model_name (str): Model identifier
256
+ retries (int): Number of retries if generation fails
257
+
258
+ Returns:
259
+ tuple: (image, status_message, enhanced_prompt)
260
+ """
261
+ try:
262
+ # Validate input
263
+ if not description.strip():
264
+ return None, "Please enter a description for your image", ""
265
+
266
+ logger.info(f"Generating image with model: {model_name}")
267
+
268
+ # Enhance prompt with Llama or fallback
269
+ enhanced_prompt = enhance_prompt_with_llama(description, creation_type, art_style, mood)
270
+
271
+ # Validate client availability
272
+ if hf_client is None:
273
+ logger.error("Hugging Face client not available")
274
+ return None, "Error: Unable to connect to image generation service. Please try again later.", enhanced_prompt
275
+
276
+ # Add negative prompt to avoid common issues
277
+ negative_prompt = "low quality, blurry, distorted, deformed, disfigured, bad anatomy, watermark, signature, text, poorly drawn, amateur, ugly"
278
+
279
+ try:
280
+ # Generate image with progress tracking
281
+ logger.info(f"Sending request to model {model_name} with prompt: {enhanced_prompt[:100]}...")
282
+
283
+ # Log start time for performance tracking
284
+ start_time = time.time()
285
+
286
+ # Generate the image
287
+ image = hf_client.text_to_image(
288
+ prompt=enhanced_prompt,
289
+ model=model_name,
290
+ negative_prompt=negative_prompt
291
+ )
292
+
293
+ # Calculate generation time
294
+ generation_time = time.time() - start_time
295
+ logger.info(f"Image generated successfully in {generation_time:.2f} seconds")
296
+
297
+ # Success message with generation details
298
+ if use_llama:
299
+ enhancement_method = "Llama 4 AI"
300
+ else:
301
+ enhancement_method = "rule-based enhancement"
302
+
303
+ success_message = f"Image created successfully in {generation_time:.1f}s using {model_name.split('/')[-1]} model and {enhancement_method}"
304
+
305
+ return image, success_message, enhanced_prompt
306
+
307
+ except Exception as e:
308
+ error_message = str(e)
309
+ logger.error(f"Error during image generation: {error_message}")
310
+
311
+ # Retry logic for transient errors
312
+ if retries > 0:
313
+ logger.info(f"Retrying image generation, {retries} attempts remaining")
314
+ time.sleep(1) # Small delay before retry
315
+ return generate_image(description, creation_type, art_style, mood, model_name, retries - 1)
316
+
317
+ # Format user-friendly error message
318
+ if "429" in error_message:
319
+ friendly_error = "Server is currently busy. Please try again in a few moments."
320
+ elif "401" in error_message or "403" in error_message:
321
+ friendly_error = "Authentication error with the image service. Please check API settings."
322
+ elif "timeout" in error_message.lower():
323
+ friendly_error = "Request timed out. The server might be under heavy load."
324
+ else:
325
+ friendly_error = f"Error generating image: {error_message}"
326
+
327
+ return None, friendly_error, enhanced_prompt
328
+ except Exception as e:
329
+ logger.error(f"Unexpected error in generate_image: {str(e)}")
330
+ return None, f"Unexpected error: {str(e)}", ""
331
+
332
+ # Wrapper function for generate_image with status updates
333
+ def generate_with_status(description, creation_type_val, art_style_val, mood_val, model_name):
334
+ """
335
+ Wrapper for generate_image that handles UI status updates and parameter formatting
336
+
337
+ Args:
338
+ description (str): User's original description
339
+ creation_type_val (str): Formatted creation type with icon
340
+ art_style_val (str): Formatted art style with icon
341
+ mood_val (str): Formatted mood with icon
342
+ model_name (str): Formatted model name with icon
343
+
344
+ Returns:
345
+ tuple: (image, status_html, enhanced_prompt, parameters_html)
346
+ """
347
+ # Check if description is empty
348
+ if not description.strip():
349
+ return None, update_status("Please enter a description", is_error=True), "", ""
350
+
351
+ # Extract keys from formatted values
352
+ creation_key = extract_key(creation_type_val)
353
+ art_key = extract_key(art_style_val)
354
+ mood_key = extract_key(mood_val)
355
+
356
+ # Get model key from formatted name
357
+ model_key = None
358
+ for key, info in IMAGE_MODELS.items():
359
+ if f"{info['icon']} {info['display_name']}" == model_name:
360
+ model_key = key
361
+ break
362
+
363
+ if not model_key:
364
+ return None, update_status("Invalid model selection", is_error=True), "", ""
365
+
366
+ try:
367
+ # Generate the image
368
+ image, message, enhanced_prompt = generate_image(
369
+ description, creation_key, art_key, mood_key, model_key
370
+ )
371
+
372
+ if image is None:
373
+ return None, update_status(message, is_error=True), "", ""
374
+
375
+ # Format parameters display
376
+ params_html = format_parameters(creation_type_val, art_style_val, mood_val, model_name)
377
+
378
+ # Success message
379
+ success_message = update_status(message)
380
+ return image, success_message, enhanced_prompt, params_html
381
+
382
+ except Exception as e:
383
+ error_message = str(e)
384
+ logger.error(f"Error in generate_with_status: {error_message}")
385
+ return None, update_status(f"Error: {error_message}", is_error=True), "", ""
386
+
387
+ # =============== MAIN APPLICATION FLOW ===============
388
+
389
+ def main():
390
+ """
391
+ Main application entry point - creates UI and sets up event handlers
392
+ """
393
+ # Create the UI components
394
+ interface, description_input, creation_type, art_style, mood_dropdown, model_selector, generate_button, image_output, generation_status, prompt_output, parameters_display, char_counter, creation_info, art_info, model_info = create_ui()
395
+
396
+ # Set up event handlers
397
+
398
+ # Character counter update
399
+ description_input.change(
400
+ fn=update_char_count,
401
+ inputs=description_input,
402
+ outputs=char_counter
403
+ )
404
+
405
+ # Creation type info update
406
+ creation_type.change(
407
+ fn=update_creation_info,
408
+ inputs=creation_type,
409
+ outputs=creation_info
410
+ )
411
+
412
+ # Art style info update
413
+ art_style.change(
414
+ fn=update_art_style_info,
415
+ inputs=art_style,
416
+ outputs=art_info
417
+ )
418
+
419
+ # Model info update
420
+ model_selector.change(
421
+ fn=update_model_info,
422
+ inputs=model_selector,
423
+ outputs=model_info
424
+ )
425
+
426
+ # Generate button click handler
427
+ generate_button.click(
428
+ fn=generate_with_status,
429
+ inputs=[
430
+ description_input,
431
+ creation_type,
432
+ art_style,
433
+ mood_dropdown,
434
+ model_selector
435
+ ],
436
+ outputs=[
437
+ image_output,
438
+ generation_status,
439
+ prompt_output,
440
+ parameters_display
441
+ ]
442
+ )
443
+
444
+ # Load default values on page load
445
+ def load_defaults():
446
+ creation_val = f"{CREATION_TYPES['Digital Art']['icon']} Digital Art"
447
+ art_val = f"{ART_STYLES['Photorealistic']['icon']} Photorealistic"
448
+ model_val = f"{IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['icon']} {IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['display_name']}"
449
+
450
+ creation_info = update_creation_info(creation_val)
451
+ art_info = update_art_style_info(art_val)
452
+ model_info = update_model_info(model_val)
453
+
454
+ return creation_info, art_info, model_info
455
+
456
+ # Load defaults when the interface loads
457
+ interface.load(
458
+ fn=load_defaults,
459
+ outputs=[creation_info, art_info, model_info]
460
+ )
461
+
462
+ # Launch the interface with theme and analytics disabled for privacy
463
+ interface.launch(
464
+ share=False, # Set to True to create a public link
465
+ debug=False, # Set to True for development
466
+ enable_queue=True, # Enable request queue for better handling under load
467
+ )
468
+
469
+ # =============== APP EXECUTION ===============
470
+
471
+ if __name__ == "__main__":
472
+ # Install dependencies if needed
473
+ try:
474
+ import pkg_resources
475
+ required_packages = ['huggingface_hub', 'gradio', 'pillow']
476
+ for package in required_packages:
477
+ try:
478
+ pkg_resources.get_distribution(package)
479
+ except pkg_resources.DistributionNotFound:
480
+ logger.info(f"Installing required package: {package}")
481
+ import subprocess
482
+ subprocess.check_call(['pip', 'install', package])
483
+ logger.info(f"Successfully installed {package}")
484
+ except Exception as e:
485
+ logger.warning(f"Error checking or installing dependencies: {str(e)}")
486
+
487
+ # Start the application
488
+ main()