deltaglider 0.3.0.dev0__tar.gz → 0.3.2.dev0__tar.gz

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 (82) hide show
  1. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/.gitignore +1 -0
  2. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/PKG-INFO +97 -44
  3. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/README.md +95 -41
  4. deltaglider-0.3.2.dev0/docs/sdk/README.md +270 -0
  5. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/pyproject.toml +1 -3
  6. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/__init__.py +18 -2
  7. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/_version.py +3 -3
  8. deltaglider-0.3.2.dev0/src/deltaglider/adapters/metrics_cloudwatch.py +215 -0
  9. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/storage_s3.py +73 -2
  10. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/app/cli/main.py +56 -20
  11. deltaglider-0.3.2.dev0/src/deltaglider/client.py +1241 -0
  12. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/core/service.py +287 -1
  13. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider.egg-info/PKG-INFO +97 -44
  14. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider.egg-info/SOURCES.txt +4 -1
  15. deltaglider-0.3.2.dev0/tests/integration/test_client.py +366 -0
  16. deltaglider-0.3.2.dev0/tests/integration/test_recursive_delete_reference_cleanup.py +396 -0
  17. deltaglider-0.3.0.dev0/docs/sdk/README.md +0 -122
  18. deltaglider-0.3.0.dev0/src/deltaglider/client.py +0 -237
  19. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/.dockerignore +0 -0
  20. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/.github/workflows/ci.yml +0 -0
  21. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/CLAUDE.md +0 -0
  22. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/CONTRIBUTING.md +0 -0
  23. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/Dockerfile +0 -0
  24. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/LICENSE +0 -0
  25. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/MANIFEST.in +0 -0
  26. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/Makefile +0 -0
  27. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/PYPI_RELEASE.md +0 -0
  28. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docker-compose.test.yml +0 -0
  29. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docker-compose.yml +0 -0
  30. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/aws-s3-cli-compatibility.md +0 -0
  31. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/case-study-readonlyrest.md +0 -0
  32. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/deltaglider.png +0 -0
  33. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/deltaglider_architecture_guidelines.txt +0 -0
  34. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/deltaglider_metadata_schema.txt +0 -0
  35. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/deltaglider_specs.txt +0 -0
  36. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/sdk/Makefile +0 -0
  37. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/sdk/api.md +0 -0
  38. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/sdk/architecture.md +0 -0
  39. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/sdk/examples.md +0 -0
  40. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/sdk/generate_docs.py +0 -0
  41. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/docs/sdk/getting-started.md +0 -0
  42. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/run-e2e-tests.sh +0 -0
  43. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/setup.cfg +0 -0
  44. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/__init__.py +0 -0
  45. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/cache_fs.py +0 -0
  46. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/clock_utc.py +0 -0
  47. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/diff_xdelta.py +0 -0
  48. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/hash_sha.py +0 -0
  49. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/logger_std.py +0 -0
  50. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/adapters/metrics_noop.py +0 -0
  51. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/app/__init__.py +0 -0
  52. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/app/cli/__init__.py +0 -0
  53. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/app/cli/aws_compat.py +0 -0
  54. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/app/cli/sync.py +0 -0
  55. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/core/__init__.py +0 -0
  56. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/core/errors.py +0 -0
  57. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/core/models.py +0 -0
  58. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/__init__.py +0 -0
  59. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/cache.py +0 -0
  60. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/clock.py +0 -0
  61. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/diff.py +0 -0
  62. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/hash.py +0 -0
  63. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/logger.py +0 -0
  64. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/metrics.py +0 -0
  65. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/ports/storage.py +0 -0
  66. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider/py.typed +0 -0
  67. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider.egg-info/dependency_links.txt +0 -0
  68. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider.egg-info/entry_points.txt +0 -0
  69. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider.egg-info/requires.txt +0 -0
  70. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/src/deltaglider.egg-info/top_level.txt +0 -0
  71. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/__init__.py +0 -0
  72. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/conftest.py +0 -0
  73. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/e2e/__init__.py +0 -0
  74. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/e2e/test_localstack.py +0 -0
  75. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/integration/__init__.py +0 -0
  76. /deltaglider-0.3.0.dev0/tests/integration/test_aws_cli_commands_v2.py → /deltaglider-0.3.2.dev0/tests/integration/test_aws_cli_commands.py +0 -0
  77. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/integration/test_full_workflow.py +0 -0
  78. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/integration/test_get_command.py +0 -0
  79. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/integration/test_xdelta.py +0 -0
  80. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/unit/__init__.py +0 -0
  81. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/unit/test_adapters.py +0 -0
  82. {deltaglider-0.3.0.dev0 → deltaglider-0.3.2.dev0}/tests/unit/test_core_service.py +0 -0
@@ -1,4 +1,5 @@
1
1
  # Python
2
+ ror-data-importer/
2
3
  __pycache__/
3
4
  *.py[cod]
4
5
  *$py.class
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deltaglider
3
- Version: 0.3.0.dev0
3
+ Version: 0.3.2.dev0
4
4
  Summary: Store 4TB in 5GB: S3-compatible storage with 99.9% compression for versioned files
5
5
  Author-email: Beshu Tech <info@beshu.tech>
6
6
  Maintainer-email: Beshu Tech Team <info@beshu.tech>
7
- License: MIT
7
+ License-Expression: MIT
8
8
  Project-URL: Homepage, https://github.com/beshu-tech/deltaglider
9
9
  Project-URL: Documentation, https://github.com/beshu-tech/deltaglider#readme
10
10
  Project-URL: Repository, https://github.com/beshu-tech/deltaglider
@@ -15,7 +15,6 @@ Keywords: s3,compression,delta,storage,backup,deduplication,xdelta3,binary-diff,
15
15
  Classifier: Development Status :: 4 - Beta
16
16
  Classifier: Intended Audience :: Developers
17
17
  Classifier: Intended Audience :: System Administrators
18
- Classifier: License :: OSI Approved :: MIT License
19
18
  Classifier: Operating System :: OS Independent
20
19
  Classifier: Programming Language :: Python :: 3
21
20
  Classifier: Programming Language :: Python :: 3.11
@@ -53,7 +52,7 @@ Dynamic: license-file
53
52
  [![xdelta3](https://img.shields.io/badge/powered%20by-xdelta3-green.svg)](https://github.com/jmacd/xdelta)
54
53
 
55
54
  <div align="center">
56
- <img src="https://github.com/sscarduzio/deltaglider/raw/main/docs/deltaglider.png" alt="DeltaGlider Logo" width="500"/>
55
+ <img src="https://github.com/beshu-tech/deltaglider/raw/main/docs/deltaglider.png" alt="DeltaGlider Logo" width="500"/>
57
56
  </div>
58
57
 
59
58
  **Store 4TB of similar files in 5GB. No, that's not a typo.**
@@ -239,94 +238,148 @@ deltaglider ls -h s3://backups/
239
238
  deltaglider rm -r s3://backups/2023/
240
239
  ```
241
240
 
242
- ### Python SDK
241
+ ### Python SDK - Drop-in boto3 Replacement
243
242
 
244
243
  **[📚 Full SDK Documentation](docs/sdk/README.md)** | **[API Reference](docs/sdk/api.md)** | **[Examples](docs/sdk/examples.md)**
245
244
 
246
- #### Quick Start
245
+ #### Quick Start - boto3 Compatible API (Recommended)
246
+
247
+ DeltaGlider provides a **100% boto3-compatible API** that works as a drop-in replacement for AWS S3 SDK:
248
+
249
+ ```python
250
+ from deltaglider import create_client
251
+
252
+ # Drop-in replacement for boto3.client('s3')
253
+ client = create_client() # Uses AWS credentials automatically
254
+
255
+ # Identical to boto3 S3 API - just works with 99% compression!
256
+ response = client.put_object(
257
+ Bucket='releases',
258
+ Key='v2.0.0/my-app.zip',
259
+ Body=open('my-app-v2.0.0.zip', 'rb')
260
+ )
261
+ print(f"Stored with ETag: {response['ETag']}")
262
+
263
+ # Standard boto3 get_object - handles delta reconstruction automatically
264
+ response = client.get_object(Bucket='releases', Key='v2.0.0/my-app.zip')
265
+ with open('downloaded.zip', 'wb') as f:
266
+ f.write(response['Body'].read())
267
+
268
+ # All boto3 S3 methods supported
269
+ client.list_objects(Bucket='releases', Prefix='v2.0.0/')
270
+ client.delete_object(Bucket='releases', Key='old-version.zip')
271
+ client.head_object(Bucket='releases', Key='v2.0.0/my-app.zip')
272
+ ```
273
+
274
+ #### Simple API (Alternative)
275
+
276
+ For simpler use cases, DeltaGlider also provides a streamlined API:
247
277
 
248
278
  ```python
249
- from pathlib import Path
250
279
  from deltaglider import create_client
251
280
 
252
- # Uses AWS credentials from environment or ~/.aws/credentials
253
281
  client = create_client()
254
282
 
255
- # Upload a file (auto-detects if delta compression should be used)
283
+ # Simple upload with automatic compression detection
256
284
  summary = client.upload("my-app-v2.0.0.zip", "s3://releases/v2.0.0/")
257
285
  print(f"Compressed from {summary.original_size_mb:.1f}MB to {summary.stored_size_mb:.1f}MB")
258
286
  print(f"Saved {summary.savings_percent:.0f}% storage space")
259
287
 
260
- # Download a file (auto-handles delta reconstruction)
288
+ # Simple download with automatic delta reconstruction
261
289
  client.download("s3://releases/v2.0.0/my-app-v2.0.0.zip", "local-app.zip")
262
290
  ```
263
291
 
264
- #### Real-World Example: Software Release Storage
292
+ #### Real-World Example: Software Release Storage with boto3 API
265
293
 
266
294
  ```python
267
295
  from deltaglider import create_client
268
296
 
297
+ # Works exactly like boto3, but with 99% compression!
269
298
  client = create_client()
270
299
 
271
- # Upload multiple versions of your software
300
+ # Upload multiple versions using boto3-compatible API
272
301
  versions = ["v1.0.0", "v1.0.1", "v1.0.2", "v1.1.0"]
273
302
  for version in versions:
274
- file = f"dist/my-app-{version}.zip"
275
- summary = client.upload(file, f"s3://releases/{version}/")
276
-
277
- if summary.is_delta:
278
- print(f"{version}: Stored as {summary.stored_size_mb:.1f}MB delta "
279
- f"(saved {summary.savings_percent:.0f}%)")
280
- else:
281
- print(f"{version}: Stored as reference ({summary.original_size_mb:.1f}MB)")
303
+ with open(f"dist/my-app-{version}.zip", 'rb') as f:
304
+ response = client.put_object(
305
+ Bucket='releases',
306
+ Key=f'{version}/my-app-{version}.zip',
307
+ Body=f,
308
+ Metadata={'version': version, 'build': 'production'}
309
+ )
310
+
311
+ # Check compression stats (DeltaGlider extension)
312
+ if 'DeltaGliderInfo' in response:
313
+ info = response['DeltaGliderInfo']
314
+ if info.get('IsDelta'):
315
+ print(f"{version}: Stored as {info['StoredSizeMB']:.1f}MB delta "
316
+ f"(saved {info['SavingsPercent']:.0f}%)")
317
+ else:
318
+ print(f"{version}: Stored as reference ({info['OriginalSizeMB']:.1f}MB)")
282
319
 
283
320
  # Result:
284
321
  # v1.0.0: Stored as reference (100.0MB)
285
322
  # v1.0.1: Stored as 0.2MB delta (saved 99.8%)
286
323
  # v1.0.2: Stored as 0.3MB delta (saved 99.7%)
287
324
  # v1.1.0: Stored as 5.2MB delta (saved 94.8%)
325
+
326
+ # Download using standard boto3 API
327
+ response = client.get_object(Bucket='releases', Key='v1.1.0/my-app-v1.1.0.zip')
328
+ with open('my-app-latest.zip', 'wb') as f:
329
+ f.write(response['Body'].read())
288
330
  ```
289
331
 
290
- #### Advanced Example: Automated Backup System
332
+ #### Advanced Example: Automated Backup with boto3 API
291
333
 
292
334
  ```python
293
335
  from datetime import datetime
294
336
  from deltaglider import create_client
295
337
 
296
- client = create_client(
297
- endpoint_url="http://minio.internal:9000", # Works with MinIO/R2/etc
298
- log_level="INFO"
299
- )
338
+ # Works with any S3-compatible storage
339
+ client = create_client(endpoint_url="http://minio.internal:9000")
300
340
 
301
341
  def backup_database():
302
- """Daily database backup with automatic deduplication."""
342
+ """Daily database backup with automatic deduplication using boto3 API."""
303
343
  date = datetime.now().strftime("%Y%m%d")
304
344
 
305
345
  # Create database dump
306
346
  dump_file = f"backup-{date}.sql.gz"
307
347
 
308
- # Upload with delta compression
309
- summary = client.upload(
310
- dump_file,
311
- f"s3://backups/postgres/{date}/",
312
- tags={"type": "daily", "database": "production"}
348
+ # Upload using boto3-compatible API
349
+ with open(dump_file, 'rb') as f:
350
+ response = client.put_object(
351
+ Bucket='backups',
352
+ Key=f'postgres/{date}/{dump_file}',
353
+ Body=f,
354
+ Tagging='type=daily&database=production',
355
+ Metadata={'date': date, 'source': 'production'}
356
+ )
357
+
358
+ # Check compression effectiveness (DeltaGlider extension)
359
+ if 'DeltaGliderInfo' in response:
360
+ info = response['DeltaGliderInfo']
361
+ if info['DeltaRatio'] > 0.1: # If delta is >10% of original
362
+ print(f"Warning: Low compression ({info['SavingsPercent']:.0f}%), "
363
+ "database might have significant changes")
364
+ print(f"Backup stored: {info['StoredSizeMB']:.1f}MB "
365
+ f"(compressed from {info['OriginalSizeMB']:.1f}MB)")
366
+
367
+ # List recent backups using boto3 API
368
+ response = client.list_objects(
369
+ Bucket='backups',
370
+ Prefix='postgres/',
371
+ MaxKeys=30
313
372
  )
314
373
 
315
- # Monitor compression effectiveness
316
- if summary.delta_ratio > 0.1: # If delta is >10% of original
317
- print(f"Warning: Low compression ({summary.savings_percent:.0f}%), "
318
- "database might have significant changes")
319
-
320
- # Keep last 30 days, archive older
321
- client.lifecycle_policy("s3://backups/postgres/",
322
- days_before_archive=30,
323
- days_before_delete=90)
324
-
325
- return summary
374
+ # Clean up old backups
375
+ for obj in response.get('Contents', []):
376
+ # Parse date from key
377
+ obj_date = obj['Key'].split('/')[1]
378
+ if days_old(obj_date) > 30:
379
+ client.delete_object(Bucket='backups', Key=obj['Key'])
326
380
 
327
381
  # Run backup
328
- result = backup_database()
329
- print(f"Backup complete: {result.stored_size_mb:.1f}MB stored")
382
+ backup_database()
330
383
  ```
331
384
 
332
385
  For more examples and detailed API documentation, see the [SDK Documentation](docs/sdk/README.md).
@@ -7,7 +7,7 @@
7
7
  [![xdelta3](https://img.shields.io/badge/powered%20by-xdelta3-green.svg)](https://github.com/jmacd/xdelta)
8
8
 
9
9
  <div align="center">
10
- <img src="https://github.com/sscarduzio/deltaglider/raw/main/docs/deltaglider.png" alt="DeltaGlider Logo" width="500"/>
10
+ <img src="https://github.com/beshu-tech/deltaglider/raw/main/docs/deltaglider.png" alt="DeltaGlider Logo" width="500"/>
11
11
  </div>
12
12
 
13
13
  **Store 4TB of similar files in 5GB. No, that's not a typo.**
@@ -193,94 +193,148 @@ deltaglider ls -h s3://backups/
193
193
  deltaglider rm -r s3://backups/2023/
194
194
  ```
195
195
 
196
- ### Python SDK
196
+ ### Python SDK - Drop-in boto3 Replacement
197
197
 
198
198
  **[📚 Full SDK Documentation](docs/sdk/README.md)** | **[API Reference](docs/sdk/api.md)** | **[Examples](docs/sdk/examples.md)**
199
199
 
200
- #### Quick Start
200
+ #### Quick Start - boto3 Compatible API (Recommended)
201
+
202
+ DeltaGlider provides a **100% boto3-compatible API** that works as a drop-in replacement for AWS S3 SDK:
203
+
204
+ ```python
205
+ from deltaglider import create_client
206
+
207
+ # Drop-in replacement for boto3.client('s3')
208
+ client = create_client() # Uses AWS credentials automatically
209
+
210
+ # Identical to boto3 S3 API - just works with 99% compression!
211
+ response = client.put_object(
212
+ Bucket='releases',
213
+ Key='v2.0.0/my-app.zip',
214
+ Body=open('my-app-v2.0.0.zip', 'rb')
215
+ )
216
+ print(f"Stored with ETag: {response['ETag']}")
217
+
218
+ # Standard boto3 get_object - handles delta reconstruction automatically
219
+ response = client.get_object(Bucket='releases', Key='v2.0.0/my-app.zip')
220
+ with open('downloaded.zip', 'wb') as f:
221
+ f.write(response['Body'].read())
222
+
223
+ # All boto3 S3 methods supported
224
+ client.list_objects(Bucket='releases', Prefix='v2.0.0/')
225
+ client.delete_object(Bucket='releases', Key='old-version.zip')
226
+ client.head_object(Bucket='releases', Key='v2.0.0/my-app.zip')
227
+ ```
228
+
229
+ #### Simple API (Alternative)
230
+
231
+ For simpler use cases, DeltaGlider also provides a streamlined API:
201
232
 
202
233
  ```python
203
- from pathlib import Path
204
234
  from deltaglider import create_client
205
235
 
206
- # Uses AWS credentials from environment or ~/.aws/credentials
207
236
  client = create_client()
208
237
 
209
- # Upload a file (auto-detects if delta compression should be used)
238
+ # Simple upload with automatic compression detection
210
239
  summary = client.upload("my-app-v2.0.0.zip", "s3://releases/v2.0.0/")
211
240
  print(f"Compressed from {summary.original_size_mb:.1f}MB to {summary.stored_size_mb:.1f}MB")
212
241
  print(f"Saved {summary.savings_percent:.0f}% storage space")
213
242
 
214
- # Download a file (auto-handles delta reconstruction)
243
+ # Simple download with automatic delta reconstruction
215
244
  client.download("s3://releases/v2.0.0/my-app-v2.0.0.zip", "local-app.zip")
216
245
  ```
217
246
 
218
- #### Real-World Example: Software Release Storage
247
+ #### Real-World Example: Software Release Storage with boto3 API
219
248
 
220
249
  ```python
221
250
  from deltaglider import create_client
222
251
 
252
+ # Works exactly like boto3, but with 99% compression!
223
253
  client = create_client()
224
254
 
225
- # Upload multiple versions of your software
255
+ # Upload multiple versions using boto3-compatible API
226
256
  versions = ["v1.0.0", "v1.0.1", "v1.0.2", "v1.1.0"]
227
257
  for version in versions:
228
- file = f"dist/my-app-{version}.zip"
229
- summary = client.upload(file, f"s3://releases/{version}/")
230
-
231
- if summary.is_delta:
232
- print(f"{version}: Stored as {summary.stored_size_mb:.1f}MB delta "
233
- f"(saved {summary.savings_percent:.0f}%)")
234
- else:
235
- print(f"{version}: Stored as reference ({summary.original_size_mb:.1f}MB)")
258
+ with open(f"dist/my-app-{version}.zip", 'rb') as f:
259
+ response = client.put_object(
260
+ Bucket='releases',
261
+ Key=f'{version}/my-app-{version}.zip',
262
+ Body=f,
263
+ Metadata={'version': version, 'build': 'production'}
264
+ )
265
+
266
+ # Check compression stats (DeltaGlider extension)
267
+ if 'DeltaGliderInfo' in response:
268
+ info = response['DeltaGliderInfo']
269
+ if info.get('IsDelta'):
270
+ print(f"{version}: Stored as {info['StoredSizeMB']:.1f}MB delta "
271
+ f"(saved {info['SavingsPercent']:.0f}%)")
272
+ else:
273
+ print(f"{version}: Stored as reference ({info['OriginalSizeMB']:.1f}MB)")
236
274
 
237
275
  # Result:
238
276
  # v1.0.0: Stored as reference (100.0MB)
239
277
  # v1.0.1: Stored as 0.2MB delta (saved 99.8%)
240
278
  # v1.0.2: Stored as 0.3MB delta (saved 99.7%)
241
279
  # v1.1.0: Stored as 5.2MB delta (saved 94.8%)
280
+
281
+ # Download using standard boto3 API
282
+ response = client.get_object(Bucket='releases', Key='v1.1.0/my-app-v1.1.0.zip')
283
+ with open('my-app-latest.zip', 'wb') as f:
284
+ f.write(response['Body'].read())
242
285
  ```
243
286
 
244
- #### Advanced Example: Automated Backup System
287
+ #### Advanced Example: Automated Backup with boto3 API
245
288
 
246
289
  ```python
247
290
  from datetime import datetime
248
291
  from deltaglider import create_client
249
292
 
250
- client = create_client(
251
- endpoint_url="http://minio.internal:9000", # Works with MinIO/R2/etc
252
- log_level="INFO"
253
- )
293
+ # Works with any S3-compatible storage
294
+ client = create_client(endpoint_url="http://minio.internal:9000")
254
295
 
255
296
  def backup_database():
256
- """Daily database backup with automatic deduplication."""
297
+ """Daily database backup with automatic deduplication using boto3 API."""
257
298
  date = datetime.now().strftime("%Y%m%d")
258
299
 
259
300
  # Create database dump
260
301
  dump_file = f"backup-{date}.sql.gz"
261
302
 
262
- # Upload with delta compression
263
- summary = client.upload(
264
- dump_file,
265
- f"s3://backups/postgres/{date}/",
266
- tags={"type": "daily", "database": "production"}
303
+ # Upload using boto3-compatible API
304
+ with open(dump_file, 'rb') as f:
305
+ response = client.put_object(
306
+ Bucket='backups',
307
+ Key=f'postgres/{date}/{dump_file}',
308
+ Body=f,
309
+ Tagging='type=daily&database=production',
310
+ Metadata={'date': date, 'source': 'production'}
311
+ )
312
+
313
+ # Check compression effectiveness (DeltaGlider extension)
314
+ if 'DeltaGliderInfo' in response:
315
+ info = response['DeltaGliderInfo']
316
+ if info['DeltaRatio'] > 0.1: # If delta is >10% of original
317
+ print(f"Warning: Low compression ({info['SavingsPercent']:.0f}%), "
318
+ "database might have significant changes")
319
+ print(f"Backup stored: {info['StoredSizeMB']:.1f}MB "
320
+ f"(compressed from {info['OriginalSizeMB']:.1f}MB)")
321
+
322
+ # List recent backups using boto3 API
323
+ response = client.list_objects(
324
+ Bucket='backups',
325
+ Prefix='postgres/',
326
+ MaxKeys=30
267
327
  )
268
328
 
269
- # Monitor compression effectiveness
270
- if summary.delta_ratio > 0.1: # If delta is >10% of original
271
- print(f"Warning: Low compression ({summary.savings_percent:.0f}%), "
272
- "database might have significant changes")
273
-
274
- # Keep last 30 days, archive older
275
- client.lifecycle_policy("s3://backups/postgres/",
276
- days_before_archive=30,
277
- days_before_delete=90)
278
-
279
- return summary
329
+ # Clean up old backups
330
+ for obj in response.get('Contents', []):
331
+ # Parse date from key
332
+ obj_date = obj['Key'].split('/')[1]
333
+ if days_old(obj_date) > 30:
334
+ client.delete_object(Bucket='backups', Key=obj['Key'])
280
335
 
281
336
  # Run backup
282
- result = backup_database()
283
- print(f"Backup complete: {result.stored_size_mb:.1f}MB stored")
337
+ backup_database()
284
338
  ```
285
339
 
286
340
  For more examples and detailed API documentation, see the [SDK Documentation](docs/sdk/README.md).