55 TYPE_CHECKING ,
66 Any ,
77 Optional ,
8- TypeVar ,
8+ Union ,
99)
1010
1111import pystac .utils
2525async def download_item (
2626 item : Item ,
2727 directory : PathLikeObject ,
28+ file_name : Optional [str ] = None ,
2829 config : Optional [Config ] = None ,
2930 queue : Optional [AnyQueue ] = None ,
3031) -> Item :
@@ -33,6 +34,8 @@ async def download_item(
3334 Args:
3435 item: The :py:class:`pystac.Item`.
3536 directory: The output directory that will hold the items and assets.
37+ file_name: The name of the item file to save. If not provided, will not
38+ be saved.
3639 config: The download configuration
3740 queue: An optional queue to use for progress reporting
3841
@@ -42,14 +45,24 @@ async def download_item(
4245 Raises:
4346 ValueError: Raised if the item doesn't have any assets.
4447 """
45- return await _download_stac_object (
46- item , directory , config = config or Config (), queue = queue
47- )
48+ async with Downloads (config or Config ()) as downloads :
49+ await downloads .add (item , Path (directory ), file_name )
50+ await downloads .download (queue )
51+
52+ self_href = item .get_self_href ()
53+ if self_href :
54+ _make_asset_hrefs_relative (item )
55+ d = item .to_dict (include_self_link = True , transform_hrefs = False )
56+ with open (self_href , "w" ) as f :
57+ json .dump (d , f )
58+
59+ return item
4860
4961
5062async def download_collection (
5163 collection : Collection ,
5264 directory : PathLikeObject ,
65+ file_name : Optional [str ] = None ,
5366 config : Optional [Config ] = None ,
5467 queue : Optional [AnyQueue ] = None ,
5568) -> Collection :
@@ -61,6 +74,8 @@ async def download_collection(
6174 Args:
6275 collection: A pystac collection
6376 directory: The destination directory
77+ file_name: The name of the collection file to save. If not provided,
78+ will not be saved.
6479 config: The download configuration
6580 queue: An optional queue to use for progress reporting
6681
@@ -70,14 +85,24 @@ async def download_collection(
7085 Raises:
7186 CantIncludeAndExclude: Raised if both include and exclude are not None.
7287 """
73- return await _download_stac_object (
74- collection , directory , config or Config (), queue = queue
75- )
88+ async with Downloads (config or Config ()) as downloads :
89+ await downloads .add (collection , Path (directory ), file_name )
90+ await downloads .download (queue )
91+
92+ self_href = collection .get_self_href ()
93+ if self_href :
94+ _make_asset_hrefs_relative (collection )
95+ d = collection .to_dict (include_self_link = True , transform_hrefs = False )
96+ with open (self_href , "w" ) as f :
97+ json .dump (d , f )
98+
99+ return collection
76100
77101
78102async def download_item_collection (
79103 item_collection : ItemCollection ,
80104 directory : PathLikeObject ,
105+ file_name : Optional [str ] = None ,
81106 config : Optional [Config ] = None ,
82107 queue : Optional [AnyQueue ] = None ,
83108) -> ItemCollection :
@@ -86,6 +111,8 @@ async def download_item_collection(
86111 Args:
87112 item_collection: The item collection to download
88113 directory: The destination directory
114+ file_name: The name of the item collection file to save. If not
115+ provided, will not be saved.
89116 config: The download configuration
90117 queue: An optional queue to use for progress reporting
91118
@@ -95,16 +122,14 @@ async def download_item_collection(
95122 Raises:
96123 CantIncludeAndExclude: Raised if both include and exclude are not None.
97124 """
98- if config is None :
99- config = Config ()
100- async with Downloads (config ) as downloads :
125+ async with Downloads (config or Config ()) as downloads :
101126 for item in item_collection .items :
102127 item .set_self_href (None )
103128 root = Path (directory ) / item .id
104- await downloads .add (item , root )
129+ await downloads .add (item , root , None )
105130 await downloads .download (queue )
106- if config . file_name :
107- dest_href = Path (directory ) / config . file_name
131+ if file_name :
132+ dest_href = Path (directory ) / file_name
108133 for item in item_collection .items :
109134 for asset in item .assets .values ():
110135 asset .href = pystac .utils .make_relative_href (
@@ -115,48 +140,9 @@ async def download_item_collection(
115140 return item_collection
116141
117142
118- _T = TypeVar ("_T" , Collection , Item )
119-
120-
121- async def _download_stac_object (
122- stac_object : _T ,
123- directory : PathLikeObject ,
124- config : Config ,
125- queue : Optional [AnyQueue ],
126- ) -> _T :
127- links = list ()
128- for link in stac_object .links :
129- absolute_href = link .get_absolute_href ()
130- if absolute_href :
131- link .target = absolute_href
132- links .append (link )
133- stac_object .links = links
134- # Will fail if the stac object doesn't have a self href and there's
135- # relative asset hrefs
136- stac_object = _make_asset_hrefs_absolute (stac_object )
137-
138- if config .file_name :
139- item_path = Path (directory ) / config .file_name
140- stac_object .set_self_href (str (item_path ))
141- else :
142- item_path = None
143- stac_object .set_self_href (item_path )
144-
145- async with Downloads (config ) as downloads :
146- await downloads .add (stac_object , Path (directory ))
147- await downloads .download (queue )
148-
149- self_href = stac_object .get_self_href ()
150- if self_href :
151- _make_asset_hrefs_relative (stac_object )
152- d = stac_object .to_dict (include_self_link = True , transform_hrefs = False )
153- with open (self_href , "w" ) as f :
154- json .dump (d , f )
155-
156- return stac_object
157-
158-
159- def _make_asset_hrefs_relative (stac_object : _T ) -> _T :
143+ def _make_asset_hrefs_relative (
144+ stac_object : Union [Item , Collection ]
145+ ) -> Union [Item , Collection ]:
160146 # Copied from
161147 # https://github.com/stac-utils/pystac/blob/381cf89fc25c15142fb5a187d905e22681de42a2/pystac/item.py#L284C5-L298C20
162148 # until a fix for https://github.com/stac-utils/pystac/issues/1199 is
@@ -170,19 +156,3 @@ def _make_asset_hrefs_relative(stac_object: _T) -> _T:
170156 )
171157 asset .href = pystac .utils .make_relative_href (asset .href , self_href )
172158 return stac_object
173-
174-
175- def _make_asset_hrefs_absolute (stac_object : _T ) -> _T :
176- # Copied from
177- # https://github.com/stac-utils/pystac/blob/381cf89fc25c15142fb5a187d905e22681de42a2/pystac/item.py#L309C3-L319C1
178- # until a fix for https://github.com/stac-utils/pystac/issues/1199 is
179- # released.
180- self_href = stac_object .get_self_href ()
181- for asset in stac_object .assets .values ():
182- if not pystac .utils .is_absolute_href (asset .href ):
183- if self_href is None :
184- raise STACError (
185- "Cannot make asset HREFs absolute if no self_href is set."
186- )
187- asset .href = pystac .utils .make_absolute_href (asset .href , self_href )
188- return stac_object
0 commit comments