wappa 0.1.8__py3-none-any.whl → 0.1.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wappa might be problematic. Click here for more details.
- wappa/__init__.py +4 -5
- wappa/api/controllers/webhook_controller.py +5 -2
- wappa/api/dependencies/__init__.py +0 -5
- wappa/api/middleware/error_handler.py +4 -4
- wappa/api/middleware/owner.py +11 -5
- wappa/api/routes/webhooks.py +2 -2
- wappa/cli/__init__.py +1 -1
- wappa/cli/examples/init/.env.example +33 -0
- wappa/cli/examples/init/app/__init__.py +0 -0
- wappa/cli/examples/init/app/main.py +9 -0
- wappa/cli/examples/init/app/master_event.py +10 -0
- wappa/cli/examples/json_cache_example/.env.example +33 -0
- wappa/cli/examples/json_cache_example/app/__init__.py +1 -0
- wappa/cli/examples/json_cache_example/app/main.py +247 -0
- wappa/cli/examples/json_cache_example/app/master_event.py +455 -0
- wappa/cli/examples/json_cache_example/app/models/__init__.py +1 -0
- wappa/cli/examples/json_cache_example/app/models/json_demo_models.py +256 -0
- wappa/cli/examples/json_cache_example/app/scores/__init__.py +35 -0
- wappa/cli/examples/json_cache_example/app/scores/score_base.py +192 -0
- wappa/cli/examples/json_cache_example/app/scores/score_cache_statistics.py +256 -0
- wappa/cli/examples/json_cache_example/app/scores/score_message_history.py +187 -0
- wappa/cli/examples/json_cache_example/app/scores/score_state_commands.py +272 -0
- wappa/cli/examples/json_cache_example/app/scores/score_user_management.py +239 -0
- wappa/cli/examples/json_cache_example/app/utils/__init__.py +26 -0
- wappa/cli/examples/json_cache_example/app/utils/cache_utils.py +174 -0
- wappa/cli/examples/json_cache_example/app/utils/message_utils.py +251 -0
- wappa/cli/examples/openai_transcript/.gitignore +63 -4
- wappa/cli/examples/openai_transcript/app/__init__.py +0 -0
- wappa/cli/examples/openai_transcript/app/main.py +9 -0
- wappa/cli/examples/openai_transcript/app/master_event.py +62 -0
- wappa/cli/examples/openai_transcript/app/openai_utils/__init__.py +3 -0
- wappa/cli/examples/openai_transcript/app/openai_utils/audio_processing.py +89 -0
- wappa/cli/examples/redis_cache_example/.env.example +33 -0
- wappa/cli/examples/redis_cache_example/app/__init__.py +6 -0
- wappa/cli/examples/redis_cache_example/app/main.py +246 -0
- wappa/cli/examples/redis_cache_example/app/master_event.py +455 -0
- wappa/cli/examples/redis_cache_example/app/models/redis_demo_models.py +256 -0
- wappa/cli/examples/redis_cache_example/app/scores/__init__.py +35 -0
- wappa/cli/examples/redis_cache_example/app/scores/score_base.py +192 -0
- wappa/cli/examples/redis_cache_example/app/scores/score_cache_statistics.py +256 -0
- wappa/cli/examples/redis_cache_example/app/scores/score_message_history.py +187 -0
- wappa/cli/examples/redis_cache_example/app/scores/score_state_commands.py +272 -0
- wappa/cli/examples/redis_cache_example/app/scores/score_user_management.py +239 -0
- wappa/cli/examples/redis_cache_example/app/utils/__init__.py +26 -0
- wappa/cli/examples/redis_cache_example/app/utils/cache_utils.py +174 -0
- wappa/cli/examples/redis_cache_example/app/utils/message_utils.py +251 -0
- wappa/cli/examples/simple_echo_example/.env.example +33 -0
- wappa/cli/examples/simple_echo_example/app/__init__.py +7 -0
- wappa/cli/examples/simple_echo_example/app/main.py +191 -0
- wappa/cli/examples/simple_echo_example/app/master_event.py +230 -0
- wappa/cli/examples/wappa_full_example/.env.example +33 -0
- wappa/cli/examples/wappa_full_example/.gitignore +63 -4
- wappa/cli/examples/wappa_full_example/app/__init__.py +6 -0
- wappa/cli/examples/wappa_full_example/app/handlers/__init__.py +5 -0
- wappa/cli/examples/wappa_full_example/app/handlers/command_handlers.py +492 -0
- wappa/cli/examples/wappa_full_example/app/handlers/message_handlers.py +559 -0
- wappa/cli/examples/wappa_full_example/app/handlers/state_handlers.py +514 -0
- wappa/cli/examples/wappa_full_example/app/main.py +269 -0
- wappa/cli/examples/wappa_full_example/app/master_event.py +504 -0
- wappa/cli/examples/wappa_full_example/app/media/README.md +54 -0
- wappa/cli/examples/wappa_full_example/app/media/buttons/README.md +62 -0
- wappa/cli/examples/wappa_full_example/app/media/buttons/kitty.png +0 -0
- wappa/cli/examples/wappa_full_example/app/media/buttons/puppy.png +0 -0
- wappa/cli/examples/wappa_full_example/app/media/list/README.md +110 -0
- wappa/cli/examples/wappa_full_example/app/media/list/audio.mp3 +0 -0
- wappa/cli/examples/wappa_full_example/app/media/list/document.pdf +0 -0
- wappa/cli/examples/wappa_full_example/app/media/list/image.png +0 -0
- wappa/cli/examples/wappa_full_example/app/media/list/video.mp4 +0 -0
- wappa/cli/examples/wappa_full_example/app/models/__init__.py +5 -0
- wappa/cli/examples/wappa_full_example/app/models/state_models.py +434 -0
- wappa/cli/examples/wappa_full_example/app/models/user_models.py +303 -0
- wappa/cli/examples/wappa_full_example/app/models/webhook_metadata.py +327 -0
- wappa/cli/examples/wappa_full_example/app/utils/__init__.py +5 -0
- wappa/cli/examples/wappa_full_example/app/utils/cache_utils.py +502 -0
- wappa/cli/examples/wappa_full_example/app/utils/media_handler.py +516 -0
- wappa/cli/examples/wappa_full_example/app/utils/metadata_extractor.py +337 -0
- wappa/cli/main.py +14 -5
- wappa/core/__init__.py +18 -23
- wappa/core/config/settings.py +7 -5
- wappa/core/events/default_handlers.py +1 -1
- wappa/core/factory/wappa_builder.py +38 -25
- wappa/core/plugins/redis_plugin.py +1 -3
- wappa/core/plugins/wappa_core_plugin.py +7 -6
- wappa/core/types.py +12 -12
- wappa/core/wappa_app.py +10 -8
- wappa/database/__init__.py +3 -4
- wappa/domain/enums/messenger_platform.py +1 -2
- wappa/domain/factories/media_factory.py +5 -20
- wappa/domain/factories/message_factory.py +5 -20
- wappa/domain/factories/messenger_factory.py +2 -4
- wappa/domain/interfaces/cache_interface.py +7 -7
- wappa/domain/interfaces/media_interface.py +2 -5
- wappa/domain/models/media_result.py +1 -3
- wappa/domain/models/platforms/platform_config.py +1 -3
- wappa/messaging/__init__.py +9 -12
- wappa/messaging/whatsapp/handlers/whatsapp_media_handler.py +20 -22
- wappa/models/__init__.py +27 -35
- wappa/persistence/__init__.py +12 -15
- wappa/persistence/cache_factory.py +0 -1
- wappa/persistence/json/__init__.py +1 -1
- wappa/persistence/json/cache_adapters.py +37 -25
- wappa/persistence/json/handlers/state_handler.py +60 -52
- wappa/persistence/json/handlers/table_handler.py +51 -49
- wappa/persistence/json/handlers/user_handler.py +71 -55
- wappa/persistence/json/handlers/utils/file_manager.py +42 -39
- wappa/persistence/json/handlers/utils/key_factory.py +1 -1
- wappa/persistence/json/handlers/utils/serialization.py +13 -11
- wappa/persistence/json/json_cache_factory.py +4 -8
- wappa/persistence/json/storage_manager.py +66 -79
- wappa/persistence/memory/__init__.py +1 -1
- wappa/persistence/memory/cache_adapters.py +37 -25
- wappa/persistence/memory/handlers/state_handler.py +62 -52
- wappa/persistence/memory/handlers/table_handler.py +59 -53
- wappa/persistence/memory/handlers/user_handler.py +75 -55
- wappa/persistence/memory/handlers/utils/key_factory.py +1 -1
- wappa/persistence/memory/handlers/utils/memory_store.py +75 -71
- wappa/persistence/memory/handlers/utils/ttl_manager.py +59 -67
- wappa/persistence/memory/memory_cache_factory.py +3 -7
- wappa/persistence/memory/storage_manager.py +52 -62
- wappa/persistence/redis/cache_adapters.py +27 -21
- wappa/persistence/redis/ops.py +11 -11
- wappa/persistence/redis/redis_client.py +4 -6
- wappa/persistence/redis/redis_manager.py +12 -4
- wappa/processors/factory.py +5 -5
- wappa/schemas/factory.py +2 -5
- wappa/schemas/whatsapp/message_types/errors.py +3 -12
- wappa/schemas/whatsapp/validators.py +3 -3
- wappa/webhooks/__init__.py +17 -18
- wappa/webhooks/factory.py +3 -5
- wappa/webhooks/whatsapp/__init__.py +10 -13
- wappa/webhooks/whatsapp/message_types/audio.py +0 -4
- wappa/webhooks/whatsapp/message_types/document.py +1 -9
- wappa/webhooks/whatsapp/message_types/errors.py +3 -12
- wappa/webhooks/whatsapp/message_types/location.py +1 -21
- wappa/webhooks/whatsapp/message_types/sticker.py +1 -5
- wappa/webhooks/whatsapp/message_types/text.py +0 -6
- wappa/webhooks/whatsapp/message_types/video.py +1 -20
- wappa/webhooks/whatsapp/status_models.py +2 -2
- wappa/webhooks/whatsapp/validators.py +3 -3
- {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/METADATA +362 -8
- {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/RECORD +144 -80
- wappa/cli/examples/init/pyproject.toml +0 -7
- wappa/cli/examples/simple_echo_example/.python-version +0 -1
- wappa/cli/examples/simple_echo_example/pyproject.toml +0 -9
- {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/WHEEL +0 -0
- {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/entry_points.txt +0 -0
- {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Wappa Full Example - Main Application Entry Point
|
|
3
|
+
|
|
4
|
+
This is a comprehensive demonstration of the Wappa framework capabilities including:
|
|
5
|
+
- Complete message type handling with metadata extraction
|
|
6
|
+
- Interactive commands (/button, /list, /cta, /location) with state management
|
|
7
|
+
- Media relay functionality using media_id
|
|
8
|
+
- User tracking and analytics with Redis cache
|
|
9
|
+
- Welcome messages for first-time users
|
|
10
|
+
- Professional error handling and logging
|
|
11
|
+
|
|
12
|
+
SETUP REQUIRED:
|
|
13
|
+
1. Create a .env file with your WhatsApp Business API credentials:
|
|
14
|
+
WP_ACCESS_TOKEN=your_access_token_here
|
|
15
|
+
WP_PHONE_ID=your_phone_number_id_here
|
|
16
|
+
WP_BID=your_business_id_here
|
|
17
|
+
|
|
18
|
+
2. Set up Redis:
|
|
19
|
+
REDIS_URL=redis://localhost:6379
|
|
20
|
+
|
|
21
|
+
FEATURES DEMONSTRATED:
|
|
22
|
+
- Comprehensive webhook metadata extraction for all message types
|
|
23
|
+
- Interactive button demo with animal selection and media responses
|
|
24
|
+
- Interactive list demo with media file types
|
|
25
|
+
- CTA button linking to external documentation
|
|
26
|
+
- Location sharing with predefined coordinates
|
|
27
|
+
- State management with TTL (10 minute expiration)
|
|
28
|
+
- User profile caching and activity tracking
|
|
29
|
+
- First-time user welcome messages with instructions
|
|
30
|
+
|
|
31
|
+
USAGE:
|
|
32
|
+
- Direct Python: python -m app.main (from project root)
|
|
33
|
+
- FastAPI-style: uvicorn app.main:app --reload (from project root)
|
|
34
|
+
- uv run: uv run python -m app.main
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
from wappa import Wappa, __version__
|
|
38
|
+
from wappa.core.config.settings import settings
|
|
39
|
+
from wappa.core.logging import get_logger
|
|
40
|
+
|
|
41
|
+
logger = get_logger(__name__)
|
|
42
|
+
|
|
43
|
+
# Import our comprehensive WappaEventHandler implementation
|
|
44
|
+
from .master_event import WappaFullExampleHandler
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def validate_configuration() -> bool:
|
|
48
|
+
"""
|
|
49
|
+
Validate required configuration settings.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
True if configuration is valid, False otherwise
|
|
53
|
+
"""
|
|
54
|
+
missing_configs = []
|
|
55
|
+
|
|
56
|
+
if not settings.wp_access_token:
|
|
57
|
+
missing_configs.append("WP_ACCESS_TOKEN")
|
|
58
|
+
|
|
59
|
+
if not settings.wp_phone_id:
|
|
60
|
+
missing_configs.append("WP_PHONE_ID")
|
|
61
|
+
|
|
62
|
+
if not settings.wp_bid:
|
|
63
|
+
missing_configs.append("WP_BID")
|
|
64
|
+
|
|
65
|
+
if not settings.has_redis:
|
|
66
|
+
missing_configs.append("REDIS_URL")
|
|
67
|
+
|
|
68
|
+
if missing_configs:
|
|
69
|
+
logger.error(f"❌ Missing required configuration: {', '.join(missing_configs)}")
|
|
70
|
+
logger.error("💡 Create a .env file with the required credentials")
|
|
71
|
+
return False
|
|
72
|
+
|
|
73
|
+
logger.info("✅ Configuration validation passed")
|
|
74
|
+
return True
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def display_startup_information() -> None:
|
|
78
|
+
"""
|
|
79
|
+
Display startup information and demo features.
|
|
80
|
+
"""
|
|
81
|
+
print(f"🚀 Wappa v{__version__} - Full Example (Comprehensive Demo)")
|
|
82
|
+
print("=" * 80)
|
|
83
|
+
print()
|
|
84
|
+
|
|
85
|
+
print("🎯 *COMPREHENSIVE WAPPA FRAMEWORK DEMONSTRATION*")
|
|
86
|
+
print(" This example showcases ALL major Wappa framework features:")
|
|
87
|
+
print(" • Complete message type handling with metadata extraction")
|
|
88
|
+
print(" • Interactive commands with state management and TTL")
|
|
89
|
+
print(" • Media relay functionality using media_id")
|
|
90
|
+
print(" • User tracking and analytics with Redis cache")
|
|
91
|
+
print(" • Welcome messages for first-time users")
|
|
92
|
+
print(" • Professional error handling and logging")
|
|
93
|
+
print()
|
|
94
|
+
|
|
95
|
+
print("📋 *CONFIGURATION STATUS:*")
|
|
96
|
+
print(
|
|
97
|
+
f" • Access Token: {'✅ Configured' if settings.wp_access_token else '❌ Missing'}"
|
|
98
|
+
)
|
|
99
|
+
print(
|
|
100
|
+
f" • Phone ID: {settings.wp_phone_id if settings.wp_phone_id else '❌ Missing'}"
|
|
101
|
+
)
|
|
102
|
+
print(f" • Business ID: {'✅ Configured' if settings.wp_bid else '❌ Missing'}")
|
|
103
|
+
print(f" • Redis URL: {'✅ Configured' if settings.has_redis else '❌ Missing'}")
|
|
104
|
+
print(
|
|
105
|
+
f" • Environment: {'🛠️ Development' if settings.is_development else '🚀 Production'}"
|
|
106
|
+
)
|
|
107
|
+
print()
|
|
108
|
+
|
|
109
|
+
print("🎮 *INTERACTIVE DEMO COMMANDS:*")
|
|
110
|
+
print(" • `/button` → Interactive button demo with animal selection")
|
|
111
|
+
print(" - Creates buttons for Kitty 🐱 and Puppy 🐶")
|
|
112
|
+
print(" - 10-minute TTL with state management")
|
|
113
|
+
print(" - Sends corresponding animal image on selection")
|
|
114
|
+
print(" - Shows comprehensive metadata extraction")
|
|
115
|
+
print()
|
|
116
|
+
print(" • `/list` → Interactive list demo with media files")
|
|
117
|
+
print(" - List with Image, Video, Audio, Document options")
|
|
118
|
+
print(" - Sends actual media files based on selection")
|
|
119
|
+
print(" - Demonstrates list interaction patterns")
|
|
120
|
+
print()
|
|
121
|
+
print(" • `/cta` → Call-to-Action button demonstration")
|
|
122
|
+
print(" - External link to Wappa documentation")
|
|
123
|
+
print(" - Shows CTA button implementation")
|
|
124
|
+
print()
|
|
125
|
+
print(" • `/location` → Location sharing demonstration")
|
|
126
|
+
print(" - Shares predefined location (Bogotá, Colombia)")
|
|
127
|
+
print(" - Shows location message implementation")
|
|
128
|
+
print()
|
|
129
|
+
|
|
130
|
+
print("📨 *MESSAGE TYPE HANDLING:*")
|
|
131
|
+
print(" • Text Messages → Echo with 'Echo - {content}' + metadata")
|
|
132
|
+
print(" • Media Messages → Relay same media using media_id + metadata")
|
|
133
|
+
print(" • Location Messages → Echo same location coordinates + metadata")
|
|
134
|
+
print(" • Contact Messages → Echo contact information + metadata")
|
|
135
|
+
print(" • Interactive Messages → Process selections + metadata")
|
|
136
|
+
print()
|
|
137
|
+
|
|
138
|
+
print("👤 *USER MANAGEMENT FEATURES:*")
|
|
139
|
+
print(" • First-time user detection and welcome messages")
|
|
140
|
+
print(" • User profile caching with activity tracking")
|
|
141
|
+
print(" • Message count and interaction statistics")
|
|
142
|
+
print(" • Command usage analytics")
|
|
143
|
+
print()
|
|
144
|
+
|
|
145
|
+
print("🏗️ *TECHNICAL ARCHITECTURE:*")
|
|
146
|
+
print(" • Redis cache for user profiles and interactive states")
|
|
147
|
+
print(" • Comprehensive metadata extraction per message type")
|
|
148
|
+
print(" • State management with TTL for interactive features")
|
|
149
|
+
print(" • Professional error handling and recovery")
|
|
150
|
+
print(" • Structured logging with performance metrics")
|
|
151
|
+
print(" • Clean code architecture with separation of concerns")
|
|
152
|
+
print()
|
|
153
|
+
|
|
154
|
+
print("📊 *DEMONSTRATED PATTERNS:*")
|
|
155
|
+
print(" • Complete IMessenger interface utilization")
|
|
156
|
+
print(" • Media handling with download/upload capabilities")
|
|
157
|
+
print(" • Interactive workflow state machines")
|
|
158
|
+
print(" • User session and activity tracking")
|
|
159
|
+
print(" • Production-ready error handling")
|
|
160
|
+
print(" • Scalable Redis caching strategies")
|
|
161
|
+
print()
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def create_wappa_application() -> Wappa:
|
|
165
|
+
"""
|
|
166
|
+
Create and configure the Wappa application.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
Configured Wappa application instance
|
|
170
|
+
"""
|
|
171
|
+
try:
|
|
172
|
+
# Create Wappa instance with Redis cache
|
|
173
|
+
logger.info("🏗️ Creating Wappa application with Redis cache...")
|
|
174
|
+
app = Wappa(cache="redis")
|
|
175
|
+
|
|
176
|
+
logger.info("✅ Wappa application created successfully")
|
|
177
|
+
return app
|
|
178
|
+
|
|
179
|
+
except Exception as e:
|
|
180
|
+
logger.error(f"❌ Failed to create Wappa application: {e}")
|
|
181
|
+
raise
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def main() -> None:
|
|
185
|
+
"""
|
|
186
|
+
Main application entry point.
|
|
187
|
+
|
|
188
|
+
Demonstrates complete Wappa framework integration with:
|
|
189
|
+
- Configuration validation
|
|
190
|
+
- Application setup
|
|
191
|
+
- Handler registration
|
|
192
|
+
- Professional startup flow
|
|
193
|
+
"""
|
|
194
|
+
logger.info("🚀 Starting Wappa Full Example - Comprehensive Demo")
|
|
195
|
+
|
|
196
|
+
try:
|
|
197
|
+
# Display comprehensive startup information
|
|
198
|
+
display_startup_information()
|
|
199
|
+
|
|
200
|
+
# Validate configuration before proceeding
|
|
201
|
+
if not validate_configuration():
|
|
202
|
+
logger.error(
|
|
203
|
+
"❌ Configuration validation failed - cannot start application"
|
|
204
|
+
)
|
|
205
|
+
return
|
|
206
|
+
|
|
207
|
+
# Create Wappa application
|
|
208
|
+
app = create_wappa_application()
|
|
209
|
+
|
|
210
|
+
# Create and set our comprehensive WappaEventHandler implementation
|
|
211
|
+
handler = WappaFullExampleHandler()
|
|
212
|
+
app.set_event_handler(handler)
|
|
213
|
+
|
|
214
|
+
logger.info(
|
|
215
|
+
"✅ Application initialization completed with comprehensive WappaEventHandler"
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
print("🌐 Starting comprehensive Wappa demo server...")
|
|
219
|
+
print("💡 Press CTRL+C to stop the server")
|
|
220
|
+
print()
|
|
221
|
+
print("🎯 *Try these features once connected:*")
|
|
222
|
+
print(" 1. Send any message → See metadata extraction + echo")
|
|
223
|
+
print(" 2. Send /button → Interactive button demo")
|
|
224
|
+
print(" 3. Send /list → Interactive list demo")
|
|
225
|
+
print(" 4. Send /cta → Call-to-action button")
|
|
226
|
+
print(" 5. Send /location → Location sharing demo")
|
|
227
|
+
print(" 6. Send media files → See media relay functionality")
|
|
228
|
+
print("=" * 80)
|
|
229
|
+
print()
|
|
230
|
+
|
|
231
|
+
# Start the application
|
|
232
|
+
# The framework will handle dependency injection automatically
|
|
233
|
+
app.run()
|
|
234
|
+
|
|
235
|
+
except KeyboardInterrupt:
|
|
236
|
+
logger.info("👋 Application stopped by user")
|
|
237
|
+
print("\n👋 Wappa Full Example stopped by user")
|
|
238
|
+
|
|
239
|
+
except Exception as e:
|
|
240
|
+
logger.error(f"❌ Application startup error: {e}", exc_info=True)
|
|
241
|
+
print(f"\n❌ Server error: {e}")
|
|
242
|
+
|
|
243
|
+
finally:
|
|
244
|
+
logger.info("🏁 Wappa Full Example completed")
|
|
245
|
+
print("🏁 Wappa Full Example completed")
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
# Module-level app instance for uvicorn compatibility
|
|
249
|
+
# This enables: uvicorn app.main:app --reload
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
logger.info("📦 Creating module-level Wappa application instance")
|
|
253
|
+
app = Wappa(cache="redis")
|
|
254
|
+
|
|
255
|
+
# Create and set our comprehensive WappaEventHandler implementation
|
|
256
|
+
handler = WappaFullExampleHandler()
|
|
257
|
+
app.set_event_handler(handler)
|
|
258
|
+
|
|
259
|
+
logger.info(
|
|
260
|
+
"✅ Module-level application instance ready with comprehensive WappaEventHandler"
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
except Exception as e:
|
|
264
|
+
logger.error(f"❌ Failed to create module-level app instance: {e}")
|
|
265
|
+
raise
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
if __name__ == "__main__":
|
|
269
|
+
main()
|