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.

Files changed (147) hide show
  1. wappa/__init__.py +4 -5
  2. wappa/api/controllers/webhook_controller.py +5 -2
  3. wappa/api/dependencies/__init__.py +0 -5
  4. wappa/api/middleware/error_handler.py +4 -4
  5. wappa/api/middleware/owner.py +11 -5
  6. wappa/api/routes/webhooks.py +2 -2
  7. wappa/cli/__init__.py +1 -1
  8. wappa/cli/examples/init/.env.example +33 -0
  9. wappa/cli/examples/init/app/__init__.py +0 -0
  10. wappa/cli/examples/init/app/main.py +9 -0
  11. wappa/cli/examples/init/app/master_event.py +10 -0
  12. wappa/cli/examples/json_cache_example/.env.example +33 -0
  13. wappa/cli/examples/json_cache_example/app/__init__.py +1 -0
  14. wappa/cli/examples/json_cache_example/app/main.py +247 -0
  15. wappa/cli/examples/json_cache_example/app/master_event.py +455 -0
  16. wappa/cli/examples/json_cache_example/app/models/__init__.py +1 -0
  17. wappa/cli/examples/json_cache_example/app/models/json_demo_models.py +256 -0
  18. wappa/cli/examples/json_cache_example/app/scores/__init__.py +35 -0
  19. wappa/cli/examples/json_cache_example/app/scores/score_base.py +192 -0
  20. wappa/cli/examples/json_cache_example/app/scores/score_cache_statistics.py +256 -0
  21. wappa/cli/examples/json_cache_example/app/scores/score_message_history.py +187 -0
  22. wappa/cli/examples/json_cache_example/app/scores/score_state_commands.py +272 -0
  23. wappa/cli/examples/json_cache_example/app/scores/score_user_management.py +239 -0
  24. wappa/cli/examples/json_cache_example/app/utils/__init__.py +26 -0
  25. wappa/cli/examples/json_cache_example/app/utils/cache_utils.py +174 -0
  26. wappa/cli/examples/json_cache_example/app/utils/message_utils.py +251 -0
  27. wappa/cli/examples/openai_transcript/.gitignore +63 -4
  28. wappa/cli/examples/openai_transcript/app/__init__.py +0 -0
  29. wappa/cli/examples/openai_transcript/app/main.py +9 -0
  30. wappa/cli/examples/openai_transcript/app/master_event.py +62 -0
  31. wappa/cli/examples/openai_transcript/app/openai_utils/__init__.py +3 -0
  32. wappa/cli/examples/openai_transcript/app/openai_utils/audio_processing.py +89 -0
  33. wappa/cli/examples/redis_cache_example/.env.example +33 -0
  34. wappa/cli/examples/redis_cache_example/app/__init__.py +6 -0
  35. wappa/cli/examples/redis_cache_example/app/main.py +246 -0
  36. wappa/cli/examples/redis_cache_example/app/master_event.py +455 -0
  37. wappa/cli/examples/redis_cache_example/app/models/redis_demo_models.py +256 -0
  38. wappa/cli/examples/redis_cache_example/app/scores/__init__.py +35 -0
  39. wappa/cli/examples/redis_cache_example/app/scores/score_base.py +192 -0
  40. wappa/cli/examples/redis_cache_example/app/scores/score_cache_statistics.py +256 -0
  41. wappa/cli/examples/redis_cache_example/app/scores/score_message_history.py +187 -0
  42. wappa/cli/examples/redis_cache_example/app/scores/score_state_commands.py +272 -0
  43. wappa/cli/examples/redis_cache_example/app/scores/score_user_management.py +239 -0
  44. wappa/cli/examples/redis_cache_example/app/utils/__init__.py +26 -0
  45. wappa/cli/examples/redis_cache_example/app/utils/cache_utils.py +174 -0
  46. wappa/cli/examples/redis_cache_example/app/utils/message_utils.py +251 -0
  47. wappa/cli/examples/simple_echo_example/.env.example +33 -0
  48. wappa/cli/examples/simple_echo_example/app/__init__.py +7 -0
  49. wappa/cli/examples/simple_echo_example/app/main.py +191 -0
  50. wappa/cli/examples/simple_echo_example/app/master_event.py +230 -0
  51. wappa/cli/examples/wappa_full_example/.env.example +33 -0
  52. wappa/cli/examples/wappa_full_example/.gitignore +63 -4
  53. wappa/cli/examples/wappa_full_example/app/__init__.py +6 -0
  54. wappa/cli/examples/wappa_full_example/app/handlers/__init__.py +5 -0
  55. wappa/cli/examples/wappa_full_example/app/handlers/command_handlers.py +492 -0
  56. wappa/cli/examples/wappa_full_example/app/handlers/message_handlers.py +559 -0
  57. wappa/cli/examples/wappa_full_example/app/handlers/state_handlers.py +514 -0
  58. wappa/cli/examples/wappa_full_example/app/main.py +269 -0
  59. wappa/cli/examples/wappa_full_example/app/master_event.py +504 -0
  60. wappa/cli/examples/wappa_full_example/app/media/README.md +54 -0
  61. wappa/cli/examples/wappa_full_example/app/media/buttons/README.md +62 -0
  62. wappa/cli/examples/wappa_full_example/app/media/buttons/kitty.png +0 -0
  63. wappa/cli/examples/wappa_full_example/app/media/buttons/puppy.png +0 -0
  64. wappa/cli/examples/wappa_full_example/app/media/list/README.md +110 -0
  65. wappa/cli/examples/wappa_full_example/app/media/list/audio.mp3 +0 -0
  66. wappa/cli/examples/wappa_full_example/app/media/list/document.pdf +0 -0
  67. wappa/cli/examples/wappa_full_example/app/media/list/image.png +0 -0
  68. wappa/cli/examples/wappa_full_example/app/media/list/video.mp4 +0 -0
  69. wappa/cli/examples/wappa_full_example/app/models/__init__.py +5 -0
  70. wappa/cli/examples/wappa_full_example/app/models/state_models.py +434 -0
  71. wappa/cli/examples/wappa_full_example/app/models/user_models.py +303 -0
  72. wappa/cli/examples/wappa_full_example/app/models/webhook_metadata.py +327 -0
  73. wappa/cli/examples/wappa_full_example/app/utils/__init__.py +5 -0
  74. wappa/cli/examples/wappa_full_example/app/utils/cache_utils.py +502 -0
  75. wappa/cli/examples/wappa_full_example/app/utils/media_handler.py +516 -0
  76. wappa/cli/examples/wappa_full_example/app/utils/metadata_extractor.py +337 -0
  77. wappa/cli/main.py +14 -5
  78. wappa/core/__init__.py +18 -23
  79. wappa/core/config/settings.py +7 -5
  80. wappa/core/events/default_handlers.py +1 -1
  81. wappa/core/factory/wappa_builder.py +38 -25
  82. wappa/core/plugins/redis_plugin.py +1 -3
  83. wappa/core/plugins/wappa_core_plugin.py +7 -6
  84. wappa/core/types.py +12 -12
  85. wappa/core/wappa_app.py +10 -8
  86. wappa/database/__init__.py +3 -4
  87. wappa/domain/enums/messenger_platform.py +1 -2
  88. wappa/domain/factories/media_factory.py +5 -20
  89. wappa/domain/factories/message_factory.py +5 -20
  90. wappa/domain/factories/messenger_factory.py +2 -4
  91. wappa/domain/interfaces/cache_interface.py +7 -7
  92. wappa/domain/interfaces/media_interface.py +2 -5
  93. wappa/domain/models/media_result.py +1 -3
  94. wappa/domain/models/platforms/platform_config.py +1 -3
  95. wappa/messaging/__init__.py +9 -12
  96. wappa/messaging/whatsapp/handlers/whatsapp_media_handler.py +20 -22
  97. wappa/models/__init__.py +27 -35
  98. wappa/persistence/__init__.py +12 -15
  99. wappa/persistence/cache_factory.py +0 -1
  100. wappa/persistence/json/__init__.py +1 -1
  101. wappa/persistence/json/cache_adapters.py +37 -25
  102. wappa/persistence/json/handlers/state_handler.py +60 -52
  103. wappa/persistence/json/handlers/table_handler.py +51 -49
  104. wappa/persistence/json/handlers/user_handler.py +71 -55
  105. wappa/persistence/json/handlers/utils/file_manager.py +42 -39
  106. wappa/persistence/json/handlers/utils/key_factory.py +1 -1
  107. wappa/persistence/json/handlers/utils/serialization.py +13 -11
  108. wappa/persistence/json/json_cache_factory.py +4 -8
  109. wappa/persistence/json/storage_manager.py +66 -79
  110. wappa/persistence/memory/__init__.py +1 -1
  111. wappa/persistence/memory/cache_adapters.py +37 -25
  112. wappa/persistence/memory/handlers/state_handler.py +62 -52
  113. wappa/persistence/memory/handlers/table_handler.py +59 -53
  114. wappa/persistence/memory/handlers/user_handler.py +75 -55
  115. wappa/persistence/memory/handlers/utils/key_factory.py +1 -1
  116. wappa/persistence/memory/handlers/utils/memory_store.py +75 -71
  117. wappa/persistence/memory/handlers/utils/ttl_manager.py +59 -67
  118. wappa/persistence/memory/memory_cache_factory.py +3 -7
  119. wappa/persistence/memory/storage_manager.py +52 -62
  120. wappa/persistence/redis/cache_adapters.py +27 -21
  121. wappa/persistence/redis/ops.py +11 -11
  122. wappa/persistence/redis/redis_client.py +4 -6
  123. wappa/persistence/redis/redis_manager.py +12 -4
  124. wappa/processors/factory.py +5 -5
  125. wappa/schemas/factory.py +2 -5
  126. wappa/schemas/whatsapp/message_types/errors.py +3 -12
  127. wappa/schemas/whatsapp/validators.py +3 -3
  128. wappa/webhooks/__init__.py +17 -18
  129. wappa/webhooks/factory.py +3 -5
  130. wappa/webhooks/whatsapp/__init__.py +10 -13
  131. wappa/webhooks/whatsapp/message_types/audio.py +0 -4
  132. wappa/webhooks/whatsapp/message_types/document.py +1 -9
  133. wappa/webhooks/whatsapp/message_types/errors.py +3 -12
  134. wappa/webhooks/whatsapp/message_types/location.py +1 -21
  135. wappa/webhooks/whatsapp/message_types/sticker.py +1 -5
  136. wappa/webhooks/whatsapp/message_types/text.py +0 -6
  137. wappa/webhooks/whatsapp/message_types/video.py +1 -20
  138. wappa/webhooks/whatsapp/status_models.py +2 -2
  139. wappa/webhooks/whatsapp/validators.py +3 -3
  140. {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/METADATA +362 -8
  141. {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/RECORD +144 -80
  142. wappa/cli/examples/init/pyproject.toml +0 -7
  143. wappa/cli/examples/simple_echo_example/.python-version +0 -1
  144. wappa/cli/examples/simple_echo_example/pyproject.toml +0 -9
  145. {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/WHEEL +0 -0
  146. {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/entry_points.txt +0 -0
  147. {wappa-0.1.8.dist-info → wappa-0.1.10.dist-info}/licenses/LICENSE +0 -0
wappa/__init__.py CHANGED
@@ -11,19 +11,18 @@ Clean Import Interface (SRP Compliance):
11
11
  """
12
12
 
13
13
  # Framework Essentials Only (SRP: Framework Foundation)
14
- from .core.wappa_app import Wappa
15
- from .core.events.event_handler import WappaEventHandler
16
- from .core.factory import WappaBuilder, WappaPlugin
17
-
18
14
  # Dynamic version from pyproject.toml
19
15
  from .core.config.settings import settings
16
+ from .core.events.event_handler import WappaEventHandler
17
+ from .core.factory import WappaBuilder, WappaPlugin
18
+ from .core.wappa_app import Wappa
20
19
 
21
20
  __version__ = settings.version
22
21
 
23
22
  __all__ = [
24
23
  # Core Framework Components
25
24
  "Wappa",
26
- "WappaEventHandler",
25
+ "WappaEventHandler",
27
26
  "WappaBuilder",
28
27
  "WappaPlugin",
29
28
  ]
@@ -144,8 +144,9 @@ class WebhookController:
144
144
 
145
145
  # ENHANCED DEBUGGING: Show context details
146
146
  from wappa.core.logging.context import get_context_info
147
+
147
148
  context_info = get_context_info()
148
-
149
+
149
150
  self.logger.debug(
150
151
  f"Processing webhook for platform: {platform}, owner: {owner_id}"
151
152
  )
@@ -395,7 +396,9 @@ class WebhookController:
395
396
  factory_class = create_cache_factory(cache_type)
396
397
  cache_factory = factory_class(tenant_id=tenant_id, user_id=user_id)
397
398
 
398
- self.logger.debug(f"✅ Created {cache_factory.__class__.__name__} successfully")
399
+ self.logger.debug(
400
+ f"✅ Created {cache_factory.__class__.__name__} successfully"
401
+ )
399
402
  return cache_factory
400
403
 
401
404
  except Exception as e:
@@ -5,11 +5,6 @@ Provides reusable dependencies for controllers, services, and middleware
5
5
  following clean architecture patterns.
6
6
  """
7
7
 
8
- from functools import lru_cache
9
- from typing import Annotated
10
-
11
- from fastapi import Depends, HTTPException, Request
12
-
13
8
  # Import existing dependencies
14
9
  from .whatsapp_dependencies import *
15
10
  from .whatsapp_media_dependencies import *
@@ -40,11 +40,11 @@ class ErrorHandlerMiddleware(BaseHTTPMiddleware):
40
40
 
41
41
  async def _log_http_exception(self, request: Request, exc: HTTPException) -> None:
42
42
  """Log HTTP exceptions with tenant context."""
43
- tenant_id = getattr(request.state, "tenant_id", "unknown")
43
+ getattr(request.state, "tenant_id", "unknown")
44
44
  logger = get_logger(__name__)
45
45
 
46
46
  # Extract user context from request if available
47
- user_id = getattr(request.state, "user_id", "unknown")
47
+ getattr(request.state, "user_id", "unknown")
48
48
 
49
49
  logger.warning(
50
50
  f"HTTP {exc.status_code} - {request.method} {request.url.path} - "
@@ -55,8 +55,8 @@ class ErrorHandlerMiddleware(BaseHTTPMiddleware):
55
55
  self, request: Request, exc: Exception
56
56
  ) -> JSONResponse:
57
57
  """Handle unexpected exceptions with proper logging and response."""
58
- tenant_id = getattr(request.state, "tenant_id", "unknown")
59
- user_id = getattr(request.state, "user_id", "unknown")
58
+ getattr(request.state, "tenant_id", "unknown")
59
+ getattr(request.state, "user_id", "unknown")
60
60
 
61
61
  # Get context-aware logger
62
62
  logger = get_logger(__name__)
@@ -32,14 +32,16 @@ class OwnerMiddleware(BaseHTTPMiddleware):
32
32
 
33
33
  try:
34
34
  # ENHANCED DEBUGGING: Log all request details
35
- logger.debug(f"🔍 OwnerMiddleware processing: {request.method} {request.url.path}")
36
-
35
+ logger.debug(
36
+ f"🔍 OwnerMiddleware processing: {request.method} {request.url.path}"
37
+ )
38
+
37
39
  # Extract owner_id from webhook URL pattern: /webhook/messenger/{owner_id}/{platform}
38
40
  if request.url.path.startswith("/webhook/"):
39
41
  logger.debug(f"🎯 Webhook request detected: {request.url.path}")
40
42
  path_parts = request.url.path.strip("/").split("/")
41
43
  logger.debug(f"📋 Path parts: {path_parts} (length: {len(path_parts)})")
42
-
44
+
43
45
  if len(path_parts) >= 4:
44
46
  # path_parts = ["webhook", "messenger", "owner_id", "platform"]
45
47
  owner_id = path_parts[2]
@@ -49,14 +51,18 @@ class OwnerMiddleware(BaseHTTPMiddleware):
49
51
  if self._is_valid_owner_id(owner_id):
50
52
  # Set owner_id context from URL
51
53
  set_request_context(owner_id=owner_id)
52
- logger.debug(f"✅ Owner ID context set successfully: {owner_id}")
54
+ logger.debug(
55
+ f"✅ Owner ID context set successfully: {owner_id}"
56
+ )
53
57
  else:
54
58
  logger.error(f"❌ Invalid owner ID format: {owner_id}")
55
59
  raise HTTPException(
56
60
  status_code=400, detail=f"Invalid owner ID: {owner_id}"
57
61
  )
58
62
  else:
59
- logger.warning(f"⚠️ Webhook URL does not have enough parts: {path_parts}")
63
+ logger.warning(
64
+ f"⚠️ Webhook URL does not have enough parts: {path_parts}"
65
+ )
60
66
 
61
67
  # For non-webhook endpoints, use default owner from settings
62
68
  elif not self._is_public_endpoint(request.url.path):
@@ -161,10 +161,10 @@ def create_webhook_router(event_dispatcher: WappaEventDispatcher) -> APIRouter:
161
161
  # Generate webhook URLs for this platform and tenant
162
162
  try:
163
163
  platform_type = PlatformType(platform.lower())
164
- except ValueError:
164
+ except ValueError as e:
165
165
  raise HTTPException(
166
166
  status_code=400, detail=f"Unsupported platform: {platform}"
167
- )
167
+ ) from e
168
168
 
169
169
  webhook_url = webhook_url_factory.generate_webhook_url(platform_type, tenant_id)
170
170
  verify_url = webhook_url_factory.generate_webhook_url(
wappa/cli/__init__.py CHANGED
@@ -6,4 +6,4 @@ Provides command-line interface for Wappa development and deployment workflows.
6
6
 
7
7
  from .main import app
8
8
 
9
- __all__ = ["app"]
9
+ __all__ = ["app"]
@@ -0,0 +1,33 @@
1
+ # ================================================================
2
+ # WAPPA WHATSAPP FRAMEWORK CONFIGURATION
3
+ # ================================================================
4
+
5
+ # General Configuration
6
+ PORT=8000
7
+ TIME_ZONE=America/Bogota
8
+
9
+ # DEBUG or INFO or WARNING or ERROR or CRITICAL
10
+ LOG_LEVEL=DEBUG
11
+ LOG_DIR=./logs
12
+ ## Environment DEV or PROD
13
+ ENVIRONMENT=DEV
14
+
15
+ # WhatsApp Graph API
16
+ BASE_URL=https://graph.facebook.com/
17
+ API_VERSION=v23.0
18
+
19
+ # WhatsApp Business API Credentials
20
+ WP_ACCESS_TOKEN=
21
+ WP_PHONE_ID=
22
+ WP_BID=
23
+
24
+ # Webhook Configuration
25
+ WHATSAPP_WEBHOOK_VERIFY_TOKEN=
26
+
27
+ # Redis Configuration (Optional - uncomment to enable Redis persistence)
28
+ # REDIS_URL=redis://localhost:6379/
29
+ # REDIS_MAX_CONNECTIONS=64
30
+
31
+ # Optional: AI Tools
32
+ # OPENAI_API_KEY=
33
+
File without changes
@@ -0,0 +1,9 @@
1
+ from wappa import Wappa
2
+
3
+ from .master_event import MasterEventHandler
4
+
5
+ app = Wappa()
6
+ app.set_event_handler(MasterEventHandler())
7
+
8
+ if __name__ == "__main__":
9
+ app.run()
@@ -0,0 +1,10 @@
1
+ from wappa import WappaEventHandler
2
+ from wappa.webhooks import IncomingMessageWebhook
3
+
4
+
5
+ class MasterEventHandler(WappaEventHandler):
6
+ async def process_message(self, webhook: IncomingMessageWebhook):
7
+ await self.messenger.mark_as_read(
8
+ webhook.message.message_id, webhook.user.user_id
9
+ )
10
+ await self.messenger.send_text("Welcome to Wappa", webhook.user.user_id)
@@ -0,0 +1,33 @@
1
+ # ================================================================
2
+ # WAPPA WHATSAPP FRAMEWORK CONFIGURATION
3
+ # ================================================================
4
+
5
+ # General Configuration
6
+ PORT=8000
7
+ TIME_ZONE=America/Bogota
8
+
9
+ # DEBUG or INFO or WARNING or ERROR or CRITICAL
10
+ LOG_LEVEL=DEBUG
11
+ LOG_DIR=./logs
12
+ ## Environment DEV or PROD
13
+ ENVIRONMENT=DEV
14
+
15
+ # WhatsApp Graph API
16
+ BASE_URL=https://graph.facebook.com/
17
+ API_VERSION=v23.0
18
+
19
+ # WhatsApp Business API Credentials
20
+ WP_ACCESS_TOKEN=
21
+ WP_PHONE_ID=
22
+ WP_BID=
23
+
24
+ # Webhook Configuration
25
+ WHATSAPP_WEBHOOK_VERIFY_TOKEN=
26
+
27
+ # Redis Configuration (Optional - uncomment to enable Redis persistence)
28
+ # REDIS_URL=redis://localhost:6379/
29
+ # REDIS_MAX_CONNECTIONS=64
30
+
31
+ # Optional: AI Tools
32
+ # OPENAI_API_KEY=
33
+
@@ -0,0 +1 @@
1
+ """JSON Cache Example - SOLID Architecture Implementation"""
@@ -0,0 +1,247 @@
1
+ """
2
+ JSON Cache Example - SOLID Architecture Implementation
3
+
4
+ This is the main initialization file following SOLID principles:
5
+ - Single Responsibility: Pure initialization and configuration
6
+ - Open/Closed: Extensible through score module registration
7
+ - Liskov Substitution: Compatible with Wappa framework interface
8
+ - Interface Segregation: Clean dependency interfaces
9
+ - Dependency Inversion: Abstractions injected into concrete implementations
10
+
11
+ SETUP REQUIRED:
12
+ 1. Create a .env file with your WhatsApp Business API credentials:
13
+ WP_ACCESS_TOKEN=your_access_token_here
14
+ WP_PHONE_ID=your_phone_number_id_here
15
+ WP_BID=your_business_id_here
16
+
17
+ 2. JSON Cache automatically creates cache directory:
18
+ No external dependencies required!
19
+ Cache files will be created in {project_root}/cache/
20
+
21
+ DEMO FEATURES:
22
+ - SOLID architecture with separated concerns
23
+ - Master event orchestrator with score modules
24
+ - User management, message history, and state commands
25
+ - Cache statistics and monitoring
26
+ - Professional logging and error handling
27
+ - File-based JSON cache with TTL support
28
+
29
+ USAGE:
30
+ - Direct Python: python -m app.main (from project root)
31
+ - FastAPI-style: uvicorn app.main:app --reload (from project root)
32
+ - Wappa CLI: wappa dev app.main (when CLI is available)
33
+ """
34
+
35
+ # Import core Wappa components
36
+ from wappa import Wappa, __version__
37
+ from wappa.core.config.settings import settings
38
+ from wappa.core.logging import get_logger
39
+
40
+ logger = get_logger(__name__)
41
+
42
+ # Import our SOLID architecture WappaEventHandler implementation
43
+ from .master_event import JSONCacheExampleHandler
44
+
45
+
46
+ def validate_configuration() -> bool:
47
+ """
48
+ Validate required configuration settings.
49
+
50
+ Returns:
51
+ True if configuration is valid, False otherwise
52
+ """
53
+
54
+ # Check required WhatsApp credentials
55
+ missing_configs = []
56
+
57
+ if not settings.wp_access_token:
58
+ missing_configs.append("WP_ACCESS_TOKEN")
59
+
60
+ if not settings.wp_phone_id:
61
+ missing_configs.append("WP_PHONE_ID")
62
+
63
+ if not settings.wp_bid:
64
+ missing_configs.append("WP_BID")
65
+
66
+ if missing_configs:
67
+ logger.error(f"❌ Missing required configuration: {', '.join(missing_configs)}")
68
+ logger.error("💡 Create a .env file with the required credentials")
69
+ return False
70
+
71
+ logger.info("✅ Configuration validation passed")
72
+ return True
73
+
74
+
75
+ def display_startup_information() -> None:
76
+ """
77
+ Display startup information and demo features.
78
+
79
+ Shows configuration status, architecture overview,
80
+ and available demo features.
81
+ """
82
+ print(f"🚀 Wappa v{__version__} - JSON Cache Example (SOLID Architecture)")
83
+ print("=" * 80)
84
+ print()
85
+
86
+ print("🏗️ *SOLID ARCHITECTURE IMPLEMENTATION:*")
87
+ print(" • Single Responsibility: Each score module has one specific concern")
88
+ print(" • Open/Closed: New score modules can be added without modification")
89
+ print(" • Liskov Substitution: All scores implement the same interface")
90
+ print(" • Interface Segregation: Clean, focused interfaces for each concern")
91
+ print(" • Dependency Inversion: Dependencies injected through abstractions")
92
+ print()
93
+
94
+ print("📋 *CONFIGURATION STATUS:*")
95
+ print(
96
+ f" • Access Token: {'✅ Configured' if settings.wp_access_token else '❌ Missing'}"
97
+ )
98
+ print(
99
+ f" • Phone ID: {settings.wp_phone_id if settings.wp_phone_id else '❌ Missing'}"
100
+ )
101
+ print(f" • Business ID: {'✅ Configured' if settings.wp_bid else '❌ Missing'}")
102
+ print(" • JSON Cache: ✅ No external dependencies required")
103
+ print(
104
+ f" • Environment: {'🛠️ Development' if settings.is_development else '🚀 Production'}"
105
+ )
106
+ print()
107
+
108
+ print("🎯 *SCORE MODULES (BUSINESS LOGIC):*")
109
+ print(" • UserManagementScore: User profile and caching logic")
110
+ print(" • MessageHistoryScore: Message logging and /HISTORY command")
111
+ print(" • StateCommandsScore: /WAPPA and /EXIT command processing")
112
+ print(" • CacheStatisticsScore: Cache monitoring and /STATS command")
113
+ print()
114
+
115
+ print("🧪 *DEMO FEATURES:*")
116
+ print(" 1. Send any message → User profile created/updated + message logged")
117
+ print(" 2. Send '/WAPPA' → Enter special state with cache management")
118
+ print(" 3. While in WAPPA state → All messages replied with 'Hola Wapp@ ;)'")
119
+ print(" 4. Send '/EXIT' → Leave special state with session summary")
120
+ print(" 5. Send '/HISTORY' → View your last 20 messages with timestamps")
121
+ print(" 6. Send '/STATS' → View comprehensive cache statistics")
122
+ print()
123
+
124
+ print("💎 *JSON CACHE ARCHITECTURE:*")
125
+ print(" • user_cache: User profiles stored in {project_root}/cache/users/")
126
+ print(" • table_cache: Message history in {project_root}/cache/tables/")
127
+ print(" • state_cache: Command state management in {project_root}/cache/states/")
128
+ print(" • TTL Support: Metadata-based expiration with lazy cleanup")
129
+ print(" • File Safety: Atomic write operations prevent corruption")
130
+ print()
131
+
132
+ print("🔧 *TECHNICAL FEATURES:*")
133
+ print(" • File-based persistence with project root auto-detection")
134
+ print(" • BaseModel JSON serialization with datetime handling")
135
+ print(" • TTL support through JSON metadata")
136
+ print(" • Dependency injection with interface abstractions")
137
+ print(" • Score module registry with automatic discovery")
138
+ print(" • Professional error handling and recovery")
139
+ print(" • Performance monitoring and statistics")
140
+ print(" • Comprehensive logging with structured output")
141
+ print(" • Cache file inspection for debugging")
142
+ print()
143
+
144
+
145
+ def create_wappa_application() -> Wappa:
146
+ """
147
+ Create and configure the Wappa application.
148
+
149
+ This function follows Single Responsibility Principle by focusing
150
+ only on application creation and initial configuration.
151
+
152
+ Returns:
153
+ Configured Wappa application instance
154
+ """
155
+
156
+ try:
157
+ # Create Wappa instance with JSON cache
158
+ logger.info("🏗️ Creating Wappa application with JSON cache...")
159
+ app = Wappa(cache="json")
160
+
161
+ logger.info("✅ Wappa application created successfully")
162
+ return app
163
+
164
+ except Exception as e:
165
+ logger.error(f"❌ Failed to create Wappa application: {e}")
166
+ raise
167
+
168
+
169
+ def main() -> None:
170
+ """
171
+ Main application entry point.
172
+
173
+ Demonstrates SOLID principles in action:
174
+ - Single Responsibility: Each function has one clear purpose
175
+ - Dependency Inversion: Dependencies flow from abstractions
176
+ - Open/Closed: System is open for extension via score modules
177
+ """
178
+
179
+ logger.info("🚀 Starting JSON Cache Example with SOLID Architecture")
180
+
181
+ try:
182
+ # Display startup information
183
+ display_startup_information()
184
+
185
+ # Validate configuration before proceeding
186
+ if not validate_configuration():
187
+ logger.error(
188
+ "❌ Configuration validation failed - cannot start application"
189
+ )
190
+ return
191
+
192
+ # Create Wappa application
193
+ app = create_wappa_application()
194
+
195
+ # Create and set the SOLID WappaEventHandler implementation
196
+ handler = JSONCacheExampleHandler()
197
+ app.set_event_handler(handler)
198
+
199
+ logger.info(
200
+ "✅ Application initialization completed with SOLID WappaEventHandler"
201
+ )
202
+
203
+ print("🌐 Starting SOLID JSON cache demo server...")
204
+ print("💡 Press CTRL+C to stop the server")
205
+ print("💾 Cache files will be created in the project's cache/ directory")
206
+ print("=" * 80)
207
+ print()
208
+
209
+ # Start the application
210
+ # The framework will handle dependency injection automatically
211
+ app.run()
212
+
213
+ except KeyboardInterrupt:
214
+ logger.info("👋 Application stopped by user")
215
+ print("\n👋 JSON cache demo stopped by user")
216
+
217
+ except Exception as e:
218
+ logger.error(f"❌ Application startup error: {e}", exc_info=True)
219
+ print(f"\n❌ Server error: {e}")
220
+
221
+ finally:
222
+ logger.info("🏁 JSON cache demo completed")
223
+ print("🏁 JSON cache demo completed")
224
+
225
+
226
+ # Module-level app instance for uvicorn compatibility
227
+ # This enables: uvicorn main:app --reload
228
+
229
+ try:
230
+ logger.info("📦 Creating module-level Wappa application instance")
231
+ app = Wappa(cache="json")
232
+
233
+ # Create and set the SOLID WappaEventHandler implementation
234
+ handler = JSONCacheExampleHandler()
235
+ app.set_event_handler(handler)
236
+
237
+ logger.info(
238
+ "✅ Module-level application instance ready with SOLID WappaEventHandler"
239
+ )
240
+
241
+ except Exception as e:
242
+ logger.error(f"❌ Failed to create module-level app instance: {e}")
243
+ raise
244
+
245
+
246
+ if __name__ == "__main__":
247
+ main()