cdsetool 0.2.12__tar.gz → 0.2.13__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.
@@ -1,26 +1,26 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cdsetool
3
- Version: 0.2.12
3
+ Version: 0.2.13
4
4
  Summary: Tools & CLI for interacting with CDSE product APIs
5
5
  Author-email: Jacob Vejby <javej@sdfi.dk>
6
6
  Project-URL: Homepage, https://github.com/CDSETool/CDSETool
7
7
  Project-URL: Bug Tracker, https://github.com/CDSETool/CDSETool/issues
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
- Requires-Python: >=3.8
10
+ Requires-Python: >=3.9
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
13
  Requires-Dist: typer<1,>=0.9
14
14
  Requires-Dist: rich<14,>=13.6
15
15
  Requires-Dist: requests<3,>=2.28.1
16
- Requires-Dist: pyjwt[crypto]~=2.8.0
16
+ Requires-Dist: pyjwt[crypto]<2.10,>=2.8
17
17
  Requires-Dist: geopandas>=0.13.2
18
18
  Provides-Extra: test
19
- Requires-Dist: black==24.4.2; extra == "test"
20
- Requires-Dist: pylint==3.2.6; extra == "test"
21
- Requires-Dist: pytest==8.3.2; extra == "test"
19
+ Requires-Dist: pylint==3.3.1; extra == "test"
20
+ Requires-Dist: pytest==8.3.3; extra == "test"
22
21
  Requires-Dist: pytest-cov==5.0.0; extra == "test"
23
22
  Requires-Dist: requests-mock==1.12.1; extra == "test"
23
+ Requires-Dist: ruff==0.6.6; extra == "test"
24
24
  Requires-Dist: pytest-mock==3.14.0; extra == "test"
25
25
 
26
26
  # CDSETool
@@ -96,7 +96,7 @@ cdsetool download Sentinel2 PATH/TO/DIR --concurrency 4 --search-term startDate=
96
96
  Install `cdsetool` using pip:
97
97
 
98
98
  ```bash
99
- pip install cdsetool==0.2.12
99
+ pip install cdsetool==0.2.13
100
100
  ```
101
101
 
102
102
  ## Usage
@@ -71,7 +71,7 @@ cdsetool download Sentinel2 PATH/TO/DIR --concurrency 4 --search-term startDate=
71
71
  Install `cdsetool` using pip:
72
72
 
73
73
  ```bash
74
- pip install cdsetool==0.2.12
74
+ pip install cdsetool==0.2.13
75
75
  ```
76
76
 
77
77
  ## Usage
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cdsetool"
7
- version = "0.2.12"
7
+ version = "0.2.13"
8
8
  authors = [
9
9
  { name="Jacob Vejby", email="javej@sdfi.dk" },
10
10
  ]
11
11
  description = "Tools & CLI for interacting with CDSE product APIs"
12
12
  readme = "README.md"
13
- requires-python = ">=3.8"
13
+ requires-python = ">=3.9"
14
14
  classifiers = [
15
15
  "Programming Language :: Python :: 3",
16
16
  "Operating System :: OS Independent",
@@ -19,16 +19,16 @@ dependencies = [
19
19
  "typer >= 0.9,< 1",
20
20
  "rich >= 13.6,< 14",
21
21
  "requests >= 2.28.1,< 3",
22
- "pyjwt[crypto] ~= 2.8.0",
22
+ "pyjwt[crypto] >= 2.8,< 2.10",
23
23
  "geopandas >= 0.13.2",
24
24
  ]
25
25
  [project.optional-dependencies]
26
26
  test = [
27
- "black==24.4.2",
28
- "pylint==3.2.6",
29
- "pytest==8.3.2",
27
+ "pylint==3.3.1",
28
+ "pytest==8.3.3",
30
29
  "pytest-cov==5.0.0",
31
30
  "requests-mock==1.12.1",
31
+ "ruff==0.6.6",
32
32
  "pytest-mock==3.14.0",
33
33
  ]
34
34
 
@@ -52,7 +52,6 @@ def _concurrent_process(
52
52
 
53
53
  # Continue until no more futures are queued
54
54
  while futures:
55
-
56
55
  # Wait for the first future(s) to complete
57
56
  done, not_done = wait(futures, return_when=FIRST_COMPLETED)
58
57
  futures = list(not_done)
@@ -44,7 +44,7 @@ def download_feature(
44
44
  log.debug(f"Bad URL ('{url}') or title ('{title}')")
45
45
  return None
46
46
 
47
- filename = title.replace(".SAFE", ".zip")
47
+ filename = title + ".zip"
48
48
  result_path = os.path.join(path, filename)
49
49
 
50
50
  if not options.get("overwrite_existing", False) and os.path.exists(result_path):
@@ -67,9 +67,12 @@ def download_feature(
67
67
  continue
68
68
  url = _follow_redirect(url, session)
69
69
  name_dir_prefix = filename.replace(".zip", "____")
70
- with session.get(url, stream=True) as response, tempfile.TemporaryDirectory(
71
- prefix=name_dir_prefix, dir=temp_dir_usr
72
- ) as temp_dir:
70
+ with (
71
+ session.get(url, stream=True) as response,
72
+ tempfile.TemporaryDirectory(
73
+ prefix=name_dir_prefix, dir=temp_dir_usr
74
+ ) as temp_dir,
75
+ ):
73
76
  if response.status_code != 200:
74
77
  log.warning(f"Status code {response.status_code}, retrying..")
75
78
  time.sleep(60 * (1 + (random.random() / 4)))
@@ -9,8 +9,13 @@ from xml.etree import ElementTree
9
9
  from datetime import datetime, date
10
10
  import re
11
11
  import json
12
+ from random import random
13
+ from time import sleep
12
14
  import geopandas as gpd
15
+ from requests.exceptions import ChunkedEncodingError
16
+ from urllib3.exceptions import ProtocolError
13
17
  from cdsetool.credentials import Credentials
18
+ from cdsetool.logger import NoopLogger
14
19
 
15
20
 
16
21
  class _FeatureIterator:
@@ -48,9 +53,11 @@ class FeatureQuery:
48
53
  collection: str,
49
54
  search_terms: Dict[str, Any],
50
55
  proxies: Union[Dict[str, str], None] = None,
56
+ options: Union[Dict[str, Any], None] = None,
51
57
  ) -> None:
52
58
  self.features = []
53
59
  self.proxies = proxies
60
+ self.log = (options or {}).get("logger") or NoopLogger()
54
61
  self.next_url = _query_url(
55
62
  collection, {**search_terms, "exactCount": "1"}, proxies=proxies
56
63
  )
@@ -76,16 +83,29 @@ class FeatureQuery:
76
83
  session = Credentials.make_session(
77
84
  None, False, Credentials.RETRIES, self.proxies
78
85
  )
79
- with session.get(self.next_url) as response:
80
- response.raise_for_status()
81
- res = response.json()
82
- self.features += res.get("features") or []
83
-
84
- total_results = res.get("properties", {}).get("totalResults")
85
- if total_results is not None:
86
- self.total_results = total_results
87
-
88
- self.__set_next_url(res)
86
+ attempts = 0
87
+ while attempts < 10:
88
+ attempts += 1
89
+ try:
90
+ with session.get(self.next_url) as response:
91
+ if response.status_code != 200:
92
+ self.log.warning(
93
+ f"Status code {response.status_code}, retrying.."
94
+ )
95
+ sleep(60 * (1 + (random() / 4)))
96
+ continue
97
+ res = response.json()
98
+ self.features += res.get("features") or []
99
+
100
+ total_results = res.get("properties", {}).get("totalResults")
101
+ if total_results is not None:
102
+ self.total_results = total_results
103
+
104
+ self.__set_next_url(res)
105
+ return
106
+ except (ChunkedEncodingError, ConnectionResetError, ProtocolError) as e:
107
+ self.log.warning(e)
108
+ continue
89
109
 
90
110
  def __set_next_url(self, res) -> None:
91
111
  links = res.get("properties", {}).get("links") or []
@@ -101,11 +121,14 @@ def query_features(
101
121
  collection: str,
102
122
  search_terms: Dict[str, Any],
103
123
  proxies: Union[Dict[str, str], None] = None,
124
+ options: Union[Dict[str, Any], None] = None,
104
125
  ) -> FeatureQuery:
105
126
  """
106
127
  Returns an iterator over the features matching the search terms
107
128
  """
108
- return FeatureQuery(collection, {"maxRecords": 2000, **search_terms}, proxies)
129
+ return FeatureQuery(
130
+ collection, {"maxRecords": 2000, **search_terms}, proxies, options
131
+ )
109
132
 
110
133
 
111
134
  def shape_to_wkt(shape: str) -> str:
@@ -1,26 +1,26 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cdsetool
3
- Version: 0.2.12
3
+ Version: 0.2.13
4
4
  Summary: Tools & CLI for interacting with CDSE product APIs
5
5
  Author-email: Jacob Vejby <javej@sdfi.dk>
6
6
  Project-URL: Homepage, https://github.com/CDSETool/CDSETool
7
7
  Project-URL: Bug Tracker, https://github.com/CDSETool/CDSETool/issues
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
- Requires-Python: >=3.8
10
+ Requires-Python: >=3.9
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
13
  Requires-Dist: typer<1,>=0.9
14
14
  Requires-Dist: rich<14,>=13.6
15
15
  Requires-Dist: requests<3,>=2.28.1
16
- Requires-Dist: pyjwt[crypto]~=2.8.0
16
+ Requires-Dist: pyjwt[crypto]<2.10,>=2.8
17
17
  Requires-Dist: geopandas>=0.13.2
18
18
  Provides-Extra: test
19
- Requires-Dist: black==24.4.2; extra == "test"
20
- Requires-Dist: pylint==3.2.6; extra == "test"
21
- Requires-Dist: pytest==8.3.2; extra == "test"
19
+ Requires-Dist: pylint==3.3.1; extra == "test"
20
+ Requires-Dist: pytest==8.3.3; extra == "test"
22
21
  Requires-Dist: pytest-cov==5.0.0; extra == "test"
23
22
  Requires-Dist: requests-mock==1.12.1; extra == "test"
23
+ Requires-Dist: ruff==0.6.6; extra == "test"
24
24
  Requires-Dist: pytest-mock==3.14.0; extra == "test"
25
25
 
26
26
  # CDSETool
@@ -96,7 +96,7 @@ cdsetool download Sentinel2 PATH/TO/DIR --concurrency 4 --search-term startDate=
96
96
  Install `cdsetool` using pip:
97
97
 
98
98
  ```bash
99
- pip install cdsetool==0.2.12
99
+ pip install cdsetool==0.2.13
100
100
  ```
101
101
 
102
102
  ## Usage
@@ -1,13 +1,13 @@
1
1
  typer<1,>=0.9
2
2
  rich<14,>=13.6
3
3
  requests<3,>=2.28.1
4
- pyjwt[crypto]~=2.8.0
4
+ pyjwt[crypto]<2.10,>=2.8
5
5
  geopandas>=0.13.2
6
6
 
7
7
  [test]
8
- black==24.4.2
9
- pylint==3.2.6
10
- pytest==8.3.2
8
+ pylint==3.3.1
9
+ pytest==8.3.3
11
10
  pytest-cov==5.0.0
12
11
  requests-mock==1.12.1
12
+ ruff==0.6.6
13
13
  pytest-mock==3.14.0
File without changes
File without changes
File without changes