magickmind 0.1.1__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.
Files changed (43) hide show
  1. magick_mind/__init__.py +39 -0
  2. magick_mind/auth/__init__.py +9 -0
  3. magick_mind/auth/base.py +46 -0
  4. magick_mind/auth/email_password.py +268 -0
  5. magick_mind/client.py +188 -0
  6. magick_mind/config.py +28 -0
  7. magick_mind/exceptions.py +107 -0
  8. magick_mind/http/__init__.py +5 -0
  9. magick_mind/http/client.py +313 -0
  10. magick_mind/models/__init__.py +17 -0
  11. magick_mind/models/auth.py +30 -0
  12. magick_mind/models/common.py +32 -0
  13. magick_mind/models/errors.py +73 -0
  14. magick_mind/models/v1/__init__.py +83 -0
  15. magick_mind/models/v1/api_keys.py +115 -0
  16. magick_mind/models/v1/artifact.py +151 -0
  17. magick_mind/models/v1/chat.py +104 -0
  18. magick_mind/models/v1/corpus.py +82 -0
  19. magick_mind/models/v1/end_user.py +75 -0
  20. magick_mind/models/v1/history.py +94 -0
  21. magick_mind/models/v1/mindspace.py +130 -0
  22. magick_mind/models/v1/model.py +25 -0
  23. magick_mind/models/v1/project.py +73 -0
  24. magick_mind/realtime/__init__.py +5 -0
  25. magick_mind/realtime/client.py +202 -0
  26. magick_mind/realtime/handler.py +122 -0
  27. magick_mind/resources/README.md +201 -0
  28. magick_mind/resources/__init__.py +42 -0
  29. magick_mind/resources/base.py +31 -0
  30. magick_mind/resources/v1/__init__.py +19 -0
  31. magick_mind/resources/v1/api_keys.py +181 -0
  32. magick_mind/resources/v1/artifact.py +287 -0
  33. magick_mind/resources/v1/chat.py +120 -0
  34. magick_mind/resources/v1/corpus.py +156 -0
  35. magick_mind/resources/v1/end_user.py +181 -0
  36. magick_mind/resources/v1/history.py +88 -0
  37. magick_mind/resources/v1/mindspace.py +331 -0
  38. magick_mind/resources/v1/model.py +19 -0
  39. magick_mind/resources/v1/project.py +155 -0
  40. magick_mind/routes.py +76 -0
  41. magickmind-0.1.1.dist-info/METADATA +593 -0
  42. magickmind-0.1.1.dist-info/RECORD +43 -0
  43. magickmind-0.1.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,593 @@
1
+ Metadata-Version: 2.4
2
+ Name: magickmind
3
+ Version: 0.1.1
4
+ Summary: Official Python SDK for the MagickMind AI platform.
5
+ Project-URL: Homepage, https://magickmind.ai/
6
+ Project-URL: Documentation, https://docs.magickmind.ai/
7
+ Project-URL: Repository, https://github.com/General-Magick-Industries/py-magickmind
8
+ Project-URL: Issues, https://github.com/General-Magick-Industries/py-magickmind/issues
9
+ Project-URL: Changelog, https://github.com/General-Magick-Industries/py-magickmind/blob/main/CHANGELOG.md
10
+ Author-email: Adrian <adrian@magickmind.ai>, Minnie <minnie@magickmind.ai>, Turtle <turtle@magickmind.ai>
11
+ License-Expression: MIT
12
+ Keywords: ai,api,client,magickmind,sdk
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.12
22
+ Requires-Dist: centrifuge-python>=0.4.2
23
+ Requires-Dist: httpx>=0.27.0
24
+ Requires-Dist: jwt>=1.4.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Requires-Dist: pytest-asyncio>=1.3.0
27
+ Requires-Dist: python-dotenv>=1.2.1
28
+ Provides-Extra: dev
29
+ Requires-Dist: openapi-core>=0.19.0; extra == 'dev'
30
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
31
+ Requires-Dist: pytest-mock>=3.12.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Magick Mind SDK
36
+
37
+ Python SDK for seamless integration with the Magick Mind platform (Bifrost). This SDK provides type-safe, validated access to Bifrost's chat, mindspace, and realtime features.
38
+
39
+ > [!IMPORTANT]
40
+ > **Backend-Only SDK**
41
+ > This SDK is designed for **server-side applications only** and requires service-level authentication. It cannot be used directly by end users in browsers or mobile apps.
42
+ >
43
+ > **Architecture:** End Users → Your Backend (+ SDK) → Bifrost
44
+ > See [Backend Architecture Guide](docs/architecture/backend_architecture.md) for details.
45
+
46
+ ## Features
47
+
48
+ - 🔐 **Authentication**: Secure login with email/password
49
+ - 💬 **Chat**: Type-safe chat resource with Pydantic validation
50
+ - 🧠 **Mindspaces**: Manage AI reasoning contexts and conversations
51
+ - 📡 **Realtime**: WebSocket client for live AI responses with deduplication
52
+ - 🔑 **Typed Resources**: Mindspaces, Projects, Corpus, API Keys, Artifacts, End Users, History
53
+ - ✅ **Validation**: Automatic request/response validation with Pydantic
54
+ - 🎯 **Developer Experience**: Clean, intuitive API design
55
+ - Desktop applications (PyQt, Tkinter, wxPython)
56
+ - CLI tools and automation scripts
57
+ - Server-side scripts
58
+ - **Robotics/IoT (Self-Service)**: Single device authenticates and subscribes to its own channel
59
+
60
+ **For web/mobile frontends:** If you're building browser-based apps or native mobile apps, you would need JavaScript, Swift, or Kotlin SDKs (not yet available). This Python SDK is for your backend.
61
+
62
+ **Common architecture:**
63
+ ```
64
+ [Your Frontend/App] ←→ [Your Backend + This SDK] ←→ [Bifrost SaaS]
65
+ ```
66
+
67
+ **Robotics/IoT (Self-Service):**
68
+ ```
69
+ [Robot/Device with SDK] ←→ [Bifrost SaaS]
70
+ ```
71
+ In this pattern, the device authenticates as itself and subscribes to its own channel. See [Event-Driven Patterns](docs/architecture/event_driven_patterns.md#self-service-pattern-roboticsiot) for details.
72
+
73
+
74
+ ## Installation
75
+
76
+ Using `uv` (recommended):
77
+
78
+ ```bash
79
+ cd AGD_Magick_Mind_SDK
80
+ uv sync
81
+ ```
82
+
83
+ Using pip:
84
+
85
+ ```bash
86
+ cd AGD_Magick_Mind_SDK
87
+ pip install -e .
88
+ ```
89
+
90
+ ## Core Concepts
91
+
92
+ ### Mindspaces: The Central Hub
93
+
94
+ **Mindspace is the central organizing concept in Bifrost** - it's where conversations, knowledge, and collaboration converge. When designing your application architecture, start by thinking about mindspaces:
95
+
96
+ - **All chat conversations happen within a mindspace**
97
+ - **Knowledge (corpus) attaches to mindspaces** to provide context for AI responses
98
+ - **Users collaborate through mindspaces** (private for individuals, group for teams)
99
+ - **Everything connects through mindspaces** - projects, messages, artifacts
100
+
101
+ ```mermaid
102
+ graph LR
103
+ U[Users] --> MS[Mindspace]
104
+ C[Corpus/Knowledge] --> MS
105
+ MS --> Chat[Conversations]
106
+ MS --> History[Message History]
107
+ P[Projects] -.organize.-> MS
108
+
109
+ style MS fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#fff
110
+ ```
111
+
112
+ **Architectural Implication**: When building with Bifrost, most operations reference a `mindspace_id`. This is by design - mindspaces provide the context and scope for AI interactions.
113
+
114
+ 📖 **Learn more:** [Mindspace Resource Guide](docs/resources/mindspace.md)
115
+
116
+ ## Quick Start
117
+
118
+ ### Authentication
119
+
120
+ The SDK uses **email/password authentication** which calls bifrost's `/v1/auth/login` endpoint:
121
+
122
+ ```python
123
+ from magick_mind import MagickMind
124
+
125
+ # Create client with email/password
126
+ client = MagickMind(
127
+ email="user@example.com",
128
+ password="your_password",
129
+ base_url="https://bifrost.example.com"
130
+ )
131
+
132
+ # Authentication happens automatically on first API call
133
+ # Tokens are automatically refreshed when needed
134
+ print(f"Authenticated: {client.is_authenticated()}")
135
+ ```
136
+
137
+ > **Note**: The `api_key` you might see in chat requests is **not for SDK authentication**.
138
+ > It's a parameter you pass when calling LLM endpoints (for tracking/billing).
139
+ > The SDK itself authenticates with JWT tokens from `/v1/auth/login`.
140
+
141
+ ### Making API Calls
142
+
143
+ ```python
144
+ # Once authenticated, use the HTTP client to make requests
145
+ # The client automatically adds authentication headers
146
+
147
+ # POST request
148
+ response = client.http.post(
149
+ "/v1/magickmind/chat",
150
+ json={
151
+ "api_key": "sk-your-llm-key",
152
+ "message": "Hello!",
153
+ "chat_id": "chat-123",
154
+ "sender_id": "user-456"
155
+ }
156
+ )
157
+
158
+ # GET request
159
+ response = client.http.get("/v1/some-endpoint")
160
+ ```
161
+
162
+ ### Context Manager
163
+
164
+ ```python
165
+ # Use as context manager for automatic cleanup
166
+ with MagickMind(email="user@example.com", password="pass", base_url="...") as client:
167
+ response = client.http.get("/v1/endpoint")
168
+ # Client automatically closes when exiting context
169
+ ```
170
+
171
+ ## HTTP Client for Power Users
172
+
173
+ The `client.http` property provides direct access to the authenticated HTTP client. This is intended for:
174
+
175
+ **Bifrost Developers:**
176
+ - Testing new endpoints before implementing resources
177
+ - Experimenting with beta/experimental features
178
+ - Quick prototyping
179
+
180
+ **Power Users:**
181
+ - Direct API access without waiting for typed resources
182
+ - One-off calls or custom integrations
183
+
184
+ ```python
185
+ # Test experimental endpoint
186
+ response = client.http.post(
187
+ "/beta/new-feature",
188
+ json={"test": "data"}
189
+ )
190
+
191
+ # Mix versions in same app
192
+ v1_response = client.http.post("/v1/magickmind/chat", json={...})
193
+ beta_response = client.http.post("/beta/magickmind/chat", json={...})
194
+ ```
195
+
196
+ The HTTP client automatically handles:
197
+ - ✅ Authentication token injection
198
+ - ✅ Token refresh when expired
199
+ - ✅ Error mapping to SDK exceptions
200
+ - ✅ Same configuration as main client
201
+
202
+ ## Authentication
203
+
204
+ The SDK uses **email/password authentication** with JWT tokens:
205
+
206
+ Uses bifrost's `/v1/auth/login` endpoint. Automatically handles:
207
+ - Initial login
208
+ - Token caching
209
+ - Automatic token refresh using refresh_token
210
+ - Re-authentication when refresh token expires
211
+
212
+ ```python
213
+ client = MagickMind(
214
+ email="your@email.com",
215
+ password="your_password",
216
+ base_url="https://bifrost.example.com"
217
+ )
218
+ ```
219
+
220
+ ### About API Keys
221
+
222
+ If you see `api_key` in documentation or code examples, note that this is **NOT for authenticating the SDK**.
223
+ The `api_key` is a parameter you pass when calling specific endpoints (like chat) for LLM access:
224
+
225
+ ```python
226
+ # SDK authenticates with email/password (JWT)
227
+ client = MagickMind(email="...", password="...", base_url="...")
228
+
229
+ # api_key is passed as a parameter to LLM endpoints
230
+ # response = client.chat(api_key="your-llm-api-key", message="Hello")
231
+ ```
232
+
233
+
234
+ ## Examples
235
+
236
+ See the `examples/` directory for complete working examples:
237
+
238
+ - `examples/email_password_auth.py` - Email/password with auto-refresh
239
+ - `examples/backend_service.py` - Production-ready backend service pattern
240
+ - `examples/chat_example.py` - Using the typed chat resource
241
+
242
+ Run example:
243
+
244
+ ```bash
245
+ # Set environment variables
246
+ export BIFROST_BASE_URL="http://localhost:8888"
247
+ export BIFROST_EMAIL="user@example.com"
248
+ export BIFROST_PASSWORD="your_password"
249
+
250
+ # Run example
251
+ uv run python examples/email_password_auth.py
252
+ ```
253
+
254
+ ## Backend Integration
255
+
256
+ If you're building a **backend service** that uses this SDK as middleware (e.g., your backend receives data from Bifrost and manages state for your own frontend), see:
257
+
258
+ 📖 **[Backend Integration Guide](docs/guides/backend_integration.md)**
259
+
260
+ Covers production patterns for:
261
+ - Message deduplication
262
+ - Hybrid realtime + HTTP sync
263
+ - Recovery from disconnects
264
+ - Reliable message processing
265
+
266
+ Example backend service:
267
+ ```python
268
+ from magick_mind import MagickMind
269
+ from examples.backend_service import ChatBackendService
270
+
271
+ client = MagickMind(email="...", password="...", base_url="...")
272
+ service = ChatBackendService(client)
273
+
274
+ # Handles realtime events + periodic sync for reliability
275
+ await service.start(mindspace_id="mind-123", user_id="service-user")
276
+ ```
277
+
278
+ ## Event-Driven Architecture
279
+
280
+ The SDK supports event-driven patterns with both realtime WebSocket events and HTTP APIs.
281
+
282
+ 📖 **[Event-Driven Patterns Guide](docs/architecture/event_driven_patterns.md)**
283
+
284
+ Learn about:
285
+ - Events as source of truth (current Bifrost)
286
+ - Events as notifications (industry standard)
287
+ - Hybrid approaches for production
288
+ - Migration paths
289
+
290
+ ## Realtime WebSocket Client
291
+
292
+ The SDK provides a powerful realtime client for receiving live updates via WebSocket. This is essential for building reactive applications that need instant notifications.
293
+
294
+ ### Quick Example
295
+
296
+ ```python
297
+ import asyncio
298
+ from magick_mind import MagickMind
299
+ from magick_mind.realtime.handler import RealtimeEventHandler
300
+
301
+ class MyHandler(RealtimeEventHandler):
302
+ async def on_message(self, user_id: str, payload):
303
+ # Automatically receives parsed messages
304
+ print(f"Update for {user_id}: {payload}")
305
+
306
+ async def main():
307
+ client = MagickMind(
308
+ email="user@example.com",
309
+ password="password",
310
+ base_url="https://bifrost.example.com",
311
+ ws_endpoint="wss://bifrost.example.com/connection/websocket"
312
+ )
313
+
314
+ # Connect with handler
315
+ await client.realtime.connect(events=MyHandler())
316
+
317
+ # Subscribe to users (creates per-user channels)
318
+ await client.realtime.subscribe_many(["user-1", "user-2", "user-3"])
319
+
320
+ # Keep listening...
321
+ await asyncio.sleep(60)
322
+
323
+ asyncio.run(main())
324
+ ```
325
+
326
+ ### Key Features
327
+
328
+ - **Per-User Subscriptions** - Each user gets their own secure channel
329
+ - **Bulk Operations** - `subscribe_many()` for handling 100s of users efficiently
330
+ - **Auto-Reconnect** - Centrifugo handles connection recovery automatically
331
+ - **Type-Safe Handlers** - `RealtimeEventHandler` provides clean callback interface
332
+
333
+ ### Architecture: Per-User Pattern
334
+
335
+ When building relay services or multi-user applications, the SDK uses a **per-user subscription model**:
336
+
337
+ - **500 users = 500 subscriptions** (not 1 room channel)
338
+ - Each user has an isolated subscription
339
+ - Ensures privacy, security, and efficient server-side filtering
340
+ - Single WebSocket connection multiplexes all subscriptions
341
+
342
+ **Why 500 subscriptions is correct:**
343
+ - 🔒 Security: Users can't see each other's data
344
+ - 📊 Efficiency: Server only sends relevant messages
345
+ - 📈 Scalable: Centrifugo handles millions of channels
346
+
347
+ 📖 **[Complete Realtime Guide](docs/realtime_guide.md)** - Covers subscription patterns, bulk operations, error handling, and relay service architecture.
348
+
349
+ ## Extending the SDK
350
+
351
+ The SDK currently provides authentication and HTTP client foundation. Want to add typed resource clients (e.g., `client.chat.send(...)`)?
352
+
353
+ See **[docs/contributing/resource_implementation_guide/](docs/contributing/resource_implementation_guide/)** for a complete reference implementation showing:
354
+
355
+ - ✅ Pydantic models for request/response validation
356
+ - ✅ Version-aware resource classes (v1, v2)
357
+ - ✅ Clean namespace pattern (`client.v1.chat`, `client.v2.chat`)
358
+ - ✅ Working usage examples
359
+
360
+ This serves as a template for adding chat, history, users, or any other resources to the SDK.
361
+
362
+ ## Future Plans
363
+
364
+ ### Versioned Resources
365
+
366
+ When resources are implemented, they will follow a namespace pattern:
367
+
368
+ ```python
369
+ client = MagickMind(...)
370
+
371
+ # Explicit version access
372
+ client.v1.chat.send(...) # Always v1 (stable)
373
+ client.v2.chat.send(...) # Always v2 (new features)
374
+ client.beta.chat.send(...) # Beta/experimental
375
+
376
+ # Mix and match versions
377
+ client.v1.history.list(...) # Use stable for some endpoints
378
+ client.beta.chat.send(...) # Test beta for others
379
+ ```
380
+
381
+ **Key principles:**
382
+ - **Explicit over implicit** - Users choose exact version
383
+ - **Type safe** - Each version has different request/response types
384
+ - **Mix-and-match** - Can use different versions for different endpoints
385
+ - **Sparse coverage** - Only implement resources that exist in bifrost
386
+ - Example: If `/beta/chat` exists but `/beta/history` doesn't, `client.beta` only has `chat`
387
+
388
+ **Why this approach:**
389
+ - Safe gradual migration (v1 → v2)
390
+ - Test breaking changes before full adoption
391
+ - Clear which version you're using
392
+ - No surprises when SDK updates
393
+
394
+ ### Example Usage Scenarios
395
+
396
+ **Scenario 1: Production app using stable v1**
397
+ ```python
398
+ client = MagickMind(...)
399
+
400
+ # All endpoints use v1
401
+ response = client.v1.chat.send(...)
402
+ history = client.v1.history.list(...)
403
+ user = client.v1.users.get(...)
404
+ ```
405
+
406
+ **Scenario 2: Testing beta chat, keeping others stable**
407
+ ```python
408
+ client = MagickMind(...)
409
+
410
+ # Test new chat features
411
+ response = client.beta.chat.send(
412
+ message="...",
413
+ temperature=0.8, # New parameter in beta
414
+ context={...} # New context support
415
+ )
416
+
417
+ # Keep other endpoints stable
418
+ history = client.v1.history.list(...)
419
+ user = client.v1.users.get(...)
420
+ ```
421
+
422
+ **Scenario 3: Gradual migration v1 → v2**
423
+ ```python
424
+ # Week 1: Start migrating chat to v2
425
+ response = client.v2.chat.send(...) # Migrated
426
+ history = client.v1.history.list(...) # Still v1
427
+
428
+ # Week 2: Migrate more endpoints
429
+ history = client.v2.history.list(...) # Migrated
430
+ user = client.v1.users.get(...) # Still v1
431
+
432
+ # Week 3: Fully migrated
433
+ # All endpoints now use v2
434
+ ```
435
+
436
+ **Scenario 4: Bifrost dev testing experimental endpoint**
437
+ ```python
438
+ client = MagickMind(...)
439
+
440
+ # Test endpoint that doesn't have resource yet
441
+ response = client.http.post(
442
+ "/experimental/ai-agents",
443
+ json={"task": "analyze data"}
444
+ )
445
+
446
+ # Use typed resources for stable endpoints
447
+ chat = client.v1.chat.send(...)
448
+ ```
449
+
450
+ ### Default Shortcuts (Future)
451
+
452
+ For convenience, SDK may add `client.chat` shortcuts that point to a default version:
453
+
454
+ **SDK 1.x series:**
455
+ ```python
456
+ client = MagickMind(...)
457
+
458
+ # Shortcuts point to v1 (stable)
459
+ client.chat.send(...) # → client.v1.chat.send(...)
460
+ client.history.list(...) # → client.v1.history.list(...)
461
+
462
+ # Explicit always available
463
+ client.v1.chat.send(...) # Explicit v1
464
+ client.v2.chat.send(...) # Explicit v2 (when available)
465
+ ```
466
+
467
+ **SDK 2.x series (breaking change):**
468
+ ```python
469
+ client = MagickMind(...)
470
+
471
+ # Shortcuts now point to v2 (BREAKING!)
472
+ client.chat.send(...) # → client.v2.chat.send(...)
473
+
474
+ # Explicit v1 still works
475
+ client.v1.chat.send(...) # Pin to v1 for stability
476
+ ```
477
+
478
+ **Best practice:** Use explicit versions (`client.v1.chat`) for production code that needs stability.
479
+
480
+ ### Deprecation and Migration
481
+
482
+ When bifrost deprecates an API version, SDK will follow this pattern:
483
+
484
+ **Phase 1: Deprecation Warning**
485
+ ```python
486
+ # SDK 1.5: v1 still works but warns
487
+ response = client.v1.chat.send(...)
488
+ # Warning: v1 chat API is deprecated, migrate to v2 by 2025-06-01
489
+ ```
490
+
491
+ **Phase 2: Both Versions Co-exist**
492
+ ```python
493
+ # SDK 1.x: Both v1 and v2 available
494
+ client.v1.chat.send(...) # Deprecated but works
495
+ client.v2.chat.send(...) # Recommended
496
+ ```
497
+
498
+ **Phase 3: Removal in Next Major Version**
499
+ ```python
500
+ # SDK 2.0: v1 removed
501
+ client.v1.chat.send(...) # ❌ AttributeError
502
+ client.v2.chat.send(...) # ✅ Works
503
+ ```
504
+
505
+ **Migration guide provided in CHANGELOG for each breaking change.**
506
+
507
+ ## Error Handling
508
+
509
+ The SDK provides specific exceptions for different error scenarios:
510
+
511
+ ```python
512
+ from magick_mind import (
513
+ MagickMind,
514
+ AuthenticationError,
515
+ TokenExpiredError,
516
+ ProblemDetailsException,
517
+ ValidationError,
518
+ RateLimitError
519
+ )
520
+
521
+ try:
522
+ client = MagickMind(email="user@example.com", password="wrong", base_url="...")
523
+ response = client.http.get("/v1/endpoint")
524
+ except AuthenticationError as e:
525
+ print(f"Authentication failed: {e}")
526
+ except TokenExpiredError as e:
527
+ print(f"Token expired: {e}")
528
+ except RateLimitError as e:
529
+ print(f"Rate limited: {e}")
530
+ except ValidationError as e:
531
+ # Handle field-level validation errors (400 Bad Request)
532
+ print(f"Validation error: {e.detail}")
533
+ for field, errors in e.get_field_errors().items():
534
+ print(f" {field}: {', '.join(errors)}")
535
+ except ProblemDetailsException as e:
536
+ # Handle other API errors (RFC 7807 Problem Details)
537
+ print(f"API error: {e.title} - {e.detail}")
538
+ print(f"Request ID: {e.request_id}") # For support tickets
539
+ ```
540
+
541
+ ### Error Quick Reference
542
+
543
+ | Exception | Typical Cause | Key Attributes | Recovery Action |
544
+ |-----------|---------------|----------------|-----------------|
545
+ | `AuthenticationError` | Invalid credentials | `message`, `status_code` | Check email/password and re-authenticate |
546
+ | `TokenExpiredError` | Token expired | `message` | Auto-refreshed by SDK transparently |
547
+ | `ValidationError` | Bad request data | `get_field_errors()`, `request_id` | Fix input using field error details |
548
+ | `ProblemDetailsException` | API error (4xx, 5xx) | `status`, `title`, `detail`, `request_id` | Check detail message and request_id |
549
+ | `RateLimitError` | Rate limit exceeded | `status_code` (429) | Retry with exponential backoff |
550
+
551
+ > [!IMPORTANT]
552
+ > **Always log `request_id`** from `ProblemDetailsException` - it's essential for support tickets and debugging with the Bifrost team.
553
+
554
+ 📖 **[Complete Error Handling Guide](docs/guides/error_handling.md)** - Comprehensive guide with error catalog, retry patterns, and production examples.
555
+
556
+
557
+ ## Configuration
558
+
559
+ Customize SDK behavior:
560
+
561
+ ```python
562
+ client = MagickMind(
563
+ email="user@example.com",
564
+ password="password",
565
+ base_url="https://bifrost.example.com",
566
+ timeout=60.0, # Request timeout in seconds (default: 30.0)
567
+ verify_ssl=True # Verify SSL certificates (default: True)
568
+ )
569
+ ```
570
+
571
+ ## Development
572
+
573
+ ### Install development dependencies
574
+
575
+ ```bash
576
+ uv sync --all-extras
577
+ ```
578
+
579
+ ### Run tests
580
+
581
+ ```bash
582
+ uv run pytest tests/ -v
583
+ ```
584
+
585
+ ## License
586
+
587
+ MIT License - see LICENSE file for details.
588
+
589
+ ## Authors
590
+
591
+ - Adrian (minoak@globalmagicko.com)
592
+ - Turtle (turtle@globalmagicko.com)
593
+ - Min Thu Wai (minthu@globalmagicko.com)
@@ -0,0 +1,43 @@
1
+ magick_mind/__init__.py,sha256=fz_qJ7sdA12ve_pD2ARooKa6Prr4fi8YSRoLDcOsfZA,846
2
+ magick_mind/client.py,sha256=onfrxVP57McbZ5liJnHKNtDUIrDwqhikZxEJeBkN-3c,5980
3
+ magick_mind/config.py,sha256=qpDvHpiySxdpNK_IMYphFgo5CIDHVmrbFksVN_MW5r8,734
4
+ magick_mind/exceptions.py,sha256=V2-sG12wFSWCEgL09_6fNeNRYGd3YaiPx3CzwHewwXY,3357
5
+ magick_mind/routes.py,sha256=0_qQFe5U0z28EL26HpugtzTYJ0hfz-OP6Da-ZTDIWwk,2129
6
+ magick_mind/auth/__init__.py,sha256=KFVQgzRKOFQMet4xuWRDoz3olOxT2cBPGaHergrvBpk,219
7
+ magick_mind/auth/base.py,sha256=hOv7pIkGJWIyTTNiETi9tZUeSJNVgeaaWbKGpCwmIdg,1069
8
+ magick_mind/auth/email_password.py,sha256=Hp7PsyLTBzJ0DsVCq22TBwLZfpjGHO0LuZ7RRp6NugU,10084
9
+ magick_mind/http/__init__.py,sha256=_1xtQBZQ9JX-T3Bqauwr57ujHbW5xrXjnmWdAZ5UG44,120
10
+ magick_mind/http/client.py,sha256=-TIPzYclS8OZbUWxFPW5epli870z7I9shahq_hJN4Fw,10072
11
+ magick_mind/models/__init__.py,sha256=zXmYoh8-LC10d7sWcWBC2DtBGvP3_dy7Z64NDqwyBvE,393
12
+ magick_mind/models/auth.py,sha256=O23zq-mWRIHVznxkUmSoGQjUSAecdF7wpUbQ8ITESCk,618
13
+ magick_mind/models/common.py,sha256=BGnziCXSimYNvfB9rtkhhK4xjKkqeWuCq2vmo9o1LaA,940
14
+ magick_mind/models/errors.py,sha256=CL31vPvULvv_Jc1p0PMIAizGIw7zP9NozoK-bMic1l0,2312
15
+ magick_mind/models/v1/__init__.py,sha256=HH19PeDY1TRDPYMz_qQjQ3ngCdqKBlylY9CXdaU_VeM,2064
16
+ magick_mind/models/v1/api_keys.py,sha256=31n8HZc1VDd2esnO4r-1LNY2WGod6oyk8Qqe2xvx2rs,4015
17
+ magick_mind/models/v1/artifact.py,sha256=dE1O6H2bDaGRz_nTDZw8ssBlzPDXZCuVMrKLO6wKzAE,6040
18
+ magick_mind/models/v1/chat.py,sha256=UuGs66LBeVh_Vpdga0XX72Wsx42MS7YuuX1VK-CC0aI,3408
19
+ magick_mind/models/v1/corpus.py,sha256=71YhJd173b2XuPAD9Av3KNXWsuGHFyjB8oOd3n4bRRE,2522
20
+ magick_mind/models/v1/end_user.py,sha256=PmRn5Frhg-QZnhH5--eqgivk8uzskk5Cdea1pIZm7UE,2379
21
+ magick_mind/models/v1/history.py,sha256=Z32rCzSIpyoBUN1siYPfoLyR5Di__1uZoZQAuFmqeJE,2831
22
+ magick_mind/models/v1/mindspace.py,sha256=Hw-zjUif36a4RAhZZxXfHdjUHa9qGd0jBDf5U4fp_yk,4101
23
+ magick_mind/models/v1/model.py,sha256=7lBcyxwupGVkmeJ_5qWdMi4n8cTMMOtoSiIIXBcXkR4,876
24
+ magick_mind/models/v1/project.py,sha256=J0MhVOjqnGXA8waC1tTaZ2JzVqin_cHP_n1GSK3Qiuw,2215
25
+ magick_mind/realtime/__init__.py,sha256=AXxK__ZqHX0iaCQnkPsmpmuTkWQnqBm8JAx8gAUbjoQ,132
26
+ magick_mind/realtime/client.py,sha256=RoUW65df2y28V6T3klBIqrAtrWKI8xq8dqo9pDzT2JY,6817
27
+ magick_mind/realtime/handler.py,sha256=ovq35YrKHyAGrEFdGBSqvEpP4JfCAiXzDmXyPyXMAuU,3932
28
+ magick_mind/resources/README.md,sha256=idxTiaQWJW1o3hC6WBIoeTlX6nDr4AsqzE6ELppJuy8,5712
29
+ magick_mind/resources/__init__.py,sha256=6JUxgJQFUFvzMLADCPp1kQV9UJBT87z8oXnxkgBsrvc,1609
30
+ magick_mind/resources/base.py,sha256=UYyddfgGFbdv9m8dljBNeKOIbj1zT1h9L8kQKrJ43Fg,850
31
+ magick_mind/resources/v1/__init__.py,sha256=YloUAmuSFWH26cyv5y-QFdqeHYNTKuXsG_oNwrxh4EY,655
32
+ magick_mind/resources/v1/api_keys.py,sha256=AfVA9DFCnmen7Py-g5KOo1ILNuxbBY8ZX8WM9ll_liw,5078
33
+ magick_mind/resources/v1/artifact.py,sha256=XZ-vEPGilG88xZUjkPApa2fXfGDiSfs_Z3KDPfcVAz4,9145
34
+ magick_mind/resources/v1/chat.py,sha256=L38T85eypvosau4zZU3s4_fXcB4wdwGAjnO3f7ZOApM,4030
35
+ magick_mind/resources/v1/corpus.py,sha256=bn3bwh2eUbswksFX5-3uX6gOBOmfn5FrtcREo9SqouQ,3732
36
+ magick_mind/resources/v1/end_user.py,sha256=26IVghTh-1ChLICU_ymEE8RBeGNyWFnY0H_qUSUiwnk,5259
37
+ magick_mind/resources/v1/history.py,sha256=LYMZshDRxrOnMeIOKfikHxyetVQta-LIfEcCmxky-Hw,2791
38
+ magick_mind/resources/v1/mindspace.py,sha256=NiGsu-Rei9pXrxHN_Gp3-AkoVK2W4zwjja1H2inn2cg,10358
39
+ magick_mind/resources/v1/model.py,sha256=b7sIfm8uciE3C6rjWWaLJltgmdbfgIWB09Kra3gzCoY,549
40
+ magick_mind/resources/v1/project.py,sha256=kYcGMYyrjxj_nOcmt0ldNXneNct47CfJrFD25EhB6-g,4522
41
+ magickmind-0.1.1.dist-info/METADATA,sha256=XWjHK_hEnH6Wx6V90N5BIMLsaCDWaDu2Q9m-SCf-h-w,18864
42
+ magickmind-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
43
+ magickmind-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any