chuk-artifacts 0.1.0__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.
- chuk_artifacts/__init__.py +149 -0
- chuk_artifacts/admin.py +79 -0
- chuk_artifacts/base.py +75 -0
- chuk_artifacts/batch.py +115 -0
- chuk_artifacts/config.py +338 -0
- chuk_artifacts/core.py +215 -0
- chuk_artifacts/exceptions.py +37 -0
- chuk_artifacts/metadata.py +286 -0
- chuk_artifacts/models.py +23 -0
- chuk_artifacts/presigned.py +267 -0
- chuk_artifacts/provider_factory.py +84 -0
- chuk_artifacts/providers/__init__.py +10 -0
- chuk_artifacts/providers/filesystem.py +453 -0
- chuk_artifacts/providers/ibm_cos.py +121 -0
- chuk_artifacts/providers/ibm_cos_iam.py +82 -0
- chuk_artifacts/providers/memory.py +315 -0
- chuk_artifacts/providers/s3.py +90 -0
- chuk_artifacts/store.py +383 -0
- chuk_artifacts-0.1.0.dist-info/METADATA +519 -0
- chuk_artifacts-0.1.0.dist-info/RECORD +23 -0
- chuk_artifacts-0.1.0.dist-info/WHEEL +5 -0
- chuk_artifacts-0.1.0.dist-info/licenses/LICENSE +21 -0
- chuk_artifacts-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,519 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: chuk-artifacts
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: Add your description here
|
5
|
+
License: MIT
|
6
|
+
Requires-Python: >=3.11
|
7
|
+
Description-Content-Type: text/markdown
|
8
|
+
License-File: LICENSE
|
9
|
+
Requires-Dist: chuk-tool-processor>=0.1.7
|
10
|
+
Requires-Dist: pydantic>=2.10.6
|
11
|
+
Requires-Dist: pyyaml>=6.0.2
|
12
|
+
Requires-Dist: aioboto3>=14.3.0
|
13
|
+
Requires-Dist: redis>=6.2.0
|
14
|
+
Requires-Dist: ibm-cos-sdk>=2.13.5
|
15
|
+
Requires-Dist: chuk-sessions>=0.1.0
|
16
|
+
Provides-Extra: websocket
|
17
|
+
Requires-Dist: websockets>=10.0; extra == "websocket"
|
18
|
+
Provides-Extra: dev
|
19
|
+
Requires-Dist: pytest>=8.3.5; extra == "dev"
|
20
|
+
Requires-Dist: pytest-asyncio>=0.26.0; extra == "dev"
|
21
|
+
Requires-Dist: ruff>=0.4.6; extra == "dev"
|
22
|
+
Dynamic: license-file
|
23
|
+
|
24
|
+
# Chuk Artifacts
|
25
|
+
|
26
|
+
[](https://github.com/your-org/chuk-artifacts)
|
27
|
+
[](https://python.org)
|
28
|
+
[](LICENSE)
|
29
|
+
|
30
|
+
**Asynchronous, multi-backend artifact storage with metadata caching and presigned URLs**
|
31
|
+
|
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.
|
33
|
+
|
34
|
+
## ✨ Key Features
|
35
|
+
|
36
|
+
- 🏗️ **Modular Architecture**: 5 specialized operation modules for clean separation of concerns
|
37
|
+
- 🔄 **Multi-Backend Support**: Memory, filesystem, S3, IBM COS with seamless switching
|
38
|
+
- ⚡ **Fully Async**: Built with async/await for high performance
|
39
|
+
- 🔗 **Presigned URLs**: Secure, time-limited access without credential exposure
|
40
|
+
- 📊 **Batch Operations**: Efficient multi-file uploads and processing
|
41
|
+
- 🗃️ **Metadata Caching**: Fast lookups with Redis or memory-based sessions
|
42
|
+
- 🔧 **Zero Configuration**: Works out of the box with sensible defaults
|
43
|
+
- 🌍 **Production Ready**: Battle-tested with comprehensive error handling
|
44
|
+
|
45
|
+
## 🚀 Quick Start
|
46
|
+
|
47
|
+
### Installation
|
48
|
+
|
49
|
+
```bash
|
50
|
+
pip install chuk-artifacts
|
51
|
+
# or with uv
|
52
|
+
uv add chuk-artifacts
|
53
|
+
```
|
54
|
+
|
55
|
+
### Basic Usage
|
56
|
+
|
57
|
+
```python
|
58
|
+
from chuk_artifacts import ArtifactStore
|
59
|
+
|
60
|
+
# Zero-config setup (uses memory provider)
|
61
|
+
store = ArtifactStore()
|
62
|
+
|
63
|
+
# Store an artifact
|
64
|
+
artifact_id = await store.store(
|
65
|
+
data=b"Hello, world!",
|
66
|
+
mime="text/plain",
|
67
|
+
summary="A simple greeting",
|
68
|
+
filename="hello.txt"
|
69
|
+
)
|
70
|
+
|
71
|
+
# Retrieve it
|
72
|
+
data = await store.retrieve(artifact_id)
|
73
|
+
print(data.decode()) # "Hello, world!"
|
74
|
+
|
75
|
+
# Generate a presigned URL
|
76
|
+
download_url = await store.presign_medium(artifact_id) # 1 hour
|
77
|
+
```
|
78
|
+
|
79
|
+
### With Configuration
|
80
|
+
|
81
|
+
```python
|
82
|
+
# Production setup with S3 and Redis
|
83
|
+
store = ArtifactStore(
|
84
|
+
storage_provider="s3",
|
85
|
+
session_provider="redis",
|
86
|
+
bucket="my-artifacts"
|
87
|
+
)
|
88
|
+
|
89
|
+
# Or use environment variables
|
90
|
+
# ARTIFACT_PROVIDER=s3
|
91
|
+
# SESSION_PROVIDER=redis
|
92
|
+
# AWS_ACCESS_KEY_ID=your_key
|
93
|
+
# AWS_SECRET_ACCESS_KEY=your_secret
|
94
|
+
# ARTIFACT_BUCKET=my-artifacts
|
95
|
+
|
96
|
+
store = ArtifactStore() # Auto-loads configuration
|
97
|
+
```
|
98
|
+
|
99
|
+
## 🏗️ Architecture
|
100
|
+
|
101
|
+
Chuk Artifacts uses a modular architecture with specialized operation modules:
|
102
|
+
|
103
|
+
```
|
104
|
+
ArtifactStore (Main Coordinator)
|
105
|
+
├── CoreStorageOperations # store() and retrieve()
|
106
|
+
├── PresignedURLOperations # URL generation and upload workflows
|
107
|
+
├── MetadataOperations # metadata, exists, delete, update
|
108
|
+
├── BatchOperations # store_batch() for multiple files
|
109
|
+
└── AdminOperations # validate_configuration, get_stats
|
110
|
+
```
|
111
|
+
|
112
|
+
This design provides:
|
113
|
+
- **Better testability**: Each module can be tested independently
|
114
|
+
- **Enhanced maintainability**: Clear separation of concerns
|
115
|
+
- **Easy extensibility**: Add new operation types without touching core
|
116
|
+
- **Improved debugging**: Isolated functionality for easier troubleshooting
|
117
|
+
|
118
|
+
## 📦 Storage Providers
|
119
|
+
|
120
|
+
### Memory Provider
|
121
|
+
```python
|
122
|
+
store = ArtifactStore(storage_provider="memory")
|
123
|
+
```
|
124
|
+
- Perfect for development and testing
|
125
|
+
- Zero configuration required
|
126
|
+
- Non-persistent (data lost on restart)
|
127
|
+
- Isolation between async contexts
|
128
|
+
|
129
|
+
### Filesystem Provider
|
130
|
+
```python
|
131
|
+
store = ArtifactStore(storage_provider="filesystem")
|
132
|
+
# Set root directory
|
133
|
+
os.environ["ARTIFACT_FS_ROOT"] = "./my-artifacts"
|
134
|
+
```
|
135
|
+
- Local disk storage
|
136
|
+
- Persistent across restarts
|
137
|
+
- `file://` URLs for local access
|
138
|
+
- Great for development and small deployments
|
139
|
+
|
140
|
+
### AWS S3 Provider
|
141
|
+
```python
|
142
|
+
store = ArtifactStore(storage_provider="s3")
|
143
|
+
# Configure via environment
|
144
|
+
os.environ.update({
|
145
|
+
"AWS_ACCESS_KEY_ID": "your_key",
|
146
|
+
"AWS_SECRET_ACCESS_KEY": "your_secret",
|
147
|
+
"AWS_REGION": "us-east-1",
|
148
|
+
"ARTIFACT_BUCKET": "my-bucket"
|
149
|
+
})
|
150
|
+
```
|
151
|
+
- Industry-standard cloud storage
|
152
|
+
- Native presigned URL support
|
153
|
+
- Highly scalable and durable
|
154
|
+
- Perfect for production workloads
|
155
|
+
|
156
|
+
### IBM Cloud Object Storage
|
157
|
+
```python
|
158
|
+
# HMAC authentication
|
159
|
+
store = ArtifactStore(storage_provider="ibm_cos")
|
160
|
+
os.environ.update({
|
161
|
+
"AWS_ACCESS_KEY_ID": "your_hmac_key",
|
162
|
+
"AWS_SECRET_ACCESS_KEY": "your_hmac_secret",
|
163
|
+
"IBM_COS_ENDPOINT": "https://s3.us-south.cloud-object-storage.appdomain.cloud"
|
164
|
+
})
|
165
|
+
|
166
|
+
# IAM authentication
|
167
|
+
store = ArtifactStore(storage_provider="ibm_cos_iam")
|
168
|
+
os.environ.update({
|
169
|
+
"IBM_COS_APIKEY": "your_api_key",
|
170
|
+
"IBM_COS_INSTANCE_CRN": "crn:v1:bluemix:public:cloud-object-storage:..."
|
171
|
+
})
|
172
|
+
```
|
173
|
+
|
174
|
+
## 🗃️ Session Providers
|
175
|
+
|
176
|
+
### Memory Sessions
|
177
|
+
```python
|
178
|
+
store = ArtifactStore(session_provider="memory")
|
179
|
+
```
|
180
|
+
- In-memory metadata storage
|
181
|
+
- Fast but non-persistent
|
182
|
+
- Perfect for testing
|
183
|
+
|
184
|
+
### Redis Sessions
|
185
|
+
```python
|
186
|
+
store = ArtifactStore(session_provider="redis")
|
187
|
+
os.environ["SESSION_REDIS_URL"] = "redis://localhost:6379/0"
|
188
|
+
```
|
189
|
+
- Persistent metadata storage
|
190
|
+
- Shared across multiple instances
|
191
|
+
- Production-ready caching
|
192
|
+
|
193
|
+
## 🎯 Common Use Cases
|
194
|
+
|
195
|
+
### Web Framework Integration
|
196
|
+
|
197
|
+
```python
|
198
|
+
from chuk_artifacts import ArtifactStore
|
199
|
+
|
200
|
+
# Initialize once at startup
|
201
|
+
store = ArtifactStore(
|
202
|
+
storage_provider="s3",
|
203
|
+
session_provider="redis"
|
204
|
+
)
|
205
|
+
|
206
|
+
async def upload_file(file_content: bytes, filename: str, content_type: str):
|
207
|
+
"""Handle file upload in FastAPI/Flask"""
|
208
|
+
artifact_id = await store.store(
|
209
|
+
data=file_content,
|
210
|
+
mime=content_type,
|
211
|
+
summary=f"Uploaded: {filename}",
|
212
|
+
filename=filename
|
213
|
+
)
|
214
|
+
|
215
|
+
# Return download URL
|
216
|
+
download_url = await store.presign_medium(artifact_id)
|
217
|
+
return {
|
218
|
+
"artifact_id": artifact_id,
|
219
|
+
"download_url": download_url
|
220
|
+
}
|
221
|
+
```
|
222
|
+
|
223
|
+
### Batch Processing
|
224
|
+
|
225
|
+
```python
|
226
|
+
# Prepare multiple files
|
227
|
+
items = [
|
228
|
+
{
|
229
|
+
"data": file1_content,
|
230
|
+
"mime": "image/png",
|
231
|
+
"summary": "Product image 1",
|
232
|
+
"filename": "product1.png"
|
233
|
+
},
|
234
|
+
{
|
235
|
+
"data": file2_content,
|
236
|
+
"mime": "image/png",
|
237
|
+
"summary": "Product image 2",
|
238
|
+
"filename": "product2.png"
|
239
|
+
}
|
240
|
+
]
|
241
|
+
|
242
|
+
# Store all at once
|
243
|
+
artifact_ids = await store.store_batch(items, session_id="product-images")
|
244
|
+
```
|
245
|
+
|
246
|
+
### Advanced Metadata Management
|
247
|
+
|
248
|
+
```python
|
249
|
+
# Store with custom metadata
|
250
|
+
artifact_id = await store.store(
|
251
|
+
data=image_data,
|
252
|
+
mime="image/png",
|
253
|
+
summary="Product photo",
|
254
|
+
filename="product.png",
|
255
|
+
meta={
|
256
|
+
"product_id": "12345",
|
257
|
+
"photographer": "John Doe",
|
258
|
+
"category": "electronics"
|
259
|
+
}
|
260
|
+
)
|
261
|
+
|
262
|
+
# Update metadata later
|
263
|
+
await store.update_metadata(
|
264
|
+
artifact_id,
|
265
|
+
summary="Updated product photo",
|
266
|
+
meta={"edited": True, "version": 2}
|
267
|
+
)
|
268
|
+
|
269
|
+
# Extend TTL
|
270
|
+
await store.extend_ttl(artifact_id, 3600) # Add 1 hour
|
271
|
+
```
|
272
|
+
|
273
|
+
### Context Manager Usage
|
274
|
+
|
275
|
+
```python
|
276
|
+
async with ArtifactStore() as store:
|
277
|
+
artifact_id = await store.store(
|
278
|
+
data=b"Temporary data",
|
279
|
+
mime="text/plain",
|
280
|
+
summary="Auto-cleanup example"
|
281
|
+
)
|
282
|
+
# Store automatically closed on exit
|
283
|
+
```
|
284
|
+
|
285
|
+
## 🔧 Configuration
|
286
|
+
|
287
|
+
### Environment Variables
|
288
|
+
|
289
|
+
```bash
|
290
|
+
# Storage configuration
|
291
|
+
ARTIFACT_PROVIDER=s3 # memory, filesystem, s3, ibm_cos, ibm_cos_iam
|
292
|
+
ARTIFACT_BUCKET=my-artifacts # Bucket/container name
|
293
|
+
ARTIFACT_FS_ROOT=./artifacts # Filesystem root (filesystem provider)
|
294
|
+
|
295
|
+
# Session configuration
|
296
|
+
SESSION_PROVIDER=redis # memory, redis
|
297
|
+
SESSION_REDIS_URL=redis://localhost:6379/0
|
298
|
+
|
299
|
+
# AWS/S3 configuration
|
300
|
+
AWS_ACCESS_KEY_ID=your_key
|
301
|
+
AWS_SECRET_ACCESS_KEY=your_secret
|
302
|
+
AWS_REGION=us-east-1
|
303
|
+
S3_ENDPOINT_URL=https://custom-s3.com # Optional: custom S3 endpoint
|
304
|
+
|
305
|
+
# IBM COS configuration
|
306
|
+
IBM_COS_ENDPOINT=https://s3.us-south.cloud-object-storage.appdomain.cloud
|
307
|
+
IBM_COS_APIKEY=your_api_key # For IAM auth
|
308
|
+
IBM_COS_INSTANCE_CRN=crn:v1:... # For IAM auth
|
309
|
+
```
|
310
|
+
|
311
|
+
### Programmatic Configuration
|
312
|
+
|
313
|
+
```python
|
314
|
+
from chuk_artifacts.config import configure_s3, configure_redis_session
|
315
|
+
|
316
|
+
# Configure S3 storage
|
317
|
+
configure_s3(
|
318
|
+
access_key="AKIA...",
|
319
|
+
secret_key="...",
|
320
|
+
bucket="prod-artifacts",
|
321
|
+
region="us-west-2"
|
322
|
+
)
|
323
|
+
|
324
|
+
# Configure Redis sessions
|
325
|
+
configure_redis_session("redis://prod-redis:6379/1")
|
326
|
+
|
327
|
+
# Create store with this configuration
|
328
|
+
store = ArtifactStore()
|
329
|
+
```
|
330
|
+
|
331
|
+
## 🧪 Testing
|
332
|
+
|
333
|
+
### Run All Tests
|
334
|
+
```bash
|
335
|
+
# Comprehensive smoke test (64 test scenarios)
|
336
|
+
uv run examples/artifact_smoke_test.py
|
337
|
+
|
338
|
+
# Usage examples
|
339
|
+
uv run examples/artifact_usage_examples.py
|
340
|
+
```
|
341
|
+
|
342
|
+
### Development Setup
|
343
|
+
```python
|
344
|
+
from chuk_artifacts.config import development_setup
|
345
|
+
|
346
|
+
store = development_setup() # Uses memory providers
|
347
|
+
```
|
348
|
+
|
349
|
+
### Testing Setup
|
350
|
+
```python
|
351
|
+
from chuk_artifacts.config import testing_setup
|
352
|
+
|
353
|
+
store = testing_setup("./test-artifacts") # Uses filesystem
|
354
|
+
```
|
355
|
+
|
356
|
+
## 🚀 Performance
|
357
|
+
|
358
|
+
- **Async/Await**: Non-blocking I/O for high concurrency
|
359
|
+
- **Connection Pooling**: Efficient resource usage with aioboto3
|
360
|
+
- **Metadata Caching**: Fast lookups with Redis
|
361
|
+
- **Batch Operations**: Reduced overhead for multiple files
|
362
|
+
- **Streaming**: Large file support with streaming reads/writes
|
363
|
+
|
364
|
+
## 🔒 Security
|
365
|
+
|
366
|
+
- **Presigned URLs**: Time-limited access without credential sharing
|
367
|
+
- **Secure Defaults**: Conservative TTL and expiration settings
|
368
|
+
- **Credential Isolation**: Environment-based configuration
|
369
|
+
- **Error Handling**: No sensitive data in logs or exceptions
|
370
|
+
|
371
|
+
## 🛠️ Advanced Features
|
372
|
+
|
373
|
+
### Custom Providers
|
374
|
+
```python
|
375
|
+
# Create custom storage provider
|
376
|
+
def my_custom_factory():
|
377
|
+
@asynccontextmanager
|
378
|
+
async def _ctx():
|
379
|
+
client = MyCustomClient()
|
380
|
+
try:
|
381
|
+
yield client
|
382
|
+
finally:
|
383
|
+
await client.close()
|
384
|
+
return _ctx
|
385
|
+
|
386
|
+
store = ArtifactStore(s3_factory=my_custom_factory())
|
387
|
+
```
|
388
|
+
|
389
|
+
### Error Handling
|
390
|
+
```python
|
391
|
+
from chuk_artifacts import (
|
392
|
+
ArtifactNotFoundError,
|
393
|
+
ArtifactExpiredError,
|
394
|
+
ProviderError
|
395
|
+
)
|
396
|
+
|
397
|
+
try:
|
398
|
+
data = await store.retrieve("invalid-id")
|
399
|
+
except ArtifactNotFoundError:
|
400
|
+
print("Artifact not found or expired")
|
401
|
+
except ProviderError as e:
|
402
|
+
print(f"Storage provider error: {e}")
|
403
|
+
```
|
404
|
+
|
405
|
+
### Validation and Monitoring
|
406
|
+
```python
|
407
|
+
# Validate configuration
|
408
|
+
config_status = await store.validate_configuration()
|
409
|
+
print(f"Storage: {config_status['storage']['status']}")
|
410
|
+
print(f"Session: {config_status['session']['status']}")
|
411
|
+
|
412
|
+
# Get statistics
|
413
|
+
stats = await store.get_stats()
|
414
|
+
print(f"Provider: {stats['storage_provider']}")
|
415
|
+
print(f"Bucket: {stats['bucket']}")
|
416
|
+
```
|
417
|
+
|
418
|
+
## 📝 API Reference
|
419
|
+
|
420
|
+
### Core Methods
|
421
|
+
|
422
|
+
#### `store(data, *, mime, summary, meta=None, filename=None, session_id=None, ttl=900)`
|
423
|
+
Store artifact data with metadata.
|
424
|
+
|
425
|
+
**Parameters:**
|
426
|
+
- `data` (bytes): The artifact data
|
427
|
+
- `mime` (str): MIME type (e.g., "text/plain", "image/png")
|
428
|
+
- `summary` (str): Human-readable description
|
429
|
+
- `meta` (dict, optional): Additional metadata
|
430
|
+
- `filename` (str, optional): Original filename
|
431
|
+
- `session_id` (str, optional): Session identifier for organization
|
432
|
+
- `ttl` (int, optional): Metadata TTL in seconds (default: 900)
|
433
|
+
|
434
|
+
**Returns:** `str` - Unique artifact identifier
|
435
|
+
|
436
|
+
#### `retrieve(artifact_id)`
|
437
|
+
Retrieve artifact data by ID.
|
438
|
+
|
439
|
+
**Parameters:**
|
440
|
+
- `artifact_id` (str): The artifact identifier
|
441
|
+
|
442
|
+
**Returns:** `bytes` - The artifact data
|
443
|
+
|
444
|
+
#### `metadata(artifact_id)`
|
445
|
+
Get artifact metadata.
|
446
|
+
|
447
|
+
**Returns:** `dict` - Metadata including size, MIME type, timestamps, etc.
|
448
|
+
|
449
|
+
#### `exists(artifact_id)`
|
450
|
+
Check if artifact exists and hasn't expired.
|
451
|
+
|
452
|
+
**Returns:** `bool`
|
453
|
+
|
454
|
+
#### `delete(artifact_id)`
|
455
|
+
Delete artifact and its metadata.
|
456
|
+
|
457
|
+
**Returns:** `bool` - True if deleted, False if not found
|
458
|
+
|
459
|
+
### Presigned URLs
|
460
|
+
|
461
|
+
#### `presign(artifact_id, expires=3600)`
|
462
|
+
Generate presigned URL for download.
|
463
|
+
|
464
|
+
#### `presign_short(artifact_id)` / `presign_medium(artifact_id)` / `presign_long(artifact_id)`
|
465
|
+
Generate URLs with predefined durations (15min/1hr/24hr).
|
466
|
+
|
467
|
+
#### `presign_upload(session_id=None, filename=None, mime_type="application/octet-stream", expires=3600)`
|
468
|
+
Generate presigned URL for upload.
|
469
|
+
|
470
|
+
**Returns:** `tuple[str, str]` - (upload_url, artifact_id)
|
471
|
+
|
472
|
+
### Batch Operations
|
473
|
+
|
474
|
+
#### `store_batch(items, session_id=None, ttl=900)`
|
475
|
+
Store multiple artifacts efficiently.
|
476
|
+
|
477
|
+
**Parameters:**
|
478
|
+
- `items` (list): List of dicts with keys: data, mime, summary, meta, filename
|
479
|
+
|
480
|
+
**Returns:** `list[str]` - List of artifact IDs
|
481
|
+
|
482
|
+
### Admin Operations
|
483
|
+
|
484
|
+
#### `validate_configuration()`
|
485
|
+
Validate storage and session provider connectivity.
|
486
|
+
|
487
|
+
#### `get_stats()`
|
488
|
+
Get storage statistics and configuration info.
|
489
|
+
|
490
|
+
## 🤝 Contributing
|
491
|
+
|
492
|
+
1. Fork the repository
|
493
|
+
2. Create a feature branch: `git checkout -b feature-name`
|
494
|
+
3. Make your changes
|
495
|
+
4. Run tests: `uv run examples/artifact_smoke_test.py`
|
496
|
+
5. Submit a pull request
|
497
|
+
|
498
|
+
## 📄 License
|
499
|
+
|
500
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
501
|
+
|
502
|
+
## 🔗 Links
|
503
|
+
|
504
|
+
- **Documentation**: [docs.example.com](https://docs.example.com)
|
505
|
+
- **Issue Tracker**: [github.com/your-org/chuk-artifacts/issues](https://github.com/your-org/chuk-artifacts/issues)
|
506
|
+
- **PyPI**: [pypi.org/project/chuk-artifacts](https://pypi.org/project/chuk-artifacts)
|
507
|
+
|
508
|
+
## 🎯 Roadmap
|
509
|
+
|
510
|
+
- [ ] Azure Blob Storage provider
|
511
|
+
- [ ] Google Cloud Storage provider
|
512
|
+
- [ ] Encryption at rest
|
513
|
+
- [ ] Artifact versioning
|
514
|
+
- [ ] Webhook notifications
|
515
|
+
- [ ] Prometheus metrics export
|
516
|
+
|
517
|
+
---
|
518
|
+
|
519
|
+
**Made with ❤️ by the Chuk team**
|
@@ -0,0 +1,23 @@
|
|
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
|
5
|
+
chuk_artifacts/config.py,sha256=MaUzHzKPoBUyERviEpv8JVvPybMzSksgLyj0b7AO3Sc,7664
|
6
|
+
chuk_artifacts/core.py,sha256=rS5VWjen6aRlnAIJIhLi639VfZ2u8ORaFxrPJMfpPYE,8296
|
7
|
+
chuk_artifacts/exceptions.py,sha256=f-s7Mg7c8vMXsbgqO2B6lMHdXcJQNvsESAY4GhJaV4g,814
|
8
|
+
chuk_artifacts/metadata.py,sha256=CXC0j-zjKSOoACmyu6yKqcQpy35otwr-Y_3ogfcuKdE,9123
|
9
|
+
chuk_artifacts/models.py,sha256=_foXlkr0DprqgztDw5WtlDc-s1OouLgYNp4XM1Ghp-g,837
|
10
|
+
chuk_artifacts/presigned.py,sha256=qonNg7WMd7VmOEXAzF6GssXuPs5be2s8IJhtuFul7JM,9638
|
11
|
+
chuk_artifacts/provider_factory.py,sha256=T0IXx1C8gygJzp417oB44_DxEaZoZR7jcdwQy8FghRE,3398
|
12
|
+
chuk_artifacts/store.py,sha256=QdNyik5EXg2NthHnWxUnG5JMM1L7v2jO7phCL5WmvGg,16719
|
13
|
+
chuk_artifacts/providers/__init__.py,sha256=3lN1lAy1ETT1mQslJo1f22PPR1W4CyxmsqJBclzH4NE,317
|
14
|
+
chuk_artifacts/providers/filesystem.py,sha256=F4EjE-_ItPg0RWe7CqameVpOMjU-b7AigEBkm_ZoNrc,15280
|
15
|
+
chuk_artifacts/providers/ibm_cos.py,sha256=K1-VAX4UVV9tA161MOeDXOKloQ0hB77jdw1-p46FwmU,4445
|
16
|
+
chuk_artifacts/providers/ibm_cos_iam.py,sha256=VtwvCi9rMMcZx6i9l21ob6wM8jXseqvjzgCnAA82RkY,3186
|
17
|
+
chuk_artifacts/providers/memory.py,sha256=B1C-tR1PcNz-UuDfGm1bhjPz3oITVATIMPekVbE7nm4,10487
|
18
|
+
chuk_artifacts/providers/s3.py,sha256=eWhBhFSaobpRbazn7ySfU_7D8rm_xCfdSVqRtzXzXRY,2858
|
19
|
+
chuk_artifacts-0.1.0.dist-info/licenses/LICENSE,sha256=SG9BmgtPBagPV0d-Fep-msdAGl-E1CeoBL7-EDRH2qA,1066
|
20
|
+
chuk_artifacts-0.1.0.dist-info/METADATA,sha256=G_DqvAOc5JzpuPDDdMqA1ULhTk6J588gjVVvQ9_5H9A,13847
|
21
|
+
chuk_artifacts-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
22
|
+
chuk_artifacts-0.1.0.dist-info/top_level.txt,sha256=1_PVMtWXR0A-ZmeH6apF9mPaMtU0i23JE6wmN4GBRDI,15
|
23
|
+
chuk_artifacts-0.1.0.dist-info/RECORD,,
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Chris Hay
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1 @@
|
|
1
|
+
chuk_artifacts
|