persistence-kit 3.15.0__tar.gz → 3.16.0__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.
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/PKG-INFO +10 -1
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/README.md +9 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/factory.py +3 -3
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/s3.py +32 -16
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/pyproject.toml +1 -1
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/LICENSE +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/common.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/encrypted_middleware.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/encrypted_routes.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/error_handlers.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/exceptions.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/rate_limit.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/route_loader.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/authenticated_user.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/bootstrap/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/bootstrap/configuration.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/bootstrap/seeders.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/bootstrap/startup.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/contracts.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/dynamodb.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/factory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/memory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/mongo.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/cache/namespaced.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/contracts/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/contracts/repository.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/contracts/view_repository.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/contracts.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/errors.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/factory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/mailer.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/memory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/message.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/mime.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/preview.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/smtp.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/mail/templates.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/py.typed +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/dynamodb_repo/dynamodb_mapper.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/dynamodb_repo/dynamodb_repo.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/filter_ops.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/memory_repo/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/memory_repo/memory_repo.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/mongo_repo/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/mongo_repo/mongo_mapper.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/mongo_repo/mongo_repo.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/sqlalchemy_repo/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/sqlalchemy_repo/schema_evolve.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/sqlalchemy_repo/sqlalchemy_dataclass_mapper.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/sqlalchemy_repo/sqlalchemy_engine.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/sqlalchemy_repo/sqlalchemy_repo.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/sqlalchemy_repo/table_factory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/factory/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/factory/repository_factory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/registry/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/registry/entity_registry.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/view/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/view/populating_repository.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/resilience/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/resilience/circuit.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/aggregate.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/api_key.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/base.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/basic.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/bearer.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/login.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/oauth2.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/caching.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/client.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/config.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/contracts.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/errors.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/factory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/mapping.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/memory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/payload.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/populate.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/provider.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/registry.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/resolver.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/retry.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/tracing.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/encrypted/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/encrypted/envelope.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/encrypted/errors.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/factory.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/ports.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/providers/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/providers/cognito_identity_provider.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/providers/encryption_provider.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/providers/memory_security_provider.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/registration.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/token_verifiers/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/token_verifiers/cognito_jwt_verifier.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/token_verifiers/memory_jwt_verifier.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/app_settings.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/cache_settings.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/constants.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/mail_settings.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/parsers.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/repo_settings.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/contracts.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/errors.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/local.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/media.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/storage/routes.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/utils/__init__.py +0 -0
- {persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/utils/upsert.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: persistence-kit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.16.0
|
|
4
4
|
Summary: Reusable persistence and repository toolkit
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -209,6 +209,15 @@ url = await storage.generate_presigned_url(key)
|
|
|
209
209
|
`LocalObjectStorage` writes to a directory and signs its own download URLs.
|
|
210
210
|
`S3ObjectStorage` uploads to S3 and returns AWS presigned URLs. Pick one with
|
|
211
211
|
`get_export_storage(settings)`, which reads your settings and caches the adapter.
|
|
212
|
+
Give `S3ObjectStorage` a `prefix` and every key it writes, presigns, deletes or
|
|
213
|
+
lists stays under that folder of the bucket, while the keys you pass and get back
|
|
214
|
+
stay relative to it.
|
|
215
|
+
|
|
216
|
+
For files your users upload, `build_media_storage(settings, namespace=...,
|
|
217
|
+
url_prefix=...)` checks type and size and keeps each namespace in its own
|
|
218
|
+
folder: `<LOCAL_MEDIA_STORAGE_DIR>/<namespace>` with `MEDIA_STORAGE_PROVIDER=local`,
|
|
219
|
+
and `<namespace>/` inside `AWS_S3_MEDIA_BUCKET` with `s3`. Keys are the same on
|
|
220
|
+
both, so moving to S3 does not change what your app stores.
|
|
212
221
|
|
|
213
222
|
FastAPI apps can mount `build_local_export_storage_router(...)` to serve local
|
|
214
223
|
files, passing their settings provider, an optional current-user dependency, and
|
|
@@ -158,6 +158,15 @@ url = await storage.generate_presigned_url(key)
|
|
|
158
158
|
`LocalObjectStorage` writes to a directory and signs its own download URLs.
|
|
159
159
|
`S3ObjectStorage` uploads to S3 and returns AWS presigned URLs. Pick one with
|
|
160
160
|
`get_export_storage(settings)`, which reads your settings and caches the adapter.
|
|
161
|
+
Give `S3ObjectStorage` a `prefix` and every key it writes, presigns, deletes or
|
|
162
|
+
lists stays under that folder of the bucket, while the keys you pass and get back
|
|
163
|
+
stay relative to it.
|
|
164
|
+
|
|
165
|
+
For files your users upload, `build_media_storage(settings, namespace=...,
|
|
166
|
+
url_prefix=...)` checks type and size and keeps each namespace in its own
|
|
167
|
+
folder: `<LOCAL_MEDIA_STORAGE_DIR>/<namespace>` with `MEDIA_STORAGE_PROVIDER=local`,
|
|
168
|
+
and `<namespace>/` inside `AWS_S3_MEDIA_BUCKET` with `s3`. Keys are the same on
|
|
169
|
+
both, so moving to S3 does not change what your app stores.
|
|
161
170
|
|
|
162
171
|
FastAPI apps can mount `build_local_export_storage_router(...)` to serve local
|
|
163
172
|
files, passing their settings provider, an optional current-user dependency, and
|
|
@@ -87,10 +87,10 @@ def _local_media_object_storage_cached(base_dir: str) -> ObjectStorage:
|
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
@lru_cache
|
|
90
|
-
def _s3_media_object_storage_cached(bucket: str, region: str) -> ObjectStorage:
|
|
90
|
+
def _s3_media_object_storage_cached(bucket: str, region: str, prefix: str) -> ObjectStorage:
|
|
91
91
|
from persistence_kit.storage.s3 import S3ObjectStorage
|
|
92
92
|
|
|
93
|
-
return S3ObjectStorage(bucket=bucket, region=region)
|
|
93
|
+
return S3ObjectStorage(bucket=bucket, region=region, prefix=prefix)
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
def _build_media_object_storage(
|
|
@@ -110,7 +110,7 @@ def _build_media_object_storage(
|
|
|
110
110
|
"Falta configuracion AWS_S3_MEDIA_BUCKET para el storage de media."
|
|
111
111
|
)
|
|
112
112
|
return _s3_media_object_storage_cached(
|
|
113
|
-
settings.aws_s3_media_bucket, settings.aws_region
|
|
113
|
+
settings.aws_s3_media_bucket, settings.aws_region, namespace
|
|
114
114
|
)
|
|
115
115
|
provider = getattr(
|
|
116
116
|
settings.media_storage_provider, "value", settings.media_storage_provider
|
|
@@ -22,35 +22,42 @@ logger = logging.getLogger(__name__)
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class S3ObjectStorage:
|
|
25
|
-
def __init__(self, *, bucket: str, region: str) -> None:
|
|
25
|
+
def __init__(self, *, bucket: str, region: str, prefix: str = "") -> None:
|
|
26
26
|
if boto3 is None:
|
|
27
27
|
raise StorageConfigError("Falta dependencia boto3 para integrar con S3.")
|
|
28
28
|
self._bucket = bucket
|
|
29
29
|
self._region = region
|
|
30
|
+
normalized_prefix = prefix.strip("/")
|
|
31
|
+
self._prefix = f"{normalized_prefix}/" if normalized_prefix else ""
|
|
30
32
|
self._client = boto3.client("s3", region_name=region)
|
|
31
33
|
|
|
34
|
+
def _object_key(self, key: str) -> str:
|
|
35
|
+
return f"{self._prefix}{key}"
|
|
36
|
+
|
|
32
37
|
async def upload(
|
|
33
38
|
self,
|
|
34
39
|
key: str,
|
|
35
40
|
data: bytes,
|
|
36
41
|
content_type: str = "application/octet-stream",
|
|
37
42
|
) -> str:
|
|
43
|
+
object_key = self._object_key(key)
|
|
44
|
+
|
|
38
45
|
def _upload() -> None:
|
|
39
46
|
self._client.put_object(
|
|
40
47
|
Bucket=self._bucket,
|
|
41
|
-
Key=
|
|
48
|
+
Key=object_key,
|
|
42
49
|
Body=data,
|
|
43
50
|
ContentType=content_type,
|
|
44
51
|
)
|
|
45
52
|
|
|
46
|
-
logger.info("S3 upload iniciado bucket=%s key=%s", self._bucket,
|
|
53
|
+
logger.info("S3 upload iniciado bucket=%s key=%s", self._bucket, object_key)
|
|
47
54
|
try:
|
|
48
55
|
await asyncio.to_thread(_upload)
|
|
49
56
|
except ClientError as exc:
|
|
50
|
-
logger.exception("S3 upload fallido bucket=%s key=%s", self._bucket,
|
|
57
|
+
logger.exception("S3 upload fallido bucket=%s key=%s", self._bucket, object_key)
|
|
51
58
|
raise StorageUploadError(f"No fue posible subir el archivo a S3: {exc}") from exc
|
|
52
59
|
|
|
53
|
-
logger.info("S3 upload exitoso bucket=%s key=%s", self._bucket,
|
|
60
|
+
logger.info("S3 upload exitoso bucket=%s key=%s", self._bucket, object_key)
|
|
54
61
|
return key
|
|
55
62
|
|
|
56
63
|
async def upload_file(
|
|
@@ -59,66 +66,75 @@ class S3ObjectStorage:
|
|
|
59
66
|
file_path: Path,
|
|
60
67
|
content_type: str = "application/octet-stream",
|
|
61
68
|
) -> str:
|
|
69
|
+
object_key = self._object_key(key)
|
|
70
|
+
|
|
62
71
|
def _upload_file() -> None:
|
|
63
72
|
with file_path.open("rb") as file_obj:
|
|
64
73
|
self._client.upload_fileobj(
|
|
65
74
|
Fileobj=file_obj,
|
|
66
75
|
Bucket=self._bucket,
|
|
67
|
-
Key=
|
|
76
|
+
Key=object_key,
|
|
68
77
|
ExtraArgs={"ContentType": content_type},
|
|
69
78
|
)
|
|
70
79
|
|
|
71
|
-
logger.info(
|
|
80
|
+
logger.info(
|
|
81
|
+
"S3 file upload iniciado bucket=%s key=%s path=%s", self._bucket, object_key, file_path
|
|
82
|
+
)
|
|
72
83
|
try:
|
|
73
84
|
await asyncio.to_thread(_upload_file)
|
|
74
85
|
except ClientError as exc:
|
|
75
|
-
logger.exception("S3 file upload fallido bucket=%s key=%s", self._bucket,
|
|
86
|
+
logger.exception("S3 file upload fallido bucket=%s key=%s", self._bucket, object_key)
|
|
76
87
|
raise StorageUploadError(f"No fue posible subir el archivo a S3: {exc}") from exc
|
|
77
88
|
|
|
78
|
-
logger.info("S3 file upload exitoso bucket=%s key=%s", self._bucket,
|
|
89
|
+
logger.info("S3 file upload exitoso bucket=%s key=%s", self._bucket, object_key)
|
|
79
90
|
return key
|
|
80
91
|
|
|
81
92
|
async def generate_presigned_url(self, key: str, expires_in: int = 3600) -> str:
|
|
93
|
+
object_key = self._object_key(key)
|
|
94
|
+
|
|
82
95
|
def _presign() -> str:
|
|
83
96
|
return self._client.generate_presigned_url(
|
|
84
97
|
"get_object",
|
|
85
|
-
Params={"Bucket": self._bucket, "Key":
|
|
98
|
+
Params={"Bucket": self._bucket, "Key": object_key},
|
|
86
99
|
ExpiresIn=expires_in,
|
|
87
100
|
)
|
|
88
101
|
|
|
89
102
|
try:
|
|
90
103
|
return await asyncio.to_thread(_presign)
|
|
91
104
|
except ClientError as exc:
|
|
92
|
-
logger.exception("S3 presign fallido bucket=%s key=%s", self._bucket,
|
|
105
|
+
logger.exception("S3 presign fallido bucket=%s key=%s", self._bucket, object_key)
|
|
93
106
|
raise StoragePresignError(f"No fue posible generar la URL prefirmada: {exc}") from exc
|
|
94
107
|
|
|
95
108
|
async def delete(self, key: str) -> None:
|
|
109
|
+
object_key = self._object_key(key)
|
|
110
|
+
|
|
96
111
|
def _delete() -> None:
|
|
97
|
-
self._client.delete_object(Bucket=self._bucket, Key=
|
|
112
|
+
self._client.delete_object(Bucket=self._bucket, Key=object_key)
|
|
98
113
|
|
|
99
114
|
try:
|
|
100
115
|
await asyncio.to_thread(_delete)
|
|
101
116
|
except ClientError as exc:
|
|
102
|
-
logger.exception("S3 delete fallido bucket=%s key=%s", self._bucket,
|
|
117
|
+
logger.exception("S3 delete fallido bucket=%s key=%s", self._bucket, object_key)
|
|
103
118
|
raise StorageError(f"No fue posible borrar el objeto en S3: {exc}") from exc
|
|
104
119
|
|
|
105
120
|
async def list_keys(self, prefix: str = "") -> list[str]:
|
|
106
121
|
normalized_prefix = prefix.lstrip("/")
|
|
107
122
|
if normalized_prefix and not normalized_prefix.endswith("/"):
|
|
108
123
|
normalized_prefix = normalized_prefix + "/"
|
|
124
|
+
search_prefix = self._object_key(normalized_prefix)
|
|
109
125
|
|
|
110
126
|
def _list() -> list[str]:
|
|
111
127
|
keys: list[str] = []
|
|
112
128
|
paginator = self._client.get_paginator("list_objects_v2")
|
|
113
|
-
for page in paginator.paginate(Bucket=self._bucket, Prefix=
|
|
129
|
+
for page in paginator.paginate(Bucket=self._bucket, Prefix=search_prefix):
|
|
114
130
|
for obj in page.get("Contents", []) or []:
|
|
115
|
-
keys.append(obj["Key"])
|
|
131
|
+
keys.append(obj["Key"].removeprefix(self._prefix))
|
|
116
132
|
return keys
|
|
117
133
|
|
|
118
134
|
try:
|
|
119
135
|
return await asyncio.to_thread(_list)
|
|
120
136
|
except ClientError as exc:
|
|
121
|
-
logger.exception("S3 list fallido bucket=%s prefix=%s", self._bucket,
|
|
137
|
+
logger.exception("S3 list fallido bucket=%s prefix=%s", self._bucket, search_prefix)
|
|
122
138
|
raise StorageError(f"No fue posible listar objetos en S3: {exc}") from exc
|
|
123
139
|
|
|
124
140
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/api/encrypted_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/bootstrap/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/contracts/view_repository.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/memory_repo/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository/mongo_repo/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/repository_factory/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/__init__.py
RENAMED
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/restclient/auth/api_key.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/encrypted/__init__.py
RENAMED
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/encrypted/envelope.py
RENAMED
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/encrypted/errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/security/providers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{persistence_kit-3.15.0 → persistence_kit-3.16.0}/persistence_kit/settings/cache_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|