nucliadb-utils 6.0.0.post2306__py3-none-any.whl → 6.0.0.post2314__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.
@@ -32,12 +32,15 @@ from aiobotocore.client import AioBaseClient # type: ignore
32
32
  from aiobotocore.session import AioSession, get_session # type: ignore
33
33
 
34
34
  from nucliadb_protos.resources_pb2 import CloudFile
35
- from nucliadb_telemetry import errors
35
+ from nucliadb_telemetry import errors, metrics
36
36
  from nucliadb_utils import logger
37
37
  from nucliadb_utils.storages.exceptions import UnparsableResponse
38
38
  from nucliadb_utils.storages.storage import Storage, StorageField
39
39
  from nucliadb_utils.storages.utils import ObjectInfo, ObjectMetadata, Range
40
40
 
41
+ s3_ops_observer = metrics.Observer("s3_ops", labels={"type": ""})
42
+
43
+
41
44
  MB = 1024 * 1024
42
45
  MIN_UPLOAD_SIZE = 5 * MB
43
46
  CHUNK_SIZE = MIN_UPLOAD_SIZE
@@ -78,6 +81,7 @@ class S3StorageField(StorageField):
78
81
  jitter=backoff.random_jitter,
79
82
  max_tries=MAX_TRIES,
80
83
  )
84
+ @s3_ops_observer.wrap({"type": "download"})
81
85
  async def _download(
82
86
  self,
83
87
  uri,
@@ -98,6 +102,7 @@ class S3StorageField(StorageField):
98
102
  else:
99
103
  raise
100
104
 
105
+ @s3_ops_observer.wrap({"type": "iter_data"})
101
106
  async def iter_data(self, range: Optional[Range] = None) -> AsyncGenerator[bytes, None]:
102
107
  # Suports field and key based iter
103
108
  uri = self.field.uri if self.field else self.key
@@ -114,6 +119,7 @@ class S3StorageField(StorageField):
114
119
  yield data
115
120
  data = await stream.read(CHUNK_SIZE)
116
121
 
122
+ @s3_ops_observer.wrap({"type": "abort_multipart"})
117
123
  async def _abort_multipart(self):
118
124
  try:
119
125
  mpu = self.field.resumable_uri
@@ -125,6 +131,7 @@ class S3StorageField(StorageField):
125
131
  except Exception:
126
132
  logger.warning("Could not abort multipart upload", exc_info=True)
127
133
 
134
+ @s3_ops_observer.wrap({"type": "start_upload"})
128
135
  async def start(self, cf: CloudFile) -> CloudFile:
129
136
  if self.field is not None and self.field.upload_uri != "":
130
137
  # Field has already a file beeing uploaded, cancel
@@ -166,6 +173,7 @@ class S3StorageField(StorageField):
166
173
  jitter=backoff.random_jitter,
167
174
  max_tries=MAX_TRIES,
168
175
  )
176
+ @s3_ops_observer.wrap({"type": "create_multipart"})
169
177
  async def _create_multipart(self, bucket_name: str, upload_id: str, cf: CloudFile):
170
178
  return await self.storage._s3aioclient.create_multipart_upload(
171
179
  Bucket=bucket_name,
@@ -177,6 +185,7 @@ class S3StorageField(StorageField):
177
185
  },
178
186
  )
179
187
 
188
+ @s3_ops_observer.wrap({"type": "append_data"})
180
189
  async def append(self, cf: CloudFile, iterable: AsyncIterator) -> int:
181
190
  size = 0
182
191
  if self.field is None:
@@ -204,6 +213,7 @@ class S3StorageField(StorageField):
204
213
  jitter=backoff.random_jitter,
205
214
  max_tries=MAX_TRIES,
206
215
  )
216
+ @s3_ops_observer.wrap({"type": "upload_part"})
207
217
  async def _upload_part(self, cf: CloudFile, data: bytes):
208
218
  if self.field is None:
209
219
  raise AttributeError("No field configured")
@@ -215,6 +225,7 @@ class S3StorageField(StorageField):
215
225
  Body=data,
216
226
  )
217
227
 
228
+ @s3_ops_observer.wrap({"type": "finish_upload"})
218
229
  async def finish(self):
219
230
  if self.field is None:
220
231
  raise AttributeError("No field configured")
@@ -245,6 +256,7 @@ class S3StorageField(StorageField):
245
256
  jitter=backoff.random_jitter,
246
257
  max_tries=MAX_TRIES,
247
258
  )
259
+ @s3_ops_observer.wrap({"type": "complete_multipart"})
248
260
  async def _complete_multipart_upload(self):
249
261
  # if blocks is 0, it means the file is of zero length so we need to
250
262
  # trick it to finish a multiple part with no data.
@@ -264,6 +276,7 @@ class S3StorageField(StorageField):
264
276
  MultipartUpload=part_info,
265
277
  )
266
278
 
279
+ @s3_ops_observer.wrap({"type": "exists"})
267
280
  async def exists(self) -> Optional[ObjectMetadata]:
268
281
  """
269
282
  Existence can be checked either with a CloudFile data in the field attribute
@@ -292,6 +305,7 @@ class S3StorageField(StorageField):
292
305
  return None
293
306
  raise
294
307
 
308
+ @s3_ops_observer.wrap({"type": "copy"})
295
309
  async def copy(
296
310
  self,
297
311
  origin_uri: str,
@@ -305,6 +319,7 @@ class S3StorageField(StorageField):
305
319
  Key=destination_uri,
306
320
  )
307
321
 
322
+ @s3_ops_observer.wrap({"type": "move"})
308
323
  async def move(
309
324
  self,
310
325
  origin_uri: str,
@@ -396,6 +411,7 @@ class S3Storage(Storage):
396
411
  async def finalize(self):
397
412
  await self._exit_stack.__aexit__(None, None, None)
398
413
 
414
+ @s3_ops_observer.wrap({"type": "delete"})
399
415
  async def delete_upload(self, uri: str, bucket_name: str):
400
416
  if uri:
401
417
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nucliadb_utils
3
- Version: 6.0.0.post2306
3
+ Version: 6.0.0.post2314
4
4
  Home-page: https://nuclia.com
5
5
  License: BSD
6
6
  Classifier: Development Status :: 4 - Beta
@@ -24,8 +24,8 @@ Requires-Dist: PyNaCl
24
24
  Requires-Dist: pyjwt>=2.4.0
25
25
  Requires-Dist: memorylru>=1.1.2
26
26
  Requires-Dist: mrflagly>=0.2.9
27
- Requires-Dist: nucliadb-protos>=6.0.0.post2306
28
- Requires-Dist: nucliadb-telemetry>=6.0.0.post2306
27
+ Requires-Dist: nucliadb-protos>=6.0.0.post2314
28
+ Requires-Dist: nucliadb-telemetry>=6.0.0.post2314
29
29
  Provides-Extra: cache
30
30
  Requires-Dist: redis>=4.3.4; extra == "cache"
31
31
  Requires-Dist: orjson>=3.6.7; extra == "cache"
@@ -46,7 +46,7 @@ nucliadb_utils/storages/gcs.py,sha256=MUPPTmPo5AfCWPykNvlIO35-C_8r94yWJgBxcDsRIg
46
46
  nucliadb_utils/storages/local.py,sha256=kxofHdNy4QBtdM797AeksNjIUP2kw9vIC0X7AHABJBI,10374
47
47
  nucliadb_utils/storages/nuclia.py,sha256=vEv94xAT7QM2g80S25QyrOw2pzvP2BAX-ADgZLtuCVc,2097
48
48
  nucliadb_utils/storages/object_store.py,sha256=Tw10GmpYfM5TMqJ3Tk9pLQ9wLMBk1-snL_m6uasiZDQ,4257
49
- nucliadb_utils/storages/s3.py,sha256=nXyDCa1_cGGRNJ6j1SHhu84WL0ig3UGGpzzUajKPV6Q,19647
49
+ nucliadb_utils/storages/s3.py,sha256=pbuukqpce_kqkmI_3eUTo390KbM5rmI7h8wsYAXtTAo,20377
50
50
  nucliadb_utils/storages/settings.py,sha256=ugCPy1zxBOmA2KosT-4tsjpvP002kg5iQyi42yCGCJA,1285
51
51
  nucliadb_utils/storages/storage.py,sha256=onwQJ4at-XewEG7dxcWdOqobfCw4w0PyPC7olvFJgjI,20295
52
52
  nucliadb_utils/storages/utils.py,sha256=8g2rIwJeYIumQLOB47Yw1rx3twlhRB_cJxer65QfZmk,1479
@@ -59,8 +59,8 @@ nucliadb_utils/tests/indexing.py,sha256=YW2QhkhO9Q_8A4kKWJaWSvXvyQ_AiAwY1VylcfVQ
59
59
  nucliadb_utils/tests/local.py,sha256=fXIBasrvdaFJM-sw2wk1_oiFzBcm9O10iCyC-OiXwY8,1914
60
60
  nucliadb_utils/tests/nats.py,sha256=xqpww4jZjTKY9oPGlJdDJG67L3FIBQsa9qDHxILR8r8,7687
61
61
  nucliadb_utils/tests/s3.py,sha256=pl-RJFjA4MH6iXkqhsh5g8gDuEhrYu1nPZ-laxlrMlE,3704
62
- nucliadb_utils-6.0.0.post2306.dist-info/METADATA,sha256=Oef09iG7iuVLpjg6AOvHdufhybUdhR6D7l5WhxHy4ZQ,2055
63
- nucliadb_utils-6.0.0.post2306.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
64
- nucliadb_utils-6.0.0.post2306.dist-info/top_level.txt,sha256=fE3vJtALTfgh7bcAWcNhcfXkNPp_eVVpbKK-2IYua3E,15
65
- nucliadb_utils-6.0.0.post2306.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
66
- nucliadb_utils-6.0.0.post2306.dist-info/RECORD,,
62
+ nucliadb_utils-6.0.0.post2314.dist-info/METADATA,sha256=8dWHpv7r3E-6rY2Qisfuuw4CrA0Q8cnW2vLKtu1CgIU,2055
63
+ nucliadb_utils-6.0.0.post2314.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
64
+ nucliadb_utils-6.0.0.post2314.dist-info/top_level.txt,sha256=fE3vJtALTfgh7bcAWcNhcfXkNPp_eVVpbKK-2IYua3E,15
65
+ nucliadb_utils-6.0.0.post2314.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
66
+ nucliadb_utils-6.0.0.post2314.dist-info/RECORD,,