chuk-artifacts 0.1.2__py3-none-any.whl → 0.1.4__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.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chuk-artifacts
3
- Version: 0.1.2
4
- Summary: Add your description here
3
+ Version: 0.1.4
4
+ Summary: Chuk Artifacts provides a production-ready, modular artifact storage system that works seamlessly across multiple storage backends (memory, filesystem, AWS S3, IBM Cloud Object Storage) with Redis or memory-based metadata caching and strict session-based security.
5
5
  License: MIT
6
6
  Requires-Python: >=3.11
7
7
  Description-Content-Type: text/markdown
@@ -12,7 +12,7 @@ Requires-Dist: pyyaml>=6.0.2
12
12
  Requires-Dist: aioboto3>=14.3.0
13
13
  Requires-Dist: redis>=6.2.0
14
14
  Requires-Dist: ibm-cos-sdk>=2.13.5
15
- Requires-Dist: chuk-sessions>=0.1.0
15
+ Requires-Dist: chuk-sessions>=0.1.1
16
16
  Provides-Extra: websocket
17
17
  Requires-Dist: websockets>=10.0; extra == "websocket"
18
18
  Provides-Extra: dev
@@ -23,20 +23,21 @@ Dynamic: license-file
23
23
 
24
24
  # Chuk Artifacts
25
25
 
26
- [![Tests](https://img.shields.io/badge/tests-64%2F64%20passing-brightgreen)](https://github.com/your-org/chuk-artifacts)
26
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](https://github.com/your-org/chuk-artifacts)
27
27
  [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://python.org)
28
28
  [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
29
29
 
30
- **Asynchronous, multi-backend artifact storage with session-based security and presigned URLs**
30
+ **Asynchronous, multi-backend artifact storage with mandatory session-based security and grid architecture**
31
31
 
32
32
  Chuk Artifacts provides a production-ready, modular artifact storage system that works seamlessly across multiple storage backends (memory, filesystem, AWS S3, IBM Cloud Object Storage) with Redis or memory-based metadata caching and **strict session-based security**.
33
33
 
34
34
  ## ✨ Key Features
35
35
 
36
- - 🏗️ **Modular Architecture**: 6 specialized operation modules for clean separation of concerns
37
- - 🔒 **Session-Based Security**: Strict isolation with no cross-session operations allowed
36
+ - 🏗️ **Modular Architecture**: 5 specialized operation modules for clean separation of concerns
37
+ - 🔒 **Mandatory Session Security**: Strict isolation with no anonymous artifacts or cross-session operations
38
+ - 🌐 **Grid Architecture**: `grid/{sandbox_id}/{session_id}/{artifact_id}` paths for federation-ready organization
38
39
  - 🔄 **Multi-Backend Support**: Memory, filesystem, S3, IBM COS with seamless switching
39
- - ⚡ **Fully Async**: Built with async/await for high performance (3,000+ ops/sec)
40
+ - ⚡ **High Performance**: Built with async/await for high throughput (3,000+ ops/sec)
40
41
  - 🔗 **Presigned URLs**: Secure, time-limited access without credential exposure
41
42
  - 📊 **Batch Operations**: Efficient multi-file uploads and processing
42
43
  - 🗃️ **Metadata Caching**: Fast lookups with Redis or memory-based sessions
@@ -60,61 +61,61 @@ uv add chuk-artifacts
60
61
  from chuk_artifacts import ArtifactStore
61
62
 
62
63
  # Zero-config setup (uses memory provider)
63
- store = ArtifactStore()
64
-
65
- # Store an artifact
66
- artifact_id = await store.store(
67
- data=b"Hello, world!",
68
- mime="text/plain",
69
- summary="A simple greeting",
70
- filename="hello.txt",
71
- session_id="user_123" # Session-based isolation
72
- )
73
-
74
- # Retrieve it
75
- data = await store.retrieve(artifact_id)
76
- print(data.decode()) # "Hello, world!"
77
-
78
- # Generate a presigned URL
79
- download_url = await store.presign_medium(artifact_id) # 1 hour
64
+ async with ArtifactStore() as store:
65
+ # Store an artifact (session auto-allocated)
66
+ artifact_id = await store.store(
67
+ data=b"Hello, world!",
68
+ mime="text/plain",
69
+ summary="A simple greeting",
70
+ filename="hello.txt"
71
+ # session_id auto-allocated if not provided
72
+ )
73
+
74
+ # Retrieve it
75
+ data = await store.retrieve(artifact_id)
76
+ print(data.decode()) # "Hello, world!"
77
+
78
+ # Generate a presigned URL
79
+ download_url = await store.presign_medium(artifact_id) # 1 hour
80
80
  ```
81
81
 
82
82
  ### Session-Based File Management
83
83
 
84
84
  ```python
85
- # Create files in user sessions
86
- doc_id = await store.write_file(
87
- content="# User's Document\n\nPrivate content here.",
88
- filename="docs/private.md",
89
- mime="text/markdown",
90
- session_id="user_alice"
91
- )
92
-
93
- # List files in a session
94
- files = await store.list_by_session("user_alice")
95
- print(f"Alice has {len(files)} files")
96
-
97
- # List directory-like contents
98
- docs = await store.get_directory_contents("user_alice", "docs/")
99
- print(f"Alice's docs: {len(docs)} files")
100
-
101
- # Copy within same session (allowed)
102
- backup_id = await store.copy_file(
103
- doc_id,
104
- new_filename="docs/private_backup.md"
105
- )
106
-
107
- # Cross-session operations are BLOCKED for security
108
- try:
109
- await store.copy_file(
110
- doc_id,
111
- target_session_id="user_bob" # This will fail
85
+ async with ArtifactStore() as store:
86
+ # Create files in user sessions
87
+ doc_id = await store.write_file(
88
+ content="# User's Document\n\nPrivate content here.",
89
+ filename="docs/private.md",
90
+ mime="text/markdown",
91
+ session_id="user_alice"
112
92
  )
113
- except ArtifactStoreError:
114
- print("Cross-session operations blocked!")
93
+
94
+ # List files in a session
95
+ files = await store.list_by_session("user_alice")
96
+ print(f"Alice has {len(files)} files")
97
+
98
+ # List directory-like contents
99
+ docs = await store.get_directory_contents("user_alice", "docs/")
100
+ print(f"Alice's docs: {len(docs)} files")
101
+
102
+ # Copy within same session (allowed)
103
+ backup_id = await store.copy_file(
104
+ doc_id,
105
+ new_filename="docs/private_backup.md"
106
+ )
107
+
108
+ # Cross-session operations are BLOCKED for security
109
+ try:
110
+ await store.copy_file(
111
+ doc_id,
112
+ target_session_id="user_bob" # This will fail
113
+ )
114
+ except ArtifactStoreError:
115
+ print("✅ Cross-session operations blocked!")
115
116
  ```
116
117
 
117
- ### With Configuration
118
+ ### Configuration
118
119
 
119
120
  ```python
120
121
  # Production setup with S3 and Redis
@@ -134,29 +135,56 @@ store = ArtifactStore(
134
135
  store = ArtifactStore() # Auto-loads configuration
135
136
  ```
136
137
 
137
- ## 🏗️ Architecture
138
+ ## 🏗️ Modular Architecture
138
139
 
139
- Chuk Artifacts uses a modular architecture with specialized operation modules:
140
+ Chuk Artifacts uses a clean modular architecture with specialized operation modules:
140
141
 
141
142
  ```
142
143
  ArtifactStore (Main Coordinator)
143
144
  ├── CoreStorageOperations # store() and retrieve()
144
- ├── PresignedURLOperations # URL generation and upload workflows
145
- ├── MetadataOperations # metadata, exists, delete, update, list_by_session
146
- ├── SessionOperations # session-based file operations (NEW)
145
+ ├── MetadataOperations # metadata, exists, delete, update, list operations
146
+ ├── PresignedURLOperations # URL generation and upload workflows
147
147
  ├── BatchOperations # store_batch() for multiple files
148
148
  └── AdminOperations # validate_configuration, get_stats
149
149
  ```
150
150
 
151
+ ### Grid Architecture
152
+
153
+ All artifacts are organized using a consistent grid structure:
154
+
155
+ ```
156
+ grid/{sandbox_id}/{session_id}/{artifact_id}
157
+ ```
158
+
159
+ **Benefits:**
160
+ - **Federation Ready**: Cross-sandbox discovery and routing
161
+ - **Session Isolation**: Clear boundaries for security
162
+ - **Predictable Paths**: Easy to understand and manage
163
+ - **Scalable**: Handles multi-tenant applications
164
+
151
165
  This design provides:
152
166
  - **Better testability**: Each module can be tested independently
153
167
  - **Enhanced maintainability**: Clear separation of concerns
154
168
  - **Easy extensibility**: Add new operation types without touching core
155
169
  - **Improved debugging**: Isolated functionality for easier troubleshooting
156
- - **Session security**: Dedicated module for secure session operations
157
170
 
158
171
  ## 🔒 Session-Based Security
159
172
 
173
+ ### Mandatory Sessions
174
+ ```python
175
+ # Every artifact belongs to a session - no anonymous artifacts
176
+ artifact_id = await store.store(
177
+ data=b"content",
178
+ mime="text/plain",
179
+ summary="description"
180
+ # session_id auto-allocated if not provided
181
+ )
182
+
183
+ # Get the session it was allocated to
184
+ metadata = await store.metadata(artifact_id)
185
+ session_id = metadata["session_id"]
186
+ ```
187
+
160
188
  ### Strict Session Isolation
161
189
  ```python
162
190
  # Users can only access their own files
@@ -178,19 +206,6 @@ company_b_files = await store.list_by_session("company_b")
178
206
  # Compliance-ready: GDPR, SOX, HIPAA
179
207
  ```
180
208
 
181
- ### Directory-Like Organization
182
- ```python
183
- # Organize files with path-like prefixes
184
- await store.write_file(content, filename="docs/reports/q1_sales.pdf", session_id="user_123")
185
- await store.write_file(content, filename="docs/contracts/client_a.pdf", session_id="user_123")
186
- await store.write_file(content, filename="images/profile.jpg", session_id="user_123")
187
-
188
- # List by directory
189
- docs = await store.get_directory_contents("user_123", "docs/")
190
- reports = await store.get_directory_contents("user_123", "docs/reports/")
191
- images = await store.get_directory_contents("user_123", "images/")
192
- ```
193
-
194
209
  ## 📦 Storage Providers
195
210
 
196
211
  ### Memory Provider
@@ -200,7 +215,7 @@ store = ArtifactStore(storage_provider="memory")
200
215
  - Perfect for development and testing
201
216
  - Zero configuration required
202
217
  - Non-persistent (data lost on restart)
203
- - Session listing returns empty (graceful degradation)
218
+ - **Note**: Provider isolation limitations for testing
204
219
 
205
220
  ### Filesystem Provider
206
221
  ```python
@@ -212,7 +227,7 @@ os.environ["ARTIFACT_FS_ROOT"] = "./my-artifacts"
212
227
  - Persistent across restarts
213
228
  - `file://` URLs for local access
214
229
  - **Full session listing support**
215
- - Great for development and small deployments
230
+ - Great for development and staging
216
231
 
217
232
  ### AWS S3 Provider
218
233
  ```python
@@ -295,7 +310,7 @@ async def upload_file(data_base64: str, filename: str, mime: str, session_id: st
295
310
 
296
311
  # MCP tool: List session files
297
312
  async def list_session_files(session_id: str, prefix: str = ""):
298
- files = await store.list_by_prefix(session_id, prefix)
313
+ files = await store.get_directory_contents(session_id, prefix)
299
314
  return {"files": files}
300
315
 
301
316
  # MCP tool: Copy file (within session only)
@@ -337,39 +352,6 @@ async def list_user_files(user_id: str, directory: str = ""):
337
352
  return await store.get_directory_contents(f"user_{user_id}", directory)
338
353
  ```
339
354
 
340
- ### Multi-Tenant SaaS Application
341
-
342
- ```python
343
- # Tenant isolation
344
- async def create_tenant_workspace(tenant_id: str):
345
- """Create isolated workspace for tenant"""
346
-
347
- # Create tenant directory structure
348
- directories = ["documents/", "images/", "reports/", "config/"]
349
-
350
- for directory in directories:
351
- # Create a marker file for the directory
352
- await store.write_file(
353
- content=f"# {directory.rstrip('/')} Directory\n\nTenant workspace created.",
354
- filename=f"{directory}README.md",
355
- session_id=f"tenant_{tenant_id}"
356
- )
357
-
358
- return {"tenant_id": tenant_id, "directories": directories}
359
-
360
- async def get_tenant_usage(tenant_id: str):
361
- """Get storage usage for a tenant"""
362
- files = await store.list_by_session(f"tenant_{tenant_id}")
363
- total_bytes = sum(file.get('bytes', 0) for file in files)
364
-
365
- return {
366
- "tenant_id": tenant_id,
367
- "file_count": len(files),
368
- "total_bytes": total_bytes,
369
- "total_mb": round(total_bytes / 1024 / 1024, 2)
370
- }
371
- ```
372
-
373
355
  ### Advanced File Operations
374
356
 
375
357
  ```python
@@ -391,13 +373,15 @@ await store.move_file(
391
373
  new_filename="documents/renamed_doc.md"
392
374
  )
393
375
 
394
- # Update file content (overwrite)
395
- updated_id = await store.write_file(
396
- content="# Updated Document\n\nThis content replaces the old file.",
397
- filename="documents/updated_doc.md",
398
- session_id="user_123",
399
- overwrite_artifact_id=old_artifact_id
376
+ # Update metadata
377
+ await store.update_metadata(
378
+ artifact_id,
379
+ summary="Updated summary",
380
+ meta={"version": 2, "updated_by": "user_123"}
400
381
  )
382
+
383
+ # Extend TTL
384
+ await store.extend_ttl(artifact_id, additional_seconds=3600)
401
385
  ```
402
386
 
403
387
  ### Batch Processing
@@ -423,43 +407,40 @@ items = [
423
407
  artifact_ids = await store.store_batch(items, session_id="product-catalog")
424
408
  ```
425
409
 
426
- ### Context Manager Usage
427
-
428
- ```python
429
- async with ArtifactStore() as store:
430
- artifact_id = await store.store(
431
- data=b"Temporary data",
432
- mime="text/plain",
433
- summary="Auto-cleanup example",
434
- session_id="temp_session"
435
- )
436
- # Store automatically closed on exit
437
- ```
438
-
439
410
  ## 🧪 Testing
440
411
 
441
412
  ### Run All Tests
442
413
  ```bash
443
- # Comprehensive smoke test (64+ test scenarios)
444
- uv run examples/artifact_smoke_test.py
414
+ # MCP server scenarios (recommended)
415
+ uv run examples/mcp_test_demo.py
445
416
 
446
- # Usage examples with all providers
447
- uv run examples/artifact_usage_examples.py
448
-
449
- # Session operations demo (NEW)
417
+ # Session security testing
450
418
  uv run examples/session_operations_demo.py
419
+
420
+ # Grid architecture demo
421
+ uv run examples/grid_demo.py
422
+
423
+ # Complete verification
424
+ uv run examples/complete_verification.py
451
425
  ```
452
426
 
453
- ### Session Security Testing
454
- ```bash
455
- # Run secure session operations demo
456
- uv run examples/session_operations_demo.py
427
+ ### Test Results
428
+ Recent test results show excellent performance:
429
+ ```
430
+ 📤 Test 1: Rapid file creation...
431
+ ✅ Created 20 files in 0.006s (3,083 files/sec)
457
432
 
458
- # Output shows:
459
- # Cross-session copy correctly blocked
460
- # ✅ Cross-session move correctly blocked
461
- # Cross-session overwrite correctly blocked
462
- # 🛡️ ALL SECURITY TESTS PASSED!
433
+ 📋 Test 2: Session listing performance...
434
+ Listed 20 files in 0.002s
435
+
436
+ 📁 Test 3: Directory operations...
437
+ Listed uploads/ directory (20 files) in 0.002s
438
+
439
+ 📖 Test 4: Batch read operations...
440
+ ✅ Read 10 files in 0.002s (4,693 reads/sec)
441
+
442
+ 📋 Test 5: Copy operations...
443
+ ✅ Copied 5 files in 0.003s (1,811 copies/sec)
463
444
  ```
464
445
 
465
446
  ### Development Setup
@@ -485,6 +466,7 @@ store = testing_setup("./test-artifacts") # Uses filesystem
485
466
  ARTIFACT_PROVIDER=s3 # memory, filesystem, s3, ibm_cos, ibm_cos_iam
486
467
  ARTIFACT_BUCKET=my-artifacts # Bucket/container name
487
468
  ARTIFACT_FS_ROOT=./artifacts # Filesystem root (filesystem provider)
469
+ ARTIFACT_SANDBOX_ID=my-app # Sandbox identifier for multi-tenancy
488
470
 
489
471
  # Session configuration
490
472
  SESSION_PROVIDER=redis # memory, redis
@@ -529,42 +511,47 @@ store = ArtifactStore()
529
511
  - **Connection Pooling**: Efficient resource usage with aioboto3
530
512
  - **Metadata Caching**: Sub-millisecond lookups with Redis
531
513
  - **Batch Operations**: Reduced overhead for multiple files
532
- - **Streaming**: Large file support with streaming reads/writes
533
- - **Session Listing**: Optimized prefix-based queries
514
+ - **Grid Architecture**: Optimized session-based queries
534
515
 
535
516
  ### Performance Benchmarks
536
517
  ```
537
- Created 50 files in 0.02 seconds (2,933 files/sec)
538
- Listed 50 files in 0.006 seconds
539
- Listed directory (50 files) in 0.005 seconds
540
- Read 10 files in 0.002 seconds (5,375 reads/sec)
518
+ File Creation: 3,083 files/sec
519
+ File Reading: 4,693 reads/sec
520
+ File Copying: 1,811 copies/sec
521
+ Session Listing: ~0.002s for 20+ files
522
+ ✅ Directory Listing: ~0.002s for filtered results
541
523
  ```
542
524
 
543
525
  ## 🔒 Security
544
526
 
527
+ - **Mandatory Sessions**: No anonymous artifacts allowed
545
528
  - **Session Isolation**: Strict boundaries prevent cross-session access
546
529
  - **No Cross-Session Operations**: Copy, move, overwrite blocked across sessions
530
+ - **Grid Architecture**: Clear audit trail in paths
547
531
  - **Presigned URLs**: Time-limited access without credential sharing
548
532
  - **Secure Defaults**: Conservative TTL and expiration settings
549
533
  - **Credential Isolation**: Environment-based configuration
550
534
  - **Error Handling**: No sensitive data in logs or exceptions
551
- - **Multi-Tenant Ready**: Perfect for SaaS applications
552
535
 
553
536
  ### Security Validation
554
537
  ```python
555
538
  # All these operations are blocked for security
556
539
  await store.copy_file(user_a_file, target_session_id="user_b") # ❌ Blocked
557
540
  await store.move_file(user_a_file, new_session_id="user_b") # ❌ Blocked
558
- await store.write_file(content, session_id="user_b",
559
- overwrite_artifact_id=user_a_file) # Blocked
541
+
542
+ # Security test results:
543
+ # ✅ Cross-session copy correctly blocked
544
+ # ✅ Cross-session move correctly blocked
545
+ # ✅ Cross-session overwrite correctly blocked
546
+ # 🛡️ ALL SECURITY TESTS PASSED!
560
547
  ```
561
548
 
562
549
  ## 📝 API Reference
563
550
 
564
551
  ### Core Methods
565
552
 
566
- #### `store(data, *, mime, summary, meta=None, filename=None, session_id=None, ttl=900)`
567
- Store artifact data with metadata.
553
+ #### `store(data, *, mime, summary, meta=None, filename=None, session_id=None, user_id=None, ttl=900)`
554
+ Store artifact data with metadata. Session auto-allocated if not provided.
568
555
 
569
556
  #### `retrieve(artifact_id)`
570
557
  Retrieve artifact data by ID.
@@ -575,28 +562,44 @@ Get artifact metadata.
575
562
  #### `exists(artifact_id)` / `delete(artifact_id)`
576
563
  Check existence or delete artifacts.
577
564
 
578
- ### Session Operations (NEW)
565
+ ### Session Operations
566
+
567
+ #### `create_session(user_id=None, ttl_hours=None)`
568
+ Create a new session explicitly.
569
+
570
+ #### `validate_session(session_id)` / `get_session_info(session_id)`
571
+ Session validation and information retrieval.
579
572
 
580
573
  #### `list_by_session(session_id, limit=100)`
581
574
  List all artifacts in a session.
582
575
 
583
- #### `list_by_prefix(session_id, prefix="", limit=100)`
584
- List artifacts with filename prefix (directory-like).
585
-
586
576
  #### `get_directory_contents(session_id, directory_prefix="", limit=100)`
587
577
  Get files in a directory-like structure.
588
578
 
589
- #### `copy_file(artifact_id, *, new_filename=None, target_session_id=None, new_meta=None)`
590
- Copy file within same session only (cross-session blocked).
579
+ ### File Operations
591
580
 
592
- #### `move_file(artifact_id, *, new_filename=None, new_session_id=None, new_meta=None)`
593
- Move/rename file within same session only (cross-session blocked).
581
+ #### `write_file(content, *, filename, mime="text/plain", session_id=None, ...)`
582
+ Write content to new file.
594
583
 
595
584
  #### `read_file(artifact_id, *, encoding="utf-8", as_text=True)`
596
585
  Read file content directly as text or binary.
597
586
 
598
- #### `write_file(content, *, filename, mime="text/plain", session_id=None, overwrite_artifact_id=None)`
599
- Write content to new file or overwrite existing (within same session).
587
+ #### `copy_file(artifact_id, *, new_filename=None, new_meta=None, summary=None)`
588
+ Copy file within same session only (cross-session blocked).
589
+
590
+ #### `move_file(artifact_id, *, new_filename=None, new_meta=None)`
591
+ Move/rename file within same session only (cross-session blocked).
592
+
593
+ #### `list_files(session_id, prefix="", limit=100)`
594
+ List files with optional prefix filtering.
595
+
596
+ ### Metadata Operations
597
+
598
+ #### `update_metadata(artifact_id, *, summary=None, meta=None, merge=True, **kwargs)`
599
+ Update artifact metadata.
600
+
601
+ #### `extend_ttl(artifact_id, additional_seconds)`
602
+ Extend artifact TTL.
600
603
 
601
604
  ### Presigned URLs
602
605
 
@@ -609,6 +612,9 @@ Generate URLs with predefined durations (15min/1hr/24hr).
609
612
  #### `presign_upload(session_id=None, filename=None, mime_type="application/octet-stream", expires=3600)`
610
613
  Generate presigned URL for upload.
611
614
 
615
+ #### `register_uploaded_artifact(artifact_id, *, mime, summary, ...)`
616
+ Register metadata for presigned uploads.
617
+
612
618
  ### Batch Operations
613
619
 
614
620
  #### `store_batch(items, session_id=None, ttl=900)`
@@ -622,23 +628,15 @@ Validate storage and session provider connectivity.
622
628
  #### `get_stats()`
623
629
  Get storage statistics and configuration info.
624
630
 
625
- ## 🛠️ Advanced Features
631
+ ### Grid Operations
626
632
 
627
- ### Custom Providers
628
- ```python
629
- # Create custom storage provider
630
- def my_custom_factory():
631
- @asynccontextmanager
632
- async def _ctx():
633
- client = MyCustomClient()
634
- try:
635
- yield client
636
- finally:
637
- await client.close()
638
- return _ctx
633
+ #### `get_canonical_prefix(session_id)`
634
+ Get grid path prefix for session.
639
635
 
640
- store = ArtifactStore(s3_factory=my_custom_factory())
641
- ```
636
+ #### `generate_artifact_key(session_id, artifact_id)`
637
+ Generate grid artifact key.
638
+
639
+ ## 🛠️ Advanced Features
642
640
 
643
641
  ### Error Handling
644
642
  ```python
@@ -646,7 +644,8 @@ from chuk_artifacts import (
646
644
  ArtifactNotFoundError,
647
645
  ArtifactExpiredError,
648
646
  ProviderError,
649
- ArtifactStoreError # NEW: for session security violations
647
+ SessionError,
648
+ ArtifactStoreError # For session security violations
650
649
  )
651
650
 
652
651
  try:
@@ -670,6 +669,18 @@ print(f"Session: {config_status['session']['status']}")
670
669
  stats = await store.get_stats()
671
670
  print(f"Provider: {stats['storage_provider']}")
672
671
  print(f"Bucket: {stats['bucket']}")
672
+ print(f"Sandbox: {stats['sandbox_id']}")
673
+ ```
674
+
675
+ ### Context Manager Usage
676
+ ```python
677
+ async with ArtifactStore() as store:
678
+ artifact_id = await store.store(
679
+ data=b"Temporary data",
680
+ mime="text/plain",
681
+ summary="Auto-cleanup example"
682
+ )
683
+ # Store automatically closed on exit
673
684
  ```
674
685
 
675
686
  ## 🤝 Contributing
@@ -677,7 +688,7 @@ print(f"Bucket: {stats['bucket']}")
677
688
  1. Fork the repository
678
689
  2. Create a feature branch: `git checkout -b feature-name`
679
690
  3. Make your changes
680
- 4. Run tests: `uv run examples/artifact_smoke_test.py`
691
+ 4. Run tests: `uv run examples/mcp_test_demo.py`
681
692
  5. Test session operations: `uv run examples/session_operations_demo.py`
682
693
  6. Submit a pull request
683
694
 
@@ -685,26 +696,24 @@ print(f"Bucket: {stats['bucket']}")
685
696
 
686
697
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
687
698
 
688
- ## 🔗 Links
689
-
690
- - **Documentation**: [docs.example.com](https://docs.example.com)
691
- - **Issue Tracker**: [github.com/your-org/chuk-artifacts/issues](https://github.com/your-org/chuk-artifacts/issues)
692
- - **PyPI**: [pypi.org/project/chuk-artifacts](https://pypi.org/project/chuk-artifacts)
693
-
694
699
  ## 🎯 Roadmap
695
700
 
696
701
  - [x] **Session-based security** with strict isolation
697
- - [x] **Directory-like operations** with prefix filtering
702
+ - [x] **Grid architecture** with federation-ready paths
703
+ - [x] **Modular design** with specialized operation modules
698
704
  - [x] **High-performance operations** (3,000+ ops/sec)
705
+ - [x] **Directory-like operations** with prefix filtering
706
+ - [x] **Comprehensive testing** with real-world scenarios
699
707
  - [ ] Azure Blob Storage provider
700
- - [ ] Google Cloud Storage provider
708
+ - [ ] Google Cloud Storage provider
701
709
  - [ ] Encryption at rest
702
710
  - [ ] Artifact versioning
703
711
  - [ ] Webhook notifications
704
712
  - [ ] Prometheus metrics export
713
+ - [ ] Federation implementation
705
714
 
706
715
  ---
707
716
 
708
- **Made with ❤️ by the Chuk team**
717
+ **Made with ❤️ for secure, scalable artifact storage**
709
718
 
710
- *Secure, fast, and reliable artifact storage for modern applications*
719
+ *Production-ready artifact storage with mandatory session security and grid architecture*
@@ -1,24 +1,23 @@
1
1
  chuk_artifacts/__init__.py,sha256=-4S9FWKVcQSa2ZD3GVbmbpGZPcl0cTQN_TFZLSqV7lQ,3605
2
- chuk_artifacts/admin.py,sha256=g8r1nta_cDkoy_KgScTHkeeV7ij5PR6jX0GXgUYub7Y,2662
3
- chuk_artifacts/base.py,sha256=d3iA3AJR9wF0I3kmppkosPDxaMTgufqI6v_wW5fQfKY,2411
4
- chuk_artifacts/batch.py,sha256=I5WgWajuzrvqTCkQYYgpzrL1WduzxJchA3Ihv3Xvhcw,4264
2
+ chuk_artifacts/admin.py,sha256=O7jQCMbH-ExmYvJkfjHidagOgTF8o32-xQ7d2Ul9o_I,5727
3
+ chuk_artifacts/base.py,sha256=BtuVnC9M8QI1znyTdBxjZ6knIKP_k0yUfLfh7inGJUc,2559
4
+ chuk_artifacts/batch.py,sha256=x8ARrWJ24I9fAXXodzvh31uMxYrvwZCGGJhUCM4vMJ4,5099
5
5
  chuk_artifacts/config.py,sha256=MaUzHzKPoBUyERviEpv8JVvPybMzSksgLyj0b7AO3Sc,7664
6
- chuk_artifacts/core.py,sha256=rS5VWjen6aRlnAIJIhLi639VfZ2u8ORaFxrPJMfpPYE,8296
6
+ chuk_artifacts/core.py,sha256=hokH7cgGE2ZaEwlV8XMKOov3EMvcLS2HufdApLS6l3M,6699
7
7
  chuk_artifacts/exceptions.py,sha256=f-s7Mg7c8vMXsbgqO2B6lMHdXcJQNvsESAY4GhJaV4g,814
8
- chuk_artifacts/metadata.py,sha256=cBMMwCuyRtmJHjqHWuKMbK1G-kg_G4QpfqW-7RxhIzw,11858
8
+ chuk_artifacts/metadata.py,sha256=KinpOF-b8qOYffXx9Ixbv-Ms9MjD7wMtAP03ZVofCsU,7731
9
9
  chuk_artifacts/models.py,sha256=_foXlkr0DprqgztDw5WtlDc-s1OouLgYNp4XM1Ghp-g,837
10
- chuk_artifacts/presigned.py,sha256=qonNg7WMd7VmOEXAzF6GssXuPs5be2s8IJhtuFul7JM,9638
10
+ chuk_artifacts/presigned.py,sha256=-GE8r0CfUZuPNA_jnSGTfX7kuws6kYCPe7C4y6FItdo,11491
11
11
  chuk_artifacts/provider_factory.py,sha256=T0IXx1C8gygJzp417oB44_DxEaZoZR7jcdwQy8FghRE,3398
12
- chuk_artifacts/session_operations.py,sha256=dolSkSnm4W_9ZElZJy25RmsKuLjUnnkfH8SvZWkbW5A,14232
13
- chuk_artifacts/store.py,sha256=0RKSAkSfTM1v-qg3ERv3-8VaRiBVMxdGy2qxjFVz9MY,19749
12
+ chuk_artifacts/store.py,sha256=3E_eh7JcgyW7-ikLSn_fFMUV4AwN5A0phkEmF0cMaxw,24779
14
13
  chuk_artifacts/providers/__init__.py,sha256=3lN1lAy1ETT1mQslJo1f22PPR1W4CyxmsqJBclzH4NE,317
15
14
  chuk_artifacts/providers/filesystem.py,sha256=F4EjE-_ItPg0RWe7CqameVpOMjU-b7AigEBkm_ZoNrc,15280
16
15
  chuk_artifacts/providers/ibm_cos.py,sha256=K1-VAX4UVV9tA161MOeDXOKloQ0hB77jdw1-p46FwmU,4445
17
16
  chuk_artifacts/providers/ibm_cos_iam.py,sha256=VtwvCi9rMMcZx6i9l21ob6wM8jXseqvjzgCnAA82RkY,3186
18
17
  chuk_artifacts/providers/memory.py,sha256=B1C-tR1PcNz-UuDfGm1bhjPz3oITVATIMPekVbE7nm4,10487
19
18
  chuk_artifacts/providers/s3.py,sha256=eWhBhFSaobpRbazn7ySfU_7D8rm_xCfdSVqRtzXzXRY,2858
20
- chuk_artifacts-0.1.2.dist-info/licenses/LICENSE,sha256=SG9BmgtPBagPV0d-Fep-msdAGl-E1CeoBL7-EDRH2qA,1066
21
- chuk_artifacts-0.1.2.dist-info/METADATA,sha256=RYa5j8aK37uuKQeqSp9OKpP1KGU4PoJXLUStrwq_pZY,20975
22
- chuk_artifacts-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- chuk_artifacts-0.1.2.dist-info/top_level.txt,sha256=1_PVMtWXR0A-ZmeH6apF9mPaMtU0i23JE6wmN4GBRDI,15
24
- chuk_artifacts-0.1.2.dist-info/RECORD,,
19
+ chuk_artifacts-0.1.4.dist-info/licenses/LICENSE,sha256=SG9BmgtPBagPV0d-Fep-msdAGl-E1CeoBL7-EDRH2qA,1066
20
+ chuk_artifacts-0.1.4.dist-info/METADATA,sha256=qtT0mnVKLwYjOhtRaFCY1GDmyrv9eOCC9bjKYDnmYD0,21188
21
+ chuk_artifacts-0.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ chuk_artifacts-0.1.4.dist-info/top_level.txt,sha256=1_PVMtWXR0A-ZmeH6apF9mPaMtU0i23JE6wmN4GBRDI,15
23
+ chuk_artifacts-0.1.4.dist-info/RECORD,,