specklia 1.9.16__py3-none-any.whl → 1.9.17__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.
@@ -25,16 +25,21 @@ from http import HTTPStatus
25
25
  from io import BytesIO
26
26
  from logging import Logger
27
27
  import struct
28
+ import time
28
29
  from typing import List, Tuple, Union
29
30
 
30
- from geopandas import GeoDataFrame, read_feather as read_geofeather
31
- from pandas import DataFrame, read_feather
31
+ from geopandas import GeoDataFrame
32
+ from geopandas import read_feather as read_geofeather
33
+ from pandas import DataFrame
34
+ from pandas import read_feather
32
35
  import requests
33
36
 
34
37
  CHUNK_DB_NAME = "data_transfer_chunks"
35
38
  CHUNK_METADATA_COLLECTION_NAME = "chunk_metadata"
36
39
  MAX_CHUNK_AGE_SECONDS = 3600
37
40
  MAX_CHUNK_SIZE_BYTES = 5 * 1024 ** 2 # must be small enough to fit into an HTTP GET Request
41
+ CHUNK_DOWNLOAD_RETRIES = 10
42
+ CHUNK_DOWNLOAD_TIMEOUT_S = 10
38
43
 
39
44
 
40
45
  class ChunkSetStatus(Enum):
@@ -87,7 +92,7 @@ def upload_chunks(api_address: str, chunks: List[Tuple[int, bytes]], logger: Log
87
92
  return chunk_set_uuid
88
93
 
89
94
 
90
- def download_chunks(api_address: str, chunk_set_uuid: str) -> List[Tuple[int, bytes]]:
95
+ def download_chunks(api_address: str, chunk_set_uuid: str, logger: Logger) -> List[Tuple[int, bytes]]:
91
96
  """
92
97
  Download data chunks.
93
98
 
@@ -100,24 +105,52 @@ def download_chunks(api_address: str, chunk_set_uuid: str) -> List[Tuple[int, by
100
105
  The full URL of the API, including port but not including endpoint, e.g. "http://127.0.0.1:9999"
101
106
  chunk_set_uuid : str
102
107
  The uuid of the chunk set to download.
108
+ logger : Logger
109
+ A logger with which to log the download.
103
110
 
104
111
  Returns
105
112
  -------
106
113
  chunks : List[Tuple[int, bytes]]
107
114
  A list of tuples containing the ordinal number of the chunk and each chunk
115
+
116
+ Raises
117
+ ------
118
+ RuntimeError
119
+ If the download fails after a number of retries.
108
120
  """
109
121
  # fetch the data
110
122
  data_chunks = []
111
123
  finished = False
124
+
112
125
  while not finished:
113
- this_chunk_response = requests.get(api_address + f"/chunk/download/{chunk_set_uuid}")
114
- if this_chunk_response.status_code == HTTPStatus.NO_CONTENT:
115
- finished = True
116
- else:
117
- data_chunks.append((
118
- struct.unpack('i', this_chunk_response.content[:4])[0],
119
- this_chunk_response.content[4:]))
126
+ retries = 0
127
+ success = False
120
128
 
129
+ while retries < CHUNK_DOWNLOAD_RETRIES and not success:
130
+ try:
131
+ this_chunk_response = requests.get(
132
+ f"{api_address}/chunk/download/{chunk_set_uuid}",
133
+ timeout=CHUNK_DOWNLOAD_TIMEOUT_S
134
+ )
135
+ if this_chunk_response.status_code == HTTPStatus.NO_CONTENT:
136
+ finished = True
137
+ else:
138
+ data_chunks.append((
139
+ struct.unpack('i', this_chunk_response.content[:4])[0],
140
+ this_chunk_response.content[4:]))
141
+ success = True
142
+
143
+ except (requests.Timeout, requests.ConnectionError) as e:
144
+ retries += 1
145
+ logger.warning(
146
+ "Request failed with %s. Retrying (%s/%s)...", e, retries, CHUNK_DOWNLOAD_RETRIES)
147
+ time.sleep(1) # Small backoff before retrying
148
+
149
+ if not success:
150
+ error_message = (
151
+ f"Failed to download from chunk set {chunk_set_uuid} after {CHUNK_DOWNLOAD_TIMEOUT_S} attempts.")
152
+ logger.error(error_message)
153
+ raise RuntimeError(error_message)
121
154
  return data_chunks
122
155
 
123
156
 
specklia/client.py CHANGED
@@ -232,7 +232,7 @@ class Specklia:
232
232
  gdf = chunked_transfer.deserialise_dataframe(
233
233
  chunked_transfer.merge_from_chunks(
234
234
  chunked_transfer.download_chunks(
235
- self.server_url, response_dict['chunk_set_uuid'])))
235
+ self.server_url, response_dict['chunk_set_uuid'], _log)))
236
236
  else:
237
237
  gdf = gpd.GeoDataFrame()
238
238
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: specklia
3
- Version: 1.9.16
3
+ Version: 1.9.17
4
4
  Summary: Python client for Specklia, a geospatial point cloud database by Earthwave.
5
5
  Home-page: https://specklia.earthwave.co.uk/
6
6
  Author: Earthwave Ltd
@@ -0,0 +1,9 @@
1
+ specklia/__init__.py,sha256=ePVHqq642NocoE8tS0cNTd0B5wJdUB7r3y815oQXD6A,51
2
+ specklia/chunked_transfer.py,sha256=Mw0wLaOYzNvVTRE421RdHnsnaDbEpNYgQNGV_kcjuVs,8327
3
+ specklia/client.py,sha256=P4XXzC24OuLK5S6joc7d0zt9Q39-IveAK87EUCF7n3M,41858
4
+ specklia/utilities.py,sha256=0_pgTbcq2RgQhys0-CZ6h5YZJg9ZMPhD_ibGPggFUpE,5018
5
+ specklia-1.9.17.dist-info/LICENCE,sha256=kjWTA-TtT_rJtsWuAgWvesvu01BytVXgt_uCbeQgjOg,1061
6
+ specklia-1.9.17.dist-info/METADATA,sha256=AUV3Mor8hxiA330rCnyWHMhpgf5uq7MKoEULcDpw2xE,3082
7
+ specklia-1.9.17.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
+ specklia-1.9.17.dist-info/top_level.txt,sha256=XgU53UpAJbqEni5EjJaPdQPYuNx16Geg2I5A9lo1BQw,9
9
+ specklia-1.9.17.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- specklia/__init__.py,sha256=ePVHqq642NocoE8tS0cNTd0B5wJdUB7r3y815oQXD6A,51
2
- specklia/chunked_transfer.py,sha256=hO7luSNjznsH-8s585PFNks1agn3cj6v_Sxg_nLVdM8,7179
3
- specklia/client.py,sha256=6grKdJwtRUsj5u3I91rbJFVXvLONS-CoPNy9BUr6LVw,41852
4
- specklia/utilities.py,sha256=0_pgTbcq2RgQhys0-CZ6h5YZJg9ZMPhD_ibGPggFUpE,5018
5
- specklia-1.9.16.dist-info/LICENCE,sha256=kjWTA-TtT_rJtsWuAgWvesvu01BytVXgt_uCbeQgjOg,1061
6
- specklia-1.9.16.dist-info/METADATA,sha256=rNtsnqyOI9BLCe8LMLBKZj1wF9ZyG4R_9qWg1tFAvcs,3082
7
- specklia-1.9.16.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
- specklia-1.9.16.dist-info/top_level.txt,sha256=XgU53UpAJbqEni5EjJaPdQPYuNx16Geg2I5A9lo1BQw,9
9
- specklia-1.9.16.dist-info/RECORD,,