planet 2.6.dev0__tar.gz → 2.7__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.
Files changed (47) hide show
  1. {planet-2.6.dev0 → planet-2.7}/PKG-INFO +1 -1
  2. planet-2.7/planet/__version__.py +1 -0
  3. {planet-2.6.dev0 → planet-2.7}/planet/cli/data.py +22 -6
  4. {planet-2.6.dev0 → planet-2.7}/planet/cli/subscriptions.py +6 -2
  5. {planet-2.6.dev0 → planet-2.7}/planet/cli/types.py +14 -0
  6. planet-2.7/planet/cli/validators.py +27 -0
  7. {planet-2.6.dev0 → planet-2.7}/planet/clients/data.py +17 -1
  8. {planet-2.6.dev0 → planet-2.7}/planet/data_filter.py +4 -3
  9. {planet-2.6.dev0 → planet-2.7}/planet/exceptions.py +4 -0
  10. {planet-2.6.dev0 → planet-2.7}/planet/geojson.py +73 -19
  11. {planet-2.6.dev0 → planet-2.7}/planet/order_request.py +2 -2
  12. {planet-2.6.dev0 → planet-2.7}/planet/subscription_request.py +12 -10
  13. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/PKG-INFO +1 -1
  14. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/SOURCES.txt +1 -0
  15. planet-2.6.dev0/planet/__version__.py +0 -1
  16. {planet-2.6.dev0 → planet-2.7}/LICENSE +0 -0
  17. {planet-2.6.dev0 → planet-2.7}/README.md +0 -0
  18. {planet-2.6.dev0 → planet-2.7}/planet/__init__.py +0 -0
  19. {planet-2.6.dev0 → planet-2.7}/planet/auth.py +0 -0
  20. {planet-2.6.dev0 → planet-2.7}/planet/cli/__init__.py +0 -0
  21. {planet-2.6.dev0 → planet-2.7}/planet/cli/auth.py +0 -0
  22. {planet-2.6.dev0 → planet-2.7}/planet/cli/cli.py +0 -0
  23. {planet-2.6.dev0 → planet-2.7}/planet/cli/cmds.py +0 -0
  24. {planet-2.6.dev0 → planet-2.7}/planet/cli/collect.py +0 -0
  25. {planet-2.6.dev0 → planet-2.7}/planet/cli/io.py +0 -0
  26. {planet-2.6.dev0 → planet-2.7}/planet/cli/options.py +0 -0
  27. {planet-2.6.dev0 → planet-2.7}/planet/cli/orders.py +0 -0
  28. {planet-2.6.dev0 → planet-2.7}/planet/cli/session.py +0 -0
  29. {planet-2.6.dev0 → planet-2.7}/planet/clients/__init__.py +0 -0
  30. {planet-2.6.dev0 → planet-2.7}/planet/clients/orders.py +0 -0
  31. {planet-2.6.dev0 → planet-2.7}/planet/clients/subscriptions.py +0 -0
  32. {planet-2.6.dev0 → planet-2.7}/planet/constants.py +0 -0
  33. {planet-2.6.dev0 → planet-2.7}/planet/data/Feature.json +0 -0
  34. {planet-2.6.dev0 → planet-2.7}/planet/data/README.md +0 -0
  35. {planet-2.6.dev0 → planet-2.7}/planet/data/orders_product_bundle_2023-02-24.json +0 -0
  36. {planet-2.6.dev0 → planet-2.7}/planet/http.py +0 -0
  37. {planet-2.6.dev0 → planet-2.7}/planet/io.py +0 -0
  38. {planet-2.6.dev0 → planet-2.7}/planet/models.py +0 -0
  39. {planet-2.6.dev0 → planet-2.7}/planet/reporting.py +0 -0
  40. {planet-2.6.dev0 → planet-2.7}/planet/specs.py +0 -0
  41. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/dependency_links.txt +0 -0
  42. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/entry_points.txt +0 -0
  43. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/not-zip-safe +0 -0
  44. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/requires.txt +0 -0
  45. {planet-2.6.dev0 → planet-2.7}/planet.egg-info/top_level.txt +0 -0
  46. {planet-2.6.dev0 → planet-2.7}/setup.cfg +0 -0
  47. {planet-2.6.dev0 → planet-2.7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: planet
3
- Version: 2.6.dev0
3
+ Version: 2.7
4
4
  Summary: Planet SDK for Python
5
5
  Home-page: https://github.com/planetlabs/planet-client-python
6
6
  Author: Jennifer Reiber Kyle
@@ -0,0 +1 @@
1
+ __version__ = '2.7'
@@ -15,7 +15,6 @@
15
15
  from typing import List, Optional
16
16
  from contextlib import asynccontextmanager
17
17
  from pathlib import Path
18
-
19
18
  import click
20
19
 
21
20
  from planet.reporting import AssetStatusBar
@@ -37,6 +36,7 @@ from .cmds import coro, translate_exceptions
37
36
  from .io import echo_json
38
37
  from .options import limit, pretty
39
38
  from .session import CliSession
39
+ from .validators import check_geom
40
40
 
41
41
  valid_item_string = "Valid entries for ITEM_TYPES: " + "|".join(
42
42
  get_data_item_types())
@@ -281,6 +281,7 @@ def filter(ctx,
281
281
  @click.argument("item_types",
282
282
  type=types.CommaSeparatedString(),
283
283
  callback=check_item_types)
284
+ @click.option("--geom", type=types.Geometry(), callback=check_geom)
284
285
  @click.option('--filter',
285
286
  type=types.JSON(),
286
287
  help="""Apply specified filter to search. Can be a json string,
@@ -293,7 +294,7 @@ def filter(ctx,
293
294
  show_default=True,
294
295
  help='Field and direction to order results by.')
295
296
  @pretty
296
- async def search(ctx, item_types, filter, limit, name, sort, pretty):
297
+ async def search(ctx, item_types, geom, filter, limit, name, sort, pretty):
297
298
  """Execute a structured item search.
298
299
 
299
300
  This function outputs a series of GeoJSON descriptions, one for each of the
@@ -311,6 +312,7 @@ async def search(ctx, item_types, filter, limit, name, sort, pretty):
311
312
  async with data_client(ctx) as cl:
312
313
 
313
314
  async for item in cl.search(item_types,
315
+ geometry=geom,
314
316
  search_filter=filter,
315
317
  name=name,
316
318
  sort=sort,
@@ -325,6 +327,7 @@ async def search(ctx, item_types, filter, limit, name, sort, pretty):
325
327
  @click.argument("item_types",
326
328
  type=types.CommaSeparatedString(),
327
329
  callback=check_item_types)
330
+ @click.option("--geom", type=types.Geometry(), callback=check_geom)
328
331
  @click.option(
329
332
  '--filter',
330
333
  type=types.JSON(),
@@ -339,7 +342,13 @@ async def search(ctx, item_types, filter, limit, name, sort, pretty):
339
342
  is_flag=True,
340
343
  help='Send a daily email when new results are added.')
341
344
  @pretty
342
- async def search_create(ctx, item_types, filter, name, daily_email, pretty):
345
+ async def search_create(ctx,
346
+ item_types,
347
+ geom,
348
+ filter,
349
+ name,
350
+ daily_email,
351
+ pretty):
343
352
  """Create a new saved structured item search.
344
353
 
345
354
  This function outputs a full JSON description of the created search,
@@ -349,6 +358,7 @@ async def search_create(ctx, item_types, filter, name, daily_email, pretty):
349
358
  """
350
359
  async with data_client(ctx) as cl:
351
360
  items = await cl.create_search(item_types=item_types,
361
+ geometry=geom,
352
362
  search_filter=filter,
353
363
  name=name,
354
364
  enable_email=daily_email)
@@ -485,6 +495,10 @@ async def search_delete(ctx, search_id):
485
495
  type=str,
486
496
  required=True,
487
497
  help='Name of the saved search.')
498
+ @click.option("--geom",
499
+ type=types.Geometry(),
500
+ callback=check_geom,
501
+ default=None)
488
502
  @click.option('--daily-email',
489
503
  is_flag=True,
490
504
  help='Send a daily email when new results are added.')
@@ -493,6 +507,7 @@ async def search_update(ctx,
493
507
  search_id,
494
508
  item_types,
495
509
  filter,
510
+ geom,
496
511
  name,
497
512
  daily_email,
498
513
  pretty):
@@ -504,9 +519,10 @@ async def search_update(ctx,
504
519
  async with data_client(ctx) as cl:
505
520
  items = await cl.update_search(search_id,
506
521
  item_types,
507
- filter,
508
- name,
509
- daily_email)
522
+ search_filter=filter,
523
+ name=name,
524
+ geometry=geom,
525
+ enable_email=daily_email)
510
526
  echo_json(items, pretty)
511
527
 
512
528
 
@@ -13,6 +13,7 @@ from planet.clients.subscriptions import SubscriptionsClient
13
13
  from .. import subscription_request
14
14
  from ..subscription_request import sentinel_hub
15
15
  from ..specs import get_item_types, validate_item_type, SpecificationException
16
+ from .validators import check_geom
16
17
 
17
18
  ALL_ITEM_TYPES = get_item_types()
18
19
  valid_item_string = "Valid entries for ITEM_TYPES: " + "|".join(ALL_ITEM_TYPES)
@@ -346,7 +347,8 @@ def request(name,
346
347
  @click.option(
347
348
  '--geometry',
348
349
  required=True,
349
- type=types.JSON(),
350
+ type=types.Geometry(),
351
+ callback=check_geom,
350
352
  help="""Geometry of the area of interest of the subscription that will be
351
353
  used to determine matches. Can be a string, filename, or - for stdin.""")
352
354
  @click.option('--start-time',
@@ -406,6 +408,7 @@ def request_catalog(item_types,
406
408
  required=True,
407
409
  help='Planetary variable type.',
408
410
  type=click.Choice([
411
+ "analysis_ready_ps",
409
412
  "biomass_proxy",
410
413
  "land_surface_temperature",
411
414
  "soil_water_content",
@@ -418,7 +421,8 @@ def request_catalog(item_types,
418
421
  @click.option(
419
422
  '--geometry',
420
423
  required=True,
421
- type=types.JSON(),
424
+ type=types.Geometry(),
425
+ callback=check_geom,
422
426
  help="""Geometry of the area of interest of the subscription that will be
423
427
  used to determine matches. Can be a string, filename, or - for stdin.""")
424
428
  @click.option('--start-time',
@@ -93,6 +93,20 @@ class JSON(click.ParamType):
93
93
  return convdict
94
94
 
95
95
 
96
+ class Geometry(click.ParamType):
97
+ name = 'geom'
98
+
99
+ def __init__(self):
100
+ self.types = [JSON(), CommaSeparatedString()]
101
+
102
+ def convert(self, value, param, ctx):
103
+ for type in self.types:
104
+ try:
105
+ return type.convert(value, param, ctx)
106
+ except click.BadParameter:
107
+ continue
108
+
109
+
96
110
  class Field(click.ParamType):
97
111
  """Clarify that this entry is for a field"""
98
112
  name = 'field'
@@ -0,0 +1,27 @@
1
+ # Copyright 2022 Planet Labs, PBC.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ # use this file except in compliance with the License. You may obtain a copy of
5
+ # the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations under
13
+ # the License.
14
+ """CLI Parameter validation"""
15
+ from typing import Optional
16
+ from planet import geojson
17
+
18
+
19
+ def check_geom(ctx, param, geometry) -> Optional[dict]:
20
+ """Validates geometry as GeoJSON or feature ref(s)."""
21
+ if isinstance(geometry, dict):
22
+ return geojson.as_geom_or_ref(geometry)
23
+ geoms = {}
24
+ if geometry:
25
+ for geom in geometry:
26
+ geoms.update(geojson.as_geom_or_ref(geom))
27
+ return geoms if geoms else None
@@ -26,6 +26,7 @@ from ..constants import PLANET_BASE_URL
26
26
  from ..http import Session
27
27
  from ..models import Paged, StreamingBody
28
28
  from ..specs import validate_data_item_type
29
+ from ..geojson import as_geom_or_ref
29
30
 
30
31
  BASE_URL = f'{PLANET_BASE_URL}/data/v1/'
31
32
  SEARCHES_PATH = '/searches'
@@ -112,6 +113,7 @@ class DataClient:
112
113
 
113
114
  async def search(self,
114
115
  item_types: List[str],
116
+ geometry: Optional[dict] = None,
115
117
  search_filter: Optional[dict] = None,
116
118
  name: Optional[str] = None,
117
119
  sort: Optional[str] = None,
@@ -134,6 +136,8 @@ class DataClient:
134
136
  sort: Field and direction to order results by. Valid options are
135
137
  given in SEARCH_SORT.
136
138
  name: The name of the saved search.
139
+ geometry: GeoJSON, a feature reference or a list of feature
140
+ references
137
141
  limit: Maximum number of results to return. When set to 0, no
138
142
  maximum is applied.
139
143
 
@@ -149,6 +153,9 @@ class DataClient:
149
153
 
150
154
  item_types = [validate_data_item_type(item) for item in item_types]
151
155
  request_json = {'filter': search_filter, 'item_types': item_types}
156
+
157
+ if geometry:
158
+ request_json['geometry'] = as_geom_or_ref(geometry)
152
159
  if name:
153
160
  request_json['name'] = name
154
161
 
@@ -159,7 +166,6 @@ class DataClient:
159
166
  raise exceptions.ClientError(
160
167
  f'{sort} must be one of {SEARCH_SORT}')
161
168
  params['_sort'] = sort
162
-
163
169
  response = await self._session.request(method='POST',
164
170
  url=url,
165
171
  json=request_json,
@@ -171,6 +177,7 @@ class DataClient:
171
177
  item_types: List[str],
172
178
  search_filter: dict,
173
179
  name: str,
180
+ geometry: Optional[dict] = None,
174
181
  enable_email: bool = False) -> dict:
175
182
  """Create a new saved structured item search.
176
183
 
@@ -192,6 +199,7 @@ class DataClient:
192
199
 
193
200
  Parameters:
194
201
  item_types: The item types to include in the search.
202
+ geometry: A feature reference or a GeoJSON
195
203
  search_filter: Structured search criteria.
196
204
  name: The name of the saved search.
197
205
  enable_email: Send a daily email when new results are added.
@@ -205,12 +213,15 @@ class DataClient:
205
213
  url = self._searches_url()
206
214
 
207
215
  item_types = [validate_data_item_type(item) for item in item_types]
216
+
208
217
  request = {
209
218
  'name': name,
210
219
  'filter': search_filter,
211
220
  'item_types': item_types,
212
221
  '__daily_email_enabled': enable_email
213
222
  }
223
+ if geometry:
224
+ request['geometry'] = as_geom_or_ref(geometry)
214
225
 
215
226
  response = await self._session.request(method='POST',
216
227
  url=url,
@@ -222,12 +233,14 @@ class DataClient:
222
233
  item_types: List[str],
223
234
  search_filter: dict,
224
235
  name: str,
236
+ geometry: Optional[dict] = None,
225
237
  enable_email: bool = False) -> dict:
226
238
  """Update an existing saved search.
227
239
 
228
240
  Parameters:
229
241
  search_id: Saved search identifier.
230
242
  item_types: The item types to include in the search.
243
+ geometry: A feature reference or a GeoJSON
231
244
  search_filter: Structured search criteria.
232
245
  name: The name of the saved search.
233
246
  enable_email: Send a daily email when new results are added.
@@ -238,12 +251,15 @@ class DataClient:
238
251
  url = f'{self._searches_url()}/{search_id}'
239
252
 
240
253
  item_types = [validate_data_item_type(item) for item in item_types]
254
+
241
255
  request = {
242
256
  'name': name,
243
257
  'filter': search_filter,
244
258
  'item_types': item_types,
245
259
  '__daily_email_enabled': enable_email
246
260
  }
261
+ if geometry:
262
+ request['geometry'] = geometry
247
263
 
248
264
  response = await self._session.request(method='PUT',
249
265
  url=url,
@@ -238,9 +238,10 @@ def geometry_filter(geom: dict) -> dict:
238
238
  geom: GeoJSON describing the filter geometry, feature, or feature
239
239
  collection.
240
240
  """
241
- return _field_filter('GeometryFilter',
242
- field_name='geometry',
243
- config=geojson.as_geom(geom))
241
+ geom_filter = _field_filter('GeometryFilter',
242
+ field_name='geometry',
243
+ config=geojson.validate_geom_as_geojson(geom))
244
+ return geom_filter
244
245
 
245
246
 
246
247
  def number_in_filter(field_name: str, values: List[float]) -> dict:
@@ -90,3 +90,7 @@ class PagingError(ClientError):
90
90
 
91
91
  class GeoJSONError(ClientError):
92
92
  """Errors that occur due to invalid GeoJSON"""
93
+
94
+
95
+ class FeatureError(ClientError):
96
+ """Errors that occur due to incorrectly formatted feature reference"""
@@ -12,23 +12,22 @@
12
12
  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
13
  # License for the specific language governing permissions and limitations under
14
14
  # the License.
15
- """Functionality for interacting with GeoJSON."""
15
+ """Functionality for interacting with GeoJSON and planet references."""
16
16
  import json
17
17
  import logging
18
18
  import typing
19
19
 
20
20
  import geojson as gj
21
21
  from jsonschema import Draft7Validator
22
-
23
22
  from .constants import DATA_DIR
24
- from .exceptions import GeoJSONError
23
+ from .exceptions import GeoJSONError, FeatureError
25
24
 
26
- GEOJSON_TYPES = ['Feature']
25
+ GEOJSON_TYPES = ["Feature"]
27
26
 
28
27
  LOGGER = logging.getLogger(__name__)
29
28
 
30
29
 
31
- def as_geom(data: dict) -> dict:
30
+ def as_geom_or_ref(data) -> dict:
32
31
  """Extract the geometry from GeoJSON and validate.
33
32
 
34
33
  Parameters:
@@ -42,13 +41,65 @@ def as_geom(data: dict) -> dict:
42
41
  or FeatureCollection or if more than one Feature is in a
43
42
  FeatureCollection.
44
43
  """
45
- geom = geom_from_geojson(data)
46
- validate_geom(geom)
47
- return geom
44
+ if isinstance(data, str):
45
+ return as_ref(data)
46
+ geom_type = data['type']
47
+ if geom_type == 'ref':
48
+ return as_ref(data)
49
+ else:
50
+ geom = geom_from_geojson(data)
51
+ validate_geom_as_geojson(geom)
52
+ return geom
53
+
54
+
55
+ def validate_ref(uri) -> bool:
56
+ if uri is None:
57
+ raise FeatureError("Expected str, not None")
58
+ parts = uri.split("/", 4)
59
+ if parts[0] != "pl:features":
60
+ raise FeatureError("Expected scheme pl:features")
61
+ path = parts[1:]
62
+ if len(path) < 2:
63
+ raise FeatureError("Expceted dataset/collection path")
64
+ return True
65
+
66
+
67
+ def convert_ref_to_dict(data: str) -> dict:
68
+ """ Ensure geom reference is in the expected format
69
+ Then convert it into a geometry block
70
+
71
+ Parameters:
72
+ data: str, a feature reference
73
+ Returns:
74
+ GeoJSON geometry reference
75
+ """
76
+ if validate_ref(data):
77
+ geom = {
78
+ "type": "ref",
79
+ "content": data,
80
+ }
81
+ return geom
82
+ return dict()
83
+
84
+
85
+ def as_ref(data) -> dict:
86
+ if isinstance(data, str):
87
+ data = convert_ref_to_dict(data)
88
+ if isinstance(data, dict):
89
+ geom_type = data['type']
90
+ if geom_type.lower() != 'ref':
91
+ raise FeatureError(
92
+ f'Invalid geometry reference: {geom_type} is not a reference (the type should be "ref").'
93
+ )
94
+ if "content" not in data:
95
+ raise FeatureError(
96
+ 'Invalid geometry reference: Missing content block that contains the reference.'
97
+ )
98
+ return data
48
99
 
49
100
 
50
101
  def as_polygon(data: dict) -> dict:
51
- geom = as_geom(data)
102
+ geom = as_geom_or_ref(data)
52
103
  geom_type = geom['type']
53
104
  if geom_type.lower() != 'polygon':
54
105
  raise GeoJSONError(
@@ -75,7 +126,7 @@ def geom_from_geojson(data: dict) -> dict:
75
126
  else:
76
127
  try:
77
128
  # feature
78
- ret = as_geom(data['geometry'])
129
+ ret = as_geom_or_ref(data['geometry'])
79
130
  except KeyError:
80
131
  try:
81
132
  # FeatureCollection
@@ -88,11 +139,11 @@ def geom_from_geojson(data: dict) -> dict:
88
139
  'FeatureCollection has multiple features. Only one feature'
89
140
  ' can be used to get geometry.')
90
141
 
91
- ret = as_geom(features[0])
142
+ ret = as_geom_or_ref(features[0])
92
143
  return ret
93
144
 
94
145
 
95
- def validate_geom(data: dict):
146
+ def validate_geom_as_geojson(data: dict):
96
147
  """Validate GeoJSON geometry.
97
148
 
98
149
  Parameters:
@@ -101,23 +152,26 @@ def validate_geom(data: dict):
101
152
  Raises:
102
153
  planet.exceptions.GeoJSONError: If data is not a valid GeoJSON
103
154
  geometry.
155
+ Returns:
156
+ GeoJSON
104
157
  """
158
+ data = geom_from_geojson(data)
105
159
  if 'type' not in data:
106
- raise GeoJSONError("Missing 'type' key.")
160
+ raise GeoJSONError('Missing "type" key.')
107
161
  if 'coordinates' not in data:
108
- raise GeoJSONError("Missing 'coordinates' key.")
162
+ raise GeoJSONError('Missing "coordinates" key.')
109
163
 
110
164
  try:
111
- cls = getattr(gj, data["type"])
112
- obj = cls(data["coordinates"])
165
+ cls = getattr(gj, data['type'])
166
+ obj = cls(data['coordinates'])
113
167
  if not obj.is_valid:
114
168
  raise GeoJSONError(obj.errors())
115
169
  except AttributeError as err:
116
- raise GeoJSONError("Not a GeoJSON geometry type") from err
170
+ raise GeoJSONError('Not a GeoJSON geometry type') from err
117
171
  except ValueError as err:
118
- raise GeoJSONError("Not a GeoJSON coordinate value") from err
172
+ raise GeoJSONError('Not a GeoJSON coordinate value') from err
119
173
 
120
- return
174
+ return data
121
175
 
122
176
 
123
177
  def as_featurecollection(features: typing.List[dict]) -> dict:
@@ -356,9 +356,9 @@ def clip_tool(aoi: dict) -> dict:
356
356
  planet.exceptions.ClientError: If GeoJSON is not a valid polygon or
357
357
  multipolygon.
358
358
  """
359
- valid_types = ['Polygon', 'MultiPolygon']
359
+ valid_types = ['Polygon', 'MultiPolygon', 'ref']
360
360
 
361
- geom = geojson.as_geom(aoi)
361
+ geom = geojson.as_geom_or_ref(aoi)
362
362
  if geom['type'].lower() not in [v.lower() for v in valid_types]:
363
363
  raise ClientError(
364
364
  f'Invalid geometry type: {geom["type"]} is not in {valid_types}.')
@@ -167,7 +167,7 @@ def build_request(name: str,
167
167
  def catalog_source(
168
168
  item_types: List[str],
169
169
  asset_types: List[str],
170
- geometry: Mapping,
170
+ geometry: dict,
171
171
  start_time: datetime,
172
172
  filter: Optional[Mapping] = None,
173
173
  end_time: Optional[datetime] = None,
@@ -250,7 +250,7 @@ def catalog_source(
250
250
  parameters = {
251
251
  "item_types": item_types,
252
252
  "asset_types": asset_types,
253
- "geometry": geojson.as_geom(dict(geometry)),
253
+ "geometry": geojson.as_geom_or_ref(geometry),
254
254
  }
255
255
 
256
256
  try:
@@ -280,14 +280,15 @@ def catalog_source(
280
280
 
281
281
 
282
282
  def planetary_variable_source(
283
- var_type: Literal["biomass_proxy",
283
+ var_type: Literal["analysis_ready_ps",
284
+ "biomass_proxy",
284
285
  "land_surface_temperature",
285
286
  "soil_water_content",
286
287
  "vegetation_optical_depth",
287
288
  "forest_carbon_diligence_30m",
288
289
  "field_boundaries_sentinel_2_p1m"],
289
290
  var_id: str,
290
- geometry: Mapping,
291
+ geometry: dict,
291
292
  start_time: datetime,
292
293
  end_time: Optional[datetime] = None,
293
294
  ) -> dict:
@@ -304,9 +305,10 @@ def planetary_variable_source(
304
305
  Note: this function does not validate variable types and ids.
305
306
 
306
307
  Parameters:
307
- var_type: one of "biomass_proxy", "land_surface_temperature",
308
- "soil_water_content", "vegetation_optical_depth",
309
- "forest_carbon_diligence_30m, or field_boundaries_sentinel_2_p1m".
308
+ var_type: one of "analysis_ready_ps", "biomass_proxy",
309
+ "land_surface_temperature", "soil_water_content",
310
+ "vegetation_optical_depth", "forest_carbon_diligence_30m,
311
+ or field_boundaries_sentinel_2_p1m".
310
312
  var_id: a value such as "SWC-AMSR2-C_V1.0_100" for soil water
311
313
  content derived from AMSR2 C band.
312
314
  geometry: The area of interest of the subscription that will be
@@ -355,7 +357,7 @@ def planetary_variable_source(
355
357
 
356
358
  parameters = {
357
359
  "id": var_id,
358
- "geometry": geojson.as_geom(dict(geometry)),
360
+ "geometry": geojson.as_geom_or_ref(geometry),
359
361
  }
360
362
 
361
363
  try:
@@ -596,9 +598,9 @@ def clip_tool(aoi: Mapping) -> dict:
596
598
  planet.exceptions.ClientError: If aoi is not a valid polygon or
597
599
  multipolygon.
598
600
  """
599
- valid_types = ['Polygon', 'MultiPolygon']
601
+ valid_types = ['Polygon', 'MultiPolygon', 'ref']
600
602
 
601
- geom = geojson.as_geom(dict(aoi))
603
+ geom = geojson.as_geom_or_ref(dict(aoi))
602
604
  if geom['type'].lower() not in [v.lower() for v in valid_types]:
603
605
  raise ClientError(
604
606
  f'Invalid geometry type: {geom["type"]} is not in {valid_types}.')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: planet
3
- Version: 2.6.dev0
3
+ Version: 2.7
4
4
  Summary: Planet SDK for Python
5
5
  Home-page: https://github.com/planetlabs/planet-client-python
6
6
  Author: Jennifer Reiber Kyle
@@ -35,6 +35,7 @@ planet/cli/orders.py
35
35
  planet/cli/session.py
36
36
  planet/cli/subscriptions.py
37
37
  planet/cli/types.py
38
+ planet/cli/validators.py
38
39
  planet/clients/__init__.py
39
40
  planet/clients/data.py
40
41
  planet/clients/orders.py
@@ -1 +0,0 @@
1
- __version__ = '2.6dev'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes