Skip to content

Commit cb85dd1

Browse files
Nate SchmitzGoogle Earth Engine Authors
Nate Schmitz
authored and
Google Earth Engine Authors
committed
data: Update ee.data.create_assets to work with project-owned assets.
PiperOrigin-RevId: 740407354
1 parent d1f3203 commit cb85dd1

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

python/ee/data.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -2331,16 +2331,17 @@ def create_assets(
23312331
asset_ids: Sequence[str], asset_type: str, mk_parents: bool
23322332
) -> None:
23332333
"""Creates the specified assets if they do not exist."""
2334-
for asset_id in asset_ids:
2334+
ids = [convert_asset_id_to_asset_name(asset_id) for asset_id in asset_ids]
2335+
for asset_id in ids:
23352336
if getInfo(asset_id):
23362337
print('Asset %s already exists.' % asset_id)
23372338
continue
23382339
if mk_parents:
23392340
parts = asset_id.split('/')
23402341
# We don't need to create the namespace and the user's/project's folder.
2341-
if len(parts) > 2:
2342-
path = parts[0] + '/' + parts[1] + '/'
2343-
for part in parts[2:-1]:
2342+
if len(parts) > 3:
2343+
path = '/'.join(parts[0:3]) + '/'
2344+
for part in parts[3:-1]:
23442345
path += part
23452346
if getInfo(path) is None:
23462347
createAsset({'type': ASSET_TYPE_FOLDER_CLOUD}, path)

python/ee/tests/data_test.py

+82
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#!/usr/bin/env python3
22
"""Test for the ee.data module."""
33

4+
import json
5+
from typing import Any, Optional
46
from unittest import mock
57

8+
import googleapiclient
69
import httplib2
710
import requests
811

@@ -14,6 +17,25 @@
1417
from ee import image
1518

1619

20+
def NotFoundError() -> googleapiclient.errors.HttpError:
21+
"""Creates a mock HttpError with a 404 status code."""
22+
resp = httplib2.Response({'status': '404', 'reason': 'Not Found'})
23+
content = json.dumps({'error': {'code': 404, 'message': 'Not Found'}}).encode(
24+
'utf-8'
25+
)
26+
return googleapiclient.errors.HttpError(resp, content)
27+
28+
29+
def NewFolderAsset(
30+
name: str, quota: Optional[dict[str, int]] = None
31+
) -> dict[str, Any]:
32+
return {
33+
'type': 'FOLDER',
34+
'name': name,
35+
'quota': quota or {},
36+
}
37+
38+
1739
class DataTest(unittest.TestCase):
1840

1941
def setUp(self):
@@ -183,6 +205,66 @@ def testCreateFolder(self):
183205
asset = mock_create_asset.call_args.kwargs['body']
184206
self.assertEqual(asset, {'type': 'FOLDER'})
185207

208+
def testCreateAssets(self):
209+
cloud_api_resource = mock.MagicMock()
210+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
211+
asset_name = 'projects/some-project/assets/some-asset'
212+
cloud_api_resource.projects().assets().get().execute.side_effect = (
213+
NotFoundError()
214+
)
215+
ee.data.create_assets([asset_name], 'FOLDER', False)
216+
mock_create_asset = cloud_api_resource.projects().assets().create
217+
mock_create_asset.assert_called_once_with(
218+
parent='projects/some-project',
219+
assetId='some-asset',
220+
body={'type': 'FOLDER'},
221+
prettyPrint=False,
222+
)
223+
224+
def testCreateAssets_empty(self):
225+
cloud_api_resource = mock.MagicMock()
226+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
227+
ee.data.create_assets([], 'FOLDER', False)
228+
mock_create_asset = cloud_api_resource.projects().assets().create
229+
mock_create_asset.assert_not_called()
230+
231+
def testCreateAssets_noOpIfAssetExists(self):
232+
cloud_api_resource = mock.MagicMock()
233+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
234+
asset_name = 'projects/some-project/assets/some-asset'
235+
cloud_api_resource.projects().assets().get.execute.return_value = (
236+
NewFolderAsset(asset_name)
237+
)
238+
ee.data.create_assets([asset_name], 'FOLDER', False)
239+
mock_create_asset = cloud_api_resource.projects().assets().create
240+
mock_create_asset.assert_not_called()
241+
242+
def testCreateAssets_withParents(self):
243+
cloud_api_resource = mock.MagicMock()
244+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
245+
asset_name = 'projects/some-project/assets/foo/bar'
246+
cloud_api_resource.projects().assets().get().execute.side_effect = (
247+
NotFoundError()
248+
)
249+
ee.data.create_assets([asset_name], 'FOLDER', True)
250+
mock_create_asset = cloud_api_resource.projects().assets().create
251+
mock_create_asset.assert_has_calls([
252+
mock.call(
253+
parent='projects/some-project',
254+
assetId='foo',
255+
body={'type': 'FOLDER'},
256+
prettyPrint=False,
257+
),
258+
mock.call().execute(num_retries=5),
259+
mock.call(
260+
parent='projects/some-project',
261+
assetId='foo/bar',
262+
body={'type': 'FOLDER'},
263+
prettyPrint=False,
264+
),
265+
mock.call().execute(num_retries=5),
266+
])
267+
186268
def testStartIngestion(self):
187269
cloud_api_resource = mock.MagicMock()
188270
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):

0 commit comments

Comments
 (0)