rapidata 2.21.3__py3-none-any.whl → 2.21.5__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.

Potentially problematic release.


This version of rapidata might be problematic. Click here for more details.

@@ -18,7 +18,7 @@ from typing import Dict, Optional
18
18
 
19
19
  import httpx
20
20
  from authlib.integrations.httpx_client import OAuth2Client
21
- from httpx import Timeout
21
+ from httpx import Timeout, ConnectError
22
22
 
23
23
  from rapidata.api_client.exceptions import ApiException, ApiValueError
24
24
 
@@ -67,7 +67,13 @@ class RESTClientObject:
67
67
  **client_args,
68
68
  )
69
69
 
70
- self.session.fetch_token()
70
+ try:
71
+ self.session.fetch_token()
72
+ except ConnectError as e:
73
+ if self._is_certificate_validation_error(e):
74
+ exit(self._get_ssl_verify_error_message())
75
+ else:
76
+ raise
71
77
 
72
78
  def setup_oauth_with_token(
73
79
  self,
@@ -218,14 +224,18 @@ class RESTClientObject:
218
224
  raise ApiException(status=0, reason=msg)
219
225
 
220
226
  else:
221
- r = session.request(
222
- method, url, timeout=timeout, headers=headers
223
- )
227
+ r = session.request(method, url, timeout=timeout, headers=headers)
224
228
 
225
229
  except httpx.HTTPError as e:
226
230
  msg = "\n".join([type(e).__name__, str(e)])
227
231
  raise ApiException(status=0, reason=msg)
228
232
 
233
+ except ConnectError as e:
234
+ if self._is_certificate_validation_error(e):
235
+ exit(self._get_ssl_verify_error_message())
236
+ else:
237
+ raise
238
+
229
239
  return RESTResponse(r)
230
240
 
231
241
  def _get_session_defaults(self):
@@ -251,3 +261,28 @@ class RESTClientObject:
251
261
  client_kwargs["transport"] = transport
252
262
 
253
263
  return client_kwargs
264
+
265
+ @staticmethod
266
+ def _is_certificate_validation_error(error: ConnectError) -> bool:
267
+ """
268
+ Check if the error is related to certificate validation.
269
+ """
270
+ return error.args[0].startswith("[SSL: CERTIFICATE_VERIFY_FAILED]")
271
+
272
+ @staticmethod
273
+ def _get_ssl_verify_error_message() -> str:
274
+ return """
275
+ We encountered an issue while trying to verify the SSL certificate.
276
+ This often happens on macOS when using the default Python installation provided by Apple,
277
+ which lacks the required certificates to perform secure HTTPS requests.
278
+ To resolve this, please perform the following steps:
279
+ 1. Make sure you are using the latest version of the Rapidata Package: `pip install --upgrade rapidata`
280
+ 2. If you are using the default Python installation from Apple, consider switching to a different Python distribution, such as Homebrew or pyenv.
281
+ 3. If you prefer to continue using the default Python, you can run the following command in your terminal:
282
+ `/Applications/Python\\ 3.1*/Install\\ Certificates.command`
283
+
284
+ For more details on this issue, please refer to the following link:
285
+ https://stackoverflow.com/questions/42098126/mac-osx-python-ssl-sslerror-ssl-certificate-verify-failed-certificate-verify
286
+
287
+ If the issue persists, please reach out to us at 'info@rapidata.ai', we're happy to help you.
288
+ """
@@ -7,3 +7,4 @@ from ._media_asset import MediaAsset
7
7
  from ._text_asset import TextAsset
8
8
  from ._multi_asset import MultiAsset
9
9
  from .data_type_enum import RapidataDataTypes
10
+ from ._sessions import SessionManager
@@ -4,7 +4,7 @@ Defines the MediaAsset class for handling media file paths within assets.
4
4
  Implements lazy loading for URL-based media to prevent unnecessary downloads.
5
5
  """
6
6
 
7
- from typing import Optional, cast, Sequence
7
+ from typing import Optional, cast
8
8
  import os
9
9
  from io import BytesIO
10
10
  from rapidata.rapidata_client.assets._base_asset import BaseAsset
@@ -16,8 +16,7 @@ import tempfile
16
16
  from pydantic import StrictStr, StrictBytes
17
17
  import logging
18
18
  from functools import cached_property
19
- from requests.adapters import HTTPAdapter
20
- from urllib3.util.retry import Retry
19
+ from rapidata.rapidata_client.assets._sessions import SessionManager
21
20
 
22
21
  class MediaAsset(BaseAsset):
23
22
  """MediaAsset Class with Lazy Loading
@@ -78,7 +77,7 @@ class MediaAsset(BaseAsset):
78
77
 
79
78
  self._url = None
80
79
  self._content = None
81
- self.session: None | requests.Session = None
80
+ self.session: requests.Session = SessionManager.get_session()
82
81
 
83
82
  if re.match(r'^https?://', path):
84
83
  self._url = path
@@ -130,11 +129,11 @@ class MediaAsset(BaseAsset):
130
129
  tmp.flush()
131
130
  tmp_path = tmp.name
132
131
 
133
- try:
134
- tag = TinyTag.get(tmp_path)
135
- finally:
136
- # Clean up the temporary file
137
- os.unlink(tmp_path)
132
+ try:
133
+ tag = TinyTag.get(tmp_path)
134
+ finally:
135
+ # Clean up the temporary file
136
+ os.unlink(tmp_path)
138
137
 
139
138
  if tag.duration is None:
140
139
  raise ValueError("Could not read duration from file")
@@ -0,0 +1,35 @@
1
+ import requests
2
+ from requests.adapters import HTTPAdapter
3
+ from urllib3.util.retry import Retry
4
+
5
+ class SessionManager:
6
+ _session = None
7
+
8
+ @classmethod
9
+ def get_session(cls, ) -> requests.Session:
10
+ """Get a singleton requests session with retry logic.
11
+
12
+ Returns:
13
+ requests.Session: A singleton requests session with retry logic.
14
+ """
15
+ if cls._session is None:
16
+ max_retries: int = 5
17
+ max_workers: int = 10
18
+ cls._session = requests.Session()
19
+ retries = Retry(
20
+ total=max_retries,
21
+ backoff_factor=1,
22
+ status_forcelist=[500, 502, 503, 504],
23
+ allowed_methods=["GET"],
24
+ respect_retry_after_header=True
25
+ )
26
+
27
+ adapter = HTTPAdapter(
28
+ pool_connections=max_workers * 2,
29
+ pool_maxsize=max_workers * 4,
30
+ max_retries=retries
31
+ )
32
+ cls._session.mount('http://', adapter)
33
+ cls._session.mount('https://', adapter)
34
+
35
+ return cls._session
@@ -25,38 +25,6 @@ class DemographicManager:
25
25
  title=instruction
26
26
  )
27
27
  )
28
- session = self._get_session()
29
- media.session = session
30
28
 
31
29
  self._openapi_service.rapid_api.rapid_demographic_post(model=model, file=[media.to_file()])
32
-
33
- def _get_session(self, max_retries: int = 5, max_workers: int = 10) -> requests.Session:
34
- """Get a requests session with retry logic.
35
-
36
-
37
- Args:
38
- max_retries (int): The maximum number of retries.
39
- max_workers (int): The maximum number of workers.
40
-
41
- Returns:
42
- requests.Session: A requests session with retry logic.
43
- """
44
- session = requests.Session()
45
- retries = Retry(
46
- total=max_retries,
47
- backoff_factor=1,
48
- status_forcelist=[500, 502, 503, 504],
49
- allowed_methods=["GET"],
50
- respect_retry_after_header=True
51
- )
52
-
53
- adapter = HTTPAdapter(
54
- pool_connections=max_workers * 2,
55
- pool_maxsize=max_workers * 4,
56
- max_retries=retries
57
- )
58
- session.mount('http://', adapter)
59
- session.mount('https://', adapter)
60
-
61
- return session
62
30
 
@@ -89,7 +89,6 @@ class RapidataDataset:
89
89
  media_asset: MediaAsset or MultiAsset to upload
90
90
  meta: Optional metadata for the asset
91
91
  index: Sort index for the upload
92
- session: Requests session for HTTP requests
93
92
 
94
93
  Returns:
95
94
  tuple[list[str], list[str]]: Lists of successful and failed identifiers
@@ -272,7 +271,6 @@ class RapidataDataset:
272
271
  Args:
273
272
  media_paths: List of assets to upload
274
273
  metadata: Optional sequence of metadata
275
- session: Requests session for HTTP requests
276
274
  max_workers: Maximum number of concurrent workers
277
275
  chunk_size: Number of items to process in each batch
278
276
  stop_progress_tracking: Event to signal progress tracking to stop
@@ -50,7 +50,7 @@ class RapidataOrder:
50
50
 
51
51
  def run(self, print_link: bool = True) -> "RapidataOrder":
52
52
  """Runs the order to start collecting responses."""
53
- self.__openapi_service.order_api.order_submit_post(self.order_id)
53
+ self.__openapi_service.order_api.order_order_id_submit_post(self.order_id)
54
54
  if print_link:
55
55
  print(f"Order '{self.name}' is now viewable under: {self.order_details_page}")
56
56
  return self
@@ -3,6 +3,7 @@ from rapidata.service.openapi_service import OpenAPIService
3
3
  from requests.adapters import HTTPAdapter, Retry
4
4
  import requests
5
5
  from rapidata.api_client.models.update_dimensions_model import UpdateDimensionsModel
6
+ from rapidata.rapidata_client.assets._sessions import SessionManager
6
7
 
7
8
  class RapidataValidationSet:
8
9
  """A class for interacting with a Rapidata validation set.
@@ -20,7 +21,6 @@ class RapidataValidationSet:
20
21
  self.id = validation_set_id
21
22
  self.name = name
22
23
  self.__openapi_service = openapi_service
23
- self.__session = self._get_session()
24
24
 
25
25
  def add_rapid(self, rapid: Rapid):
26
26
  """Add a Rapid to the validation set.
@@ -28,7 +28,7 @@ class RapidataValidationSet:
28
28
  Args:
29
29
  rapid (Rapid): The Rapid to add to the validation set.
30
30
  """
31
- rapid._add_to_validation_set(self.id, self.__openapi_service, self.__session)
31
+ rapid._add_to_validation_set(self.id, self.__openapi_service)
32
32
  return self
33
33
 
34
34
  def update_dimensions(self, dimensions: list[str]):
@@ -40,36 +40,6 @@ class RapidataValidationSet:
40
40
  self.__openapi_service.validation_api.validation_validation_set_id_dimensions_patch(self.id, UpdateDimensionsModel(dimensions=dimensions))
41
41
  return self
42
42
 
43
- def _get_session(self, max_retries: int = 5, max_workers: int = 10) -> requests.Session:
44
- """Get a requests session with retry logic.
45
-
46
-
47
- Args:
48
- max_retries (int): The maximum number of retries.
49
- max_workers (int): The maximum number of workers.
50
-
51
- Returns:
52
- requests.Session: A requests session with retry logic.
53
- """
54
- session = requests.Session()
55
- retries = Retry(
56
- total=max_retries,
57
- backoff_factor=1,
58
- status_forcelist=[500, 502, 503, 504],
59
- allowed_methods=["GET"],
60
- respect_retry_after_header=True
61
- )
62
-
63
- adapter = HTTPAdapter(
64
- pool_connections=max_workers * 2,
65
- pool_maxsize=max_workers * 4,
66
- max_retries=retries
67
- )
68
- session.mount('http://', adapter)
69
- session.mount('https://', adapter)
70
-
71
- return session
72
-
73
43
  def __str__(self):
74
44
  return f"name: '{self.name}' id: {self.id}"
75
45
 
@@ -30,14 +30,14 @@ class Rapid():
30
30
  self.randomCorrectProbability = randomCorrectProbability
31
31
  self.explanation = explanation
32
32
 
33
- def _add_to_validation_set(self, validationSetId: str, openapi_service: OpenAPIService, session: requests.Session) -> None:
33
+ def _add_to_validation_set(self, validationSetId: str, openapi_service: OpenAPIService) -> None:
34
34
  if isinstance(self.asset, TextAsset) or (isinstance(self.asset, MultiAsset) and isinstance(self.asset.assets[0], TextAsset)):
35
35
  openapi_service.validation_api.validation_add_validation_text_rapid_post(
36
36
  add_validation_text_rapid_model=self.__to_text_model(validationSetId)
37
37
  )
38
38
 
39
39
  elif isinstance(self.asset, MediaAsset) or (isinstance(self.asset, MultiAsset) and isinstance(self.asset.assets[0], MediaAsset)):
40
- model = self.__to_media_model(validationSetId, session=session)
40
+ model = self.__to_media_model(validationSetId)
41
41
  openapi_service.validation_api.validation_add_validation_rapid_post(
42
42
  model=model[0], files=model[1]
43
43
  )
@@ -45,7 +45,7 @@ class Rapid():
45
45
  else:
46
46
  raise TypeError("The asset must be a MediaAsset, TextAsset, or MultiAsset")
47
47
 
48
- def __to_media_model(self, validationSetId: str, session: requests.Session) -> tuple[AddValidationRapidModel, list[StrictStr | tuple[StrictStr, StrictBytes] | StrictBytes]]:
48
+ def __to_media_model(self, validationSetId: str) -> tuple[AddValidationRapidModel, list[StrictStr | tuple[StrictStr, StrictBytes] | StrictBytes]]:
49
49
  assets: list[MediaAsset] = []
50
50
  if isinstance(self.asset, MultiAsset):
51
51
  for asset in self.asset.assets:
@@ -60,9 +60,6 @@ class Rapid():
60
60
  if isinstance(self.asset, MediaAsset):
61
61
  assets = [self.asset]
62
62
 
63
- for asset in assets:
64
- asset.session = session
65
-
66
63
  return (AddValidationRapidModel(
67
64
  validationSetId=validationSetId,
68
65
  payload=AddValidationRapidModelPayload(self.payload),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rapidata
3
- Version: 2.21.3
3
+ Version: 2.21.5
4
4
  Summary: Rapidata package containing the Rapidata Python Client to interact with the Rapidata Web API in an easy way.
5
5
  License: Apache-2.0
6
6
  Author: Rapidata AG
@@ -412,21 +412,22 @@ rapidata/api_client/models/workflow_labeling_step_model.py,sha256=iXeIb78bdMhGFj
412
412
  rapidata/api_client/models/workflow_split_model.py,sha256=zthOSaUl8dbLhLymLK_lrPTBpeV1a4cODLxnHmNCAZw,4474
413
413
  rapidata/api_client/models/workflow_split_model_filter_configs_inner.py,sha256=1Fx9uZtztiiAdMXkj7YeCqt7o6VkG9lKf7D7UP_h088,7447
414
414
  rapidata/api_client/models/workflow_state.py,sha256=5LAK1se76RCoozeVB6oxMPb8p_5bhLZJqn7q5fFQWis,850
415
- rapidata/api_client/rest.py,sha256=WTkaOPZhB24TG2mV7Ih5Km76lo2ySQXFjR98nyFIGIM,9013
415
+ rapidata/api_client/rest.py,sha256=GNfE2rN_YHkiWzXiuoTHd9QlWbO99skiqwkfs3j4VHo,10834
416
416
  rapidata/api_client_README.md,sha256=XxKjqTKsOlLbAyeUNmJWnQU2Kc7LYOsJLUZ0Q_SEIIo,55005
417
417
  rapidata/rapidata_client/__init__.py,sha256=XP9btoeEBcUfLP_4Hi-tqmIsy__L7Q0l4LY1GRQZSKk,974
418
418
  rapidata/rapidata_client/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
419
419
  rapidata/rapidata_client/api/rapidata_exception.py,sha256=pJDMX5Pk1SSkxyt6PE0MCP2PQ13374qsi9SBWJYXbJI,3726
420
- rapidata/rapidata_client/assets/__init__.py,sha256=hKgrOSn8gJcBSULaf4auYhH1S1N5AfcwIhBSq1BOKwQ,323
420
+ rapidata/rapidata_client/assets/__init__.py,sha256=eQkqUrYFME1FCxPY2Xh2bbonKVPnsFElJ6aPFcsWGxI,361
421
421
  rapidata/rapidata_client/assets/_base_asset.py,sha256=B2YWH1NgaeYUYHDW3OPpHM_bqawHbH4EjnRCE2BYwiM,298
422
- rapidata/rapidata_client/assets/_media_asset.py,sha256=9IKNKWarBJ-aAxfTjh80ScNsHlWGJnd55fsDbrf8x4s,10336
422
+ rapidata/rapidata_client/assets/_media_asset.py,sha256=63I_l3E838M7ltqf3Bl8-PJOSm_h_FCeKYvUV52BwfI,10313
423
423
  rapidata/rapidata_client/assets/_multi_asset.py,sha256=92r6JsF9Sr93-9JyspoWw1_rNDC3pYInyfDAPybHYbU,2025
424
+ rapidata/rapidata_client/assets/_sessions.py,sha256=Dgcb61Q4gLwU5hurnv6sN2Jvw-ZV7vjhVWXog5Wq4aw,1094
424
425
  rapidata/rapidata_client/assets/_text_asset.py,sha256=itoe3vicn41LbdJ7UeydImORUo9iDL0SZu-ptOlbMRM,618
425
426
  rapidata/rapidata_client/assets/data_type_enum.py,sha256=ELC-ymeKnQlfNAzfqsI7MmUuRiGYamCHVcTc0qR6Fm4,185
426
427
  rapidata/rapidata_client/country_codes/__init__.py,sha256=FB9Dcks44J6C6YBSYmTmNZ71tE130x6NO_3aLJ8fKzQ,40
427
428
  rapidata/rapidata_client/country_codes/country_codes.py,sha256=ePHqeb7y9DWQZAnddBzPx1puYBcrgUjdR2sbFijuFD8,283
428
429
  rapidata/rapidata_client/demographic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
429
- rapidata/rapidata_client/demographic/demographic_manager.py,sha256=XlgXngx-37Sow2B3jisVIWo6NrMWVI7aJqu9OwF9kCA,2143
430
+ rapidata/rapidata_client/demographic/demographic_manager.py,sha256=nY0WpgItwc5q_Lf-bqM4HhestMKj3V20vX96TVzWdlk,1151
430
431
  rapidata/rapidata_client/filter/__init__.py,sha256=uHemzncxZrrs3fiKQ-spbNe6EJZ1aWxHIH6DVy2pLUo,471
431
432
  rapidata/rapidata_client/filter/_base_filter.py,sha256=ytiSyeb9dvNZf93zwgb4PRDzf9ebsAu4wHBn4x49Re0,195
432
433
  rapidata/rapidata_client/filter/age_filter.py,sha256=oRjGY65gE_X8oa0D0XRyvKAb4_Z6XOOaGTWykRSfLFA,739
@@ -450,9 +451,9 @@ rapidata/rapidata_client/metadata/_prompt_metadata.py,sha256=ecycAq_t2HCEptxgNxy
450
451
  rapidata/rapidata_client/metadata/_public_text_metadata.py,sha256=uXavDp1ucy_9u5n0girqWD_SkFr7tplGMK_2aqyyHIA,529
451
452
  rapidata/rapidata_client/metadata/_select_words_metadata.py,sha256=-MK5yQDi_G3BKEes6aaVyCcobB-sEy29b6bfo5f4pic,594
452
453
  rapidata/rapidata_client/order/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
453
- rapidata/rapidata_client/order/_rapidata_dataset.py,sha256=tjUfOyDjS94xVJsebjbE5Z18hYtpaL7jwMMVjbqHwc4,19498
454
+ rapidata/rapidata_client/order/_rapidata_dataset.py,sha256=oT__-coaYV8OdsZmvEXLDqn49qfWd6UnbKS9dw9XJpk,19386
454
455
  rapidata/rapidata_client/order/_rapidata_order_builder.py,sha256=De-gNvOnuXHz6QaRdNpr0_3zOkIEKu8hgtZkatzxZQ4,13155
455
- rapidata/rapidata_client/order/rapidata_order.py,sha256=6Ak0fz0W_NUeRWz3gSTcirNTNbgEgMgruhwwEQ0BY4I,11050
456
+ rapidata/rapidata_client/order/rapidata_order.py,sha256=BfyRmqCL3uZWfCZ4_vnZRyVGGGMh1XUFo87Ll3DBwyw,11059
456
457
  rapidata/rapidata_client/order/rapidata_order_manager.py,sha256=2HUo6d1z1qUw2PiETHlzh9fmBsCGNDPUPxVc_Udq4i8,30638
457
458
  rapidata/rapidata_client/order/rapidata_results.py,sha256=0y8EOiqUV7XuwpRJyV53mfo-ddRV1cUPdWexbPEVOHM,8044
458
459
  rapidata/rapidata_client/rapidata_client.py,sha256=fcWlmmNCZahK40Ox4aY153tEihIpwkUxYTuiypKF2SY,2857
@@ -483,10 +484,10 @@ rapidata/rapidata_client/settings/play_video_until_the_end.py,sha256=LLHx2_72k5Z
483
484
  rapidata/rapidata_client/settings/rapidata_settings.py,sha256=r6eDGo5YHMekOtWqPHD50uI8vEE9VoBJfaWEDFZ78RU,1430
484
485
  rapidata/rapidata_client/settings/translation_behaviour.py,sha256=i9n_H0eKJyKW6m3MKH_Cm1XEKWVEWsAV_79xGmGIC-4,742
485
486
  rapidata/rapidata_client/validation/__init__.py,sha256=s5wHVtcJkncXSFuL9I0zNwccNOKpWAqxqUjkeohzi2E,24
486
- rapidata/rapidata_client/validation/rapidata_validation_set.py,sha256=GaatGGuJCHRvdPbjzI0NRQhxzRftKzf-FkaFv25iB78,2649
487
+ rapidata/rapidata_client/validation/rapidata_validation_set.py,sha256=Hpk445_-myEiDk1Kr91INVn9jLLmBR0GrLxF_VP44V0,1735
487
488
  rapidata/rapidata_client/validation/rapids/__init__.py,sha256=WU5PPwtTJlte6U90MDakzx4I8Y0laj7siw9teeXj5R0,21
488
489
  rapidata/rapidata_client/validation/rapids/box.py,sha256=t3_Kn6doKXdnJdtbwefXnYKPiTKHneJl9E2inkDSqL8,589
489
- rapidata/rapidata_client/validation/rapids/rapids.py,sha256=uCKnoSn1RykNHgTFbrvCFlfzU8lF42cff-2I-Pd48w0,4620
490
+ rapidata/rapidata_client/validation/rapids/rapids.py,sha256=2X-Rmt1K2rxzmwIiSoBVPvu_TW2qnvlCct-6KZdpJks,4483
490
491
  rapidata/rapidata_client/validation/rapids/rapids_manager.py,sha256=s5VAq8H5CKACWfmIQuz9kHC8t2nd-xEHGGUj9pIfXKI,14386
491
492
  rapidata/rapidata_client/validation/validation_set_manager.py,sha256=GCFDyruCz6EIN67cc2fwRjzirUoGfs3KLTIg7n6wXbI,26722
492
493
  rapidata/rapidata_client/workflow/__init__.py,sha256=7nXcY91xkxjHudBc9H0fP35eBBtgwHGWTQKbb-M4h7Y,477
@@ -504,7 +505,7 @@ rapidata/service/__init__.py,sha256=s9bS1AJZaWIhLtJX_ZA40_CK39rAAkwdAmymTMbeWl4,
504
505
  rapidata/service/credential_manager.py,sha256=3x-Fb6tyqmgtpjI1MSOtXWW_SkzTK8Lo7I0SSL2YD7E,8602
505
506
  rapidata/service/local_file_service.py,sha256=pgorvlWcx52Uh3cEG6VrdMK_t__7dacQ_5AnfY14BW8,877
506
507
  rapidata/service/openapi_service.py,sha256=nh7gAmNRdZ5qu3sG7khi-pZmXhfg5u8KHdmEDQd_z9U,4075
507
- rapidata-2.21.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
508
- rapidata-2.21.3.dist-info/METADATA,sha256=ksb-YVRyFbsMb8kS94NtaeJFtly_1qIOFUpHHGmPSa8,1227
509
- rapidata-2.21.3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
510
- rapidata-2.21.3.dist-info/RECORD,,
508
+ rapidata-2.21.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
509
+ rapidata-2.21.5.dist-info/METADATA,sha256=bGj-l5qi005Z0QPBuKotjt9_ZlAicC_oW-Cj77htGho,1227
510
+ rapidata-2.21.5.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
511
+ rapidata-2.21.5.dist-info/RECORD,,