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
@@ -0,0 +1,230 @@
1
+ """
2
+ Simple Echo Master Event Handler
3
+
4
+ A simplified, clean event handler that demonstrates basic echo functionality
5
+ following the same patterns as the redis_cache_example but without the complexity.
6
+
7
+ This handler shows:
8
+ - Clean WappaEventHandler implementation
9
+ - Simple message echoing
10
+ - Multi-message-type support
11
+ - Proper logging and error handling
12
+ """
13
+
14
+ from wappa import WappaEventHandler
15
+ from wappa.core.logging import get_logger
16
+ from wappa.webhooks import ErrorWebhook, IncomingMessageWebhook, StatusWebhook
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ class SimpleEchoHandler(WappaEventHandler):
22
+ """
23
+ Simple echo handler that replies to all messages.
24
+
25
+ This demonstrates the basic WappaEventHandler pattern without
26
+ the complexity of score modules or caching systems.
27
+ """
28
+
29
+ def __init__(self):
30
+ """Initialize the simple echo handler."""
31
+ super().__init__()
32
+ self._message_count = 0
33
+ logger.info("🔄 SimpleEchoHandler initialized - ready to echo messages")
34
+
35
+ async def process_message(self, webhook: IncomingMessageWebhook) -> None:
36
+ """
37
+ Process incoming messages with simple echo functionality.
38
+
39
+ Args:
40
+ webhook: Incoming message webhook to process
41
+ """
42
+
43
+ # Validate dependencies are properly injected
44
+ if not self.validate_dependencies():
45
+ logger.error(
46
+ "❌ Dependencies not properly injected - cannot process message"
47
+ )
48
+ return
49
+
50
+ self._message_count += 1
51
+
52
+ user_id = webhook.user.user_id
53
+ message_text = webhook.get_message_text()
54
+ message_type = webhook.get_message_type_name()
55
+ message_id = webhook.message.message_id
56
+
57
+ logger.info(f"📝 Message #{self._message_count}: {message_type} from {user_id}")
58
+
59
+ try:
60
+ # Mark message as read with typing indicator
61
+ await self.messenger.mark_as_read(message_id=message_id, typing=True)
62
+
63
+ # Handle different message types
64
+ await self._handle_message_by_type(
65
+ webhook, user_id, message_text, message_type
66
+ )
67
+
68
+ except Exception as e:
69
+ logger.error(f"❌ Error processing message: {e}", exc_info=True)
70
+
71
+ async def _handle_message_by_type(
72
+ self,
73
+ webhook: IncomingMessageWebhook,
74
+ user_id: str,
75
+ message_text: str,
76
+ message_type: str,
77
+ ) -> None:
78
+ """Handle message based on its type."""
79
+
80
+ try:
81
+ if message_type.lower() == "text":
82
+ await self._handle_text_message(webhook, user_id, message_text)
83
+ elif message_type.lower() in [
84
+ "image",
85
+ "video",
86
+ "audio",
87
+ "document",
88
+ "sticker",
89
+ ]:
90
+ await self._handle_media_message(webhook, user_id, message_type)
91
+ elif message_type.lower() == "location":
92
+ await self._handle_location_message(webhook, user_id)
93
+ elif message_type.lower() == "contacts":
94
+ await self._handle_contact_message(webhook, user_id)
95
+ else:
96
+ await self._handle_other_message(webhook, user_id, message_type)
97
+
98
+ except Exception as e:
99
+ logger.error(f"❌ Error handling {message_type} message: {e}")
100
+
101
+ async def _handle_text_message(
102
+ self, webhook: IncomingMessageWebhook, user_id: str, message_text: str
103
+ ) -> None:
104
+ """Handle text messages with simple echo."""
105
+
106
+ logger.info(f"💬 Echoing text: '{message_text}'")
107
+
108
+ # Create echo response
109
+ echo_response = f"🔄 Echo: {message_text}"
110
+
111
+ # Add some metadata for the first few messages
112
+ if self._message_count <= 3:
113
+ echo_response += (
114
+ f"\n\n📊 Message #{self._message_count} processed successfully!"
115
+ )
116
+ if self._message_count == 1:
117
+ echo_response += "\n👋 Welcome to the Simple Echo Example!"
118
+
119
+ # Send echo response
120
+ result = await self.messenger.send_text(
121
+ recipient=user_id,
122
+ text=echo_response,
123
+ reply_to_message_id=webhook.message.message_id,
124
+ )
125
+
126
+ if result.success:
127
+ logger.info(f"✅ Text echo sent successfully: {result.message_id}")
128
+ else:
129
+ logger.error(f"❌ Text echo failed: {result.error}")
130
+
131
+ async def _handle_media_message(
132
+ self, webhook: IncomingMessageWebhook, user_id: str, message_type: str
133
+ ) -> None:
134
+ """Handle media messages."""
135
+
136
+ logger.info(f"🎬 Processing {message_type} message")
137
+
138
+ response = f"📁 {message_type.title()} received! Simple echo doesn't download media, but message was processed successfully.\n\n📊 Total messages: {self._message_count}"
139
+
140
+ result = await self.messenger.send_text(
141
+ recipient=user_id,
142
+ text=response,
143
+ reply_to_message_id=webhook.message.message_id,
144
+ )
145
+
146
+ if result.success:
147
+ logger.info(f"✅ {message_type} response sent: {result.message_id}")
148
+ else:
149
+ logger.error(f"❌ {message_type} response failed: {result.error}")
150
+
151
+ async def _handle_location_message(
152
+ self, webhook: IncomingMessageWebhook, user_id: str
153
+ ) -> None:
154
+ """Handle location messages."""
155
+
156
+ logger.info("📍 Processing location message")
157
+
158
+ response = f"📍 Location received! Thanks for sharing your location.\n\n📊 Total messages: {self._message_count}"
159
+
160
+ result = await self.messenger.send_text(
161
+ recipient=user_id,
162
+ text=response,
163
+ reply_to_message_id=webhook.message.message_id,
164
+ )
165
+
166
+ if result.success:
167
+ logger.info(f"✅ Location response sent: {result.message_id}")
168
+ else:
169
+ logger.error(f"❌ Location response failed: {result.error}")
170
+
171
+ async def _handle_contact_message(
172
+ self, webhook: IncomingMessageWebhook, user_id: str
173
+ ) -> None:
174
+ """Handle contact messages."""
175
+
176
+ logger.info("👥 Processing contact message")
177
+
178
+ response = f"👥 Contact shared! Thanks for the contact information.\n\n📊 Total messages: {self._message_count}"
179
+
180
+ result = await self.messenger.send_text(
181
+ recipient=user_id,
182
+ text=response,
183
+ reply_to_message_id=webhook.message.message_id,
184
+ )
185
+
186
+ if result.success:
187
+ logger.info(f"✅ Contact response sent: {result.message_id}")
188
+ else:
189
+ logger.error(f"❌ Contact response failed: {result.error}")
190
+
191
+ async def _handle_other_message(
192
+ self, webhook: IncomingMessageWebhook, user_id: str, message_type: str
193
+ ) -> None:
194
+ """Handle other message types."""
195
+
196
+ logger.info(f"❓ Processing unsupported message type: {message_type}")
197
+
198
+ response = f"📨 {message_type.title()} message received! This message type is not fully supported yet, but was processed successfully.\n\n📊 Total messages: {self._message_count}"
199
+
200
+ result = await self.messenger.send_text(
201
+ recipient=user_id,
202
+ text=response,
203
+ reply_to_message_id=webhook.message.message_id,
204
+ )
205
+
206
+ if result.success:
207
+ logger.info(f"✅ {message_type} response sent: {result.message_id}")
208
+ else:
209
+ logger.error(f"❌ {message_type} response failed: {result.error}")
210
+
211
+ async def process_status(self, webhook: StatusWebhook) -> None:
212
+ """Process status webhooks with simple logging."""
213
+
214
+ status_value = webhook.status.value
215
+ recipient = webhook.recipient_id
216
+
217
+ logger.info(
218
+ f"📊 Status update: {status_value.upper()} for recipient {recipient}"
219
+ )
220
+
221
+ async def process_error(self, webhook: ErrorWebhook) -> None:
222
+ """Process error webhooks with simple logging."""
223
+
224
+ error_count = webhook.get_error_count()
225
+ primary_error = webhook.get_primary_error()
226
+
227
+ logger.error(
228
+ f"🚨 Platform error: {error_count} errors, "
229
+ f"primary: {primary_error.error_code} - {primary_error.error_title}"
230
+ )
@@ -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
+
@@ -1,10 +1,69 @@
1
- # Python-generated files
1
+ # Wappa
2
+ logs/
3
+
4
+ # Environment variables
5
+ .env
6
+ .env.local
7
+ .env.development
8
+ .env.production
9
+
10
+ # Python
2
11
  __pycache__/
3
- *.py[oc]
12
+ *.py[cod]
13
+ *$py.class
14
+ *.so
15
+ .Python
4
16
  build/
17
+ develop-eggs/
5
18
  dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
6
27
  wheels/
7
- *.egg-info
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
8
33
 
9
34
  # Virtual environments
10
- .venv
35
+ .venv/
36
+ venv/
37
+ ENV/
38
+ env/
39
+
40
+ # IDE
41
+ .vscode/
42
+ .idea/
43
+ *.swp
44
+ *.swo
45
+
46
+ # OS
47
+ .DS_Store
48
+ Thumbs.db
49
+
50
+ # Logs
51
+ app/logs/
52
+ logs/
53
+ *.log
54
+
55
+ # Redis dumps
56
+ dump.rdb
57
+
58
+ # Temporary files
59
+ .tmp/
60
+ temp/
61
+ tmp/
62
+
63
+ # Coverage reports
64
+ htmlcov/
65
+ .tox/
66
+ .coverage
67
+ .coverage.*
68
+ .cache
69
+ .pytest_cache/
@@ -0,0 +1,6 @@
1
+ """
2
+ Wappa Full Example Application Package
3
+
4
+ A comprehensive wappa framework example demonstrating all messaging features
5
+ with proper metadata extraction, interactive commands, and state management.
6
+ """
@@ -0,0 +1,5 @@
1
+ """
2
+ Message and command handlers for the Wappa Full Example application.
3
+
4
+ Contains handlers for different message types, special commands, and interactive states.
5
+ """