Skip to content

Commit 1fe9b4c

Browse files
author
Phil Varner
authored
change Dict and List to dict and list (#116)
1 parent 3b1ab5b commit 1fe9b4c

File tree

8 files changed

+74
-76
lines changed

8 files changed

+74
-76
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ This library is based on a [branch of cirrus-lib](https://github.com/cirrus-geo/
1515
## Quickstart for Creating New Tasks
1616

1717
```python
18-
from typing import Any, Dict, List
18+
from typing import Any
1919

2020
from stactask import Task
2121

2222
class MyTask(Task):
2323
name = "my-task"
2424
description = "this task does it all"
2525

26-
def validate(self, payload: Dict[str, Any]) -> bool:
26+
def validate(self, payload: dict[str, Any]) -> bool:
2727
return len(self.items) == 1
2828

29-
def process(self, **kwargs: Any) -> List[Dict[str, Any]]:
29+
def process(self, **kwargs: Any) -> list[dict[str, Any]]:
3030
item = self.items[0]
3131

3232
# download a datafile

stactask/asset_io.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import os
44
from os import path as op
5-
from typing import Any, Dict, Iterable, List, Optional, Union
5+
from typing import Any, Iterable, Optional, Union
66
from urllib.parse import urlparse
77

88
import fsspec
@@ -37,7 +37,7 @@ async def download_file(fs: AbstractFileSystem, src: str, dest: str) -> None:
3737

3838
async def download_item_assets(
3939
item: Item,
40-
assets: Optional[List[str]] = None,
40+
assets: Optional[list[str]] = None,
4141
save_item: bool = True,
4242
overwrite: bool = False,
4343
path_template: str = "${collection}/${id}",
@@ -91,40 +91,40 @@ async def download_item_assets(
9191
return new_item
9292

9393

94-
async def download_items_assets(items: Iterable[Item], **kwargs: Any) -> List[Item]:
94+
async def download_items_assets(items: Iterable[Item], **kwargs: Any) -> list[Item]:
9595
tasks = []
9696
for item in items:
9797
tasks.append(asyncio.create_task(download_item_assets(item, **kwargs)))
98-
new_items: List[Item] = await asyncio.gather(*tasks)
98+
new_items: list[Item] = await asyncio.gather(*tasks)
9999
return new_items
100100

101101

102102
def upload_item_assets_to_s3(
103103
item: Item,
104-
assets: Optional[List[str]] = None,
105-
public_assets: Union[None, List[str], str] = None,
104+
assets: Optional[list[str]] = None,
105+
public_assets: Union[None, list[str], str] = None,
106106
path_template: str = "${collection}/${id}",
107107
s3_urls: bool = False,
108-
headers: Optional[Dict[str, Any]] = None,
108+
headers: Optional[dict[str, Any]] = None,
109109
s3_client: Optional[s3] = None,
110110
**kwargs: Any,
111111
) -> Item:
112-
"""Upload Item assets to s3 bucket
112+
"""Upload Item assets to an S3 bucket
113113
Args:
114-
item (Dict): STAC Item
115-
assets (List[str], optional): List of asset keys to upload. Defaults to None.
116-
public_assets (List[str], optional): List of assets keys that should be
114+
item (Item): STAC Item
115+
assets (list[str], optional): List of asset keys to upload. Defaults to None.
116+
public_assets (list[str], optional): List of assets keys that should be
117117
public. Defaults to [].
118118
path_template (str, optional): Path string template. Defaults to
119119
'${collection}/${id}'.
120120
s3_urls (bool, optional): Return s3 URLs instead of http URLs. Defaults
121121
to False.
122-
headers (Dict, optional): Dictionary of headers to set on uploaded
122+
headers (dict, optional): Dictionary of headers to set on uploaded
123123
assets. Defaults to {}.
124124
s3_client (boto3utils.s3, optional): Use this s3 object instead of the default
125125
global one. Defaults to None.
126126
Returns:
127-
Dict: A new STAC Item with uploaded assets pointing to newly uploaded file URLs
127+
Item: A new STAC Item with uploaded assets pointing to newly uploaded file URLs
128128
"""
129129

130130
if s3_client is None:

stactask/task.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pathlib import Path
1212
from shutil import rmtree
1313
from tempfile import mkdtemp
14-
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
14+
from typing import Any, Callable, Iterable, Optional, Union
1515

1616
import fsspec
1717
from boto3utils import s3
@@ -66,7 +66,7 @@ class Task(ABC):
6666

6767
def __init__(
6868
self: "Task",
69-
payload: Dict[str, Any],
69+
payload: dict[str, Any],
7070
workdir: Optional[PathLike] = None,
7171
save_workdir: Optional[bool] = None,
7272
skip_upload: bool = False, # deprecated
@@ -105,17 +105,17 @@ def __init__(
105105
)
106106

107107
@property
108-
def process_definition(self) -> Dict[str, Any]:
108+
def process_definition(self) -> dict[str, Any]:
109109
process = self._payload.get("process", {})
110110
if isinstance(process, dict):
111111
return process
112112
else:
113113
raise ValueError(f"process is not a dict: {type(process)}")
114114

115115
@property
116-
def parameters(self) -> Dict[str, Any]:
116+
def parameters(self) -> dict[str, Any]:
117117
task_configs = self.process_definition.get("tasks", [])
118-
if isinstance(task_configs, List):
118+
if isinstance(task_configs, list):
119119
warnings.warn(
120120
"task configs is list, use a dictionary instead",
121121
DeprecationWarning,
@@ -125,13 +125,13 @@ def parameters(self) -> Dict[str, Any]:
125125
if len(task_config_list) == 0:
126126
return {}
127127
else:
128-
task_config: Dict[str, Any] = task_config_list[0]
128+
task_config: dict[str, Any] = task_config_list[0]
129129
parameters = task_config.get("parameters", {})
130130
if isinstance(parameters, dict):
131131
return parameters
132132
else:
133133
raise ValueError(f"parameters is not a dict: {type(parameters)}")
134-
elif isinstance(task_configs, Dict):
134+
elif isinstance(task_configs, dict):
135135
config = task_configs.get(self.name, {})
136136
if isinstance(config, dict):
137137
return config
@@ -143,23 +143,23 @@ def parameters(self) -> Dict[str, Any]:
143143
raise ValueError(f"unexpected value for 'tasks': {task_configs}")
144144

145145
@property
146-
def upload_options(self) -> Dict[str, Any]:
146+
def upload_options(self) -> dict[str, Any]:
147147
upload_options = self.process_definition.get("upload_options", {})
148148
if isinstance(upload_options, dict):
149149
return upload_options
150150
else:
151151
raise ValueError(f"upload_options is not a dict: {type(upload_options)}")
152152

153153
@property
154-
def collection_mapping(self) -> Dict[str, str]:
154+
def collection_mapping(self) -> dict[str, str]:
155155
collection_mapping = self.upload_options.get("collections", {})
156156
if isinstance(collection_mapping, dict):
157157
return collection_mapping
158158
else:
159159
raise ValueError(f"collections is not a dict: {type(collection_mapping)}")
160160

161161
@property
162-
def items_as_dicts(self) -> List[Dict[str, Any]]:
162+
def items_as_dicts(self) -> list[dict[str, Any]]:
163163
features = self._payload.get("features", [])
164164
if isinstance(features, list):
165165
return features
@@ -172,14 +172,14 @@ def items(self) -> ItemCollection:
172172
return ItemCollection.from_dict(items_dict, preserve_dict=True)
173173

174174
@classmethod
175-
def validate(cls, payload: Dict[str, Any]) -> bool:
175+
def validate(cls, payload: dict[str, Any]) -> bool:
176176
"""Validates the payload and returns True if valid. If invalid, raises
177177
``stactask.exceptions.FailedValidation`` or returns False."""
178178
# put validation logic on input Items and process definition here
179179
return True
180180

181181
@classmethod
182-
def add_software_version(cls, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
182+
def add_software_version(cls, items: list[dict[str, Any]]) -> list[dict[str, Any]]:
183183
warnings.warn(
184184
"add_software_version is deprecated, "
185185
"use add_software_version_to_item instead",
@@ -191,7 +191,7 @@ def add_software_version(cls, items: List[Dict[str, Any]]) -> List[Dict[str, Any
191191
return modified_items
192192

193193
@classmethod
194-
def add_software_version_to_item(cls, item: Dict[str, Any]) -> Dict[str, Any]:
194+
def add_software_version_to_item(cls, item: dict[str, Any]) -> dict[str, Any]:
195195
"""Adds software version information to a single item.
196196
197197
Uses the processing extension.
@@ -200,7 +200,7 @@ def add_software_version_to_item(cls, item: Dict[str, Any]) -> Dict[str, Any]:
200200
item: A single STAC item
201201
202202
Returns:
203-
Dict[str, Any]: The same item with processing information applied.
203+
dict[str, Any]: The same item with processing information applied.
204204
"""
205205
processing_ext = (
206206
"https://stac-extensions.github.io/processing/v1.1.0/schema.json"
@@ -249,7 +249,7 @@ def download_item_assets(
249249
250250
Args:
251251
item (pystac.Item): STAC Item for which assets need be downloaded.
252-
assets (Optional[List[str]]): List of asset keys to download.
252+
assets (Optional[list[str]]): List of asset keys to download.
253253
Defaults to all assets.
254254
path_template (Optional[str]): String to be interpolated to specify
255255
where to store downloaded files.
@@ -274,15 +274,15 @@ def download_items_assets(
274274
path_template: str = "${collection}/${id}",
275275
keep_original_filenames: bool = False,
276276
**kwargs: Any,
277-
) -> List[Item]:
277+
) -> list[Item]:
278278
"""Download provided asset keys for the given items. Assets are
279279
saved in workdir in a directory (as specified by path_template), and
280280
the items are updated with the new asset hrefs.
281281
282282
Args:
283-
items (List[pystac.Item]): List of STAC Items for which assets need
283+
items (list[pystac.Item]): List of STAC Items for which assets need
284284
be downloaded.
285-
assets (Optional[List[str]]): List of asset keys to download.
285+
assets (Optional[list[str]]): List of asset keys to download.
286286
Defaults to all assets.
287287
path_template (Optional[str]): String to be interpolated to specify
288288
where to store downloaded files.
@@ -304,7 +304,7 @@ def download_items_assets(
304304
def upload_item_assets_to_s3(
305305
self,
306306
item: Item,
307-
assets: Optional[List[str]] = None,
307+
assets: Optional[list[str]] = None,
308308
s3_client: Optional[s3] = None,
309309
) -> Item:
310310
if self._upload:
@@ -319,7 +319,7 @@ def upload_item_assets_to_s3(
319319
def _is_local_asset(self, asset: Asset) -> bool:
320320
return bool(asset.href.startswith(str(self._workdir)))
321321

322-
def _get_local_asset_keys(self, item: Item) -> List[str]:
322+
def _get_local_asset_keys(self, item: Item) -> list[str]:
323323
return [
324324
key for key, asset in item.assets.items() if self._is_local_asset(asset)
325325
]
@@ -337,7 +337,7 @@ def upload_local_item_assets_to_s3(
337337

338338
# this should be in PySTAC
339339
@staticmethod
340-
def create_item_from_item(item: Dict[str, Any]) -> Dict[str, Any]:
340+
def create_item_from_item(item: dict[str, Any]) -> dict[str, Any]:
341341
new_item = deepcopy(item)
342342
# create a derived output item
343343
links = [
@@ -356,7 +356,7 @@ def create_item_from_item(item: Dict[str, Any]) -> Dict[str, Any]:
356356
return new_item
357357

358358
@abstractmethod
359-
def process(self, **kwargs: Any) -> List[Dict[str, Any]]:
359+
def process(self, **kwargs: Any) -> list[dict[str, Any]]:
360360
"""Main task logic - virtual
361361
362362
Returns:
@@ -366,7 +366,7 @@ def process(self, **kwargs: Any) -> List[Dict[str, Any]]:
366366
# do some stuff
367367
pass
368368

369-
def post_process_item(self, item: Dict[str, Any]) -> Dict[str, Any]:
369+
def post_process_item(self, item: dict[str, Any]) -> dict[str, Any]:
370370
"""Perform post-processing operations on an item.
371371
372372
E.g. add software version information.
@@ -380,15 +380,15 @@ def post_process_item(self, item: Dict[str, Any]) -> Dict[str, Any]:
380380
item: An item produced by :py:meth:`Task.process`
381381
382382
Returns:
383-
Dict[str, Any]: The item with any additional attributes applied.
383+
dict[str, Any]: The item with any additional attributes applied.
384384
"""
385385
assert "stac_extensions" in item
386386
assert isinstance(item["stac_extensions"], list)
387387
item["stac_extensions"].sort()
388388
return item
389389

390390
@classmethod
391-
def handler(cls, payload: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]:
391+
def handler(cls, payload: dict[str, Any], **kwargs: Any) -> dict[str, Any]:
392392
task = None
393393
try:
394394
if "href" in payload or "url" in payload:
@@ -414,7 +414,7 @@ def handler(cls, payload: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]:
414414
task.cleanup_workdir()
415415

416416
@classmethod
417-
def parse_args(cls, args: List[str]) -> Dict[str, Any]:
417+
def parse_args(cls, args: list[str]) -> dict[str, Any]:
418418
dhf = argparse.ArgumentDefaultsHelpFormatter
419419
parser0 = argparse.ArgumentParser(description=cls.description)
420420
parser0.add_argument(

stactask/utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
from typing import Any, Dict, Optional
1+
from typing import Any, Optional
22

33
from jsonpath_ng.ext import parser
44

55

6-
def stac_jsonpath_match(item: Dict[str, Any], expr: str) -> bool:
6+
def stac_jsonpath_match(item: dict[str, Any], expr: str) -> bool:
77
"""Match jsonpath expression against STAC JSON.
88
Use https://jsonpath.com to experiment with JSONpath
99
and https://regex101.com to experiment with regex
1010
1111
Args:
12-
item (Dict): A STAC Item
12+
item (dict): A STAC Item represented as a dict
1313
expr (str): A valid JSONPath expression
1414
1515
Raises:
@@ -22,15 +22,15 @@ def stac_jsonpath_match(item: Dict[str, Any], expr: str) -> bool:
2222

2323

2424
def find_collection(
25-
collection_mapping: Dict[str, str], item: Dict[str, Any]
25+
collection_mapping: dict[str, str], item: dict[str, Any]
2626
) -> Optional[str]:
2727
"""Find the collection for a given STAC Item represented as a dictionary from a
2828
dictionary of collection names to JSONPath expressions.
2929
3030
Args:
31-
collection_mapping (Dict): A dictionary of collection names to JSONPath
31+
collection_mapping (dict): A dictionary of collection names to JSONPath
3232
expressions.
33-
item (Dict): A STAC Item
33+
item (dict): A STAC Item
3434
3535
Returns:
3636
Optional[str]: Returns None if no JSONPath expression matches, returns a

tests/conftest.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from typing import List
2-
31
import pytest
42

53

@@ -23,7 +21,7 @@ def pytest_configure(config: pytest.Config) -> None:
2321

2422

2523
def pytest_collection_modifyitems(
26-
config: pytest.Config, items: List[pytest.Item]
24+
config: pytest.Config, items: list[pytest.Item]
2725
) -> None:
2826
if not config.getoption("--runslow"):
2927
skip_slow = pytest.mark.skip(reason="need --runslow option to run")

tests/tasks.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, List
1+
from typing import Any
22

33
from stactask import Task
44
from stactask.exceptions import FailedValidation
@@ -8,7 +8,7 @@ class NothingTask(Task):
88
name = "nothing-task"
99
description = "this task does nothing"
1010

11-
def process(self, **kwargs: Any) -> List[Dict[str, Any]]:
11+
def process(self, **kwargs: Any) -> list[dict[str, Any]]:
1212
return self.items_as_dicts
1313

1414

@@ -17,19 +17,19 @@ class FailValidateTask(Task):
1717
description = "this task always fails validation"
1818

1919
@classmethod
20-
def validate(self, payload: Dict[str, Any]) -> bool:
20+
def validate(self, payload: dict[str, Any]) -> bool:
2121
if payload:
2222
raise FailedValidation("Extra context about what went wrong")
2323
return True
2424

25-
def process(self, **kwargs: Any) -> List[Dict[str, Any]]:
25+
def process(self, **kwargs: Any) -> list[dict[str, Any]]:
2626
return self.items_as_dicts
2727

2828

2929
class DerivedItemTask(Task):
3030
name = "derived-item-task"
3131
description = "this task creates a derived item"
3232

33-
def process(self, **kwargs: Any) -> List[Dict[str, Any]]:
33+
def process(self, **kwargs: Any) -> list[dict[str, Any]]:
3434
assert kwargs["parameter"] == "value"
3535
return [self.create_item_from_item(self.items_as_dicts[0])]

0 commit comments

Comments
 (0)