Repository: planetlabs/planet-client-python
Pull request #930 (2023-04-17 15:55:35)

typo patch
**Related Issue(s):**

updated "and uses that client to create and order" to "and uses that client to generate an order"

**Proposed Changes:**

For inclusion in changelog (if applicable):

1. n/a

Not intended for changelog:

1. n/a

**Diff of User Interface**

Old behavior:

New behavior:

"and uses that client to generate an order"


**PR Checklist:**

- [x] This PR is as small and focused as possible
- [] If this PR includes proposed changes for inclusion in the changelog, the title of this PR summarizes those changes and is ready for inclusion in the Changelog.
- [] I have updated docstrings for function changes and docs in the 'docs' folder for user interface / behavior changes
- [x] This PR does not break any examples or I have updated them

**(Optional) @mentions for Notifications:**



Patch:
diff --git a/docs/python/sdk-guide.md b/docs/python/sdk-guide.md
index d9e58fc..522537e 100644
--- a/docs/python/sdk-guide.md
+++ b/docs/python/sdk-guide.md
@@ -217,7 +217,7 @@ asyncio.run(main())
 
 ```
 
-So given the order object created with the call to `create_request()`, [above](#create-an-order-request), the following code creates an Orders API client and uses that client to create and order.
+So given the order object created with the call to `create_request()`, [above](#create-an-order-request), the following code creates an Orders API client and uses that client to generate an order.
 
 ```python
 async def main():
diff --git a/planet/clients/data.py b/planet/clients/data.py
index 48891e4..f4337b4 100644
--- a/planet/clients/data.py
+++ b/planet/clients/data.py
@@ -408,6 +408,89 @@ class DataClient:
                                                json=request)
         return response.json()
 
+    async def list_asset_types(self) -> List[dict]:
+        """List all asset types available to the authenticated user.
+
+        Returns:
+            List of asset type details.
+
+        Raises:
+            planet.exceptions.APIError: On API error.
+        """
+        raise NotImplementedError
+
+    async def get_asset_type(self, asset_type_id: str) -> dict:
+        """Get an asset type by id.
+
+        An asset describes a product that can be derived from an item's source
+        data, and can be used for various analytic, visual or other purposes.
+        These are referred to as asset_types.
+
+        Parameters:
+            asset_type_id: Asset type identifier.
+
+        Returns:
+            Asset type details.
+
+        Raises:
+            planet.exceptions.APIError: On API error.
+        """
+        raise NotImplementedError
+
+    async def list_item_types(self) -> List[dict]:
+        """List all item types available to the authenticated user.
+
+        Returns:
+            List of item type details.
+
+        Raises:
+            planet.exceptions.APIError: On API error.
+        """
+        raise NotImplementedError
+
+    async def get_item_type(self, item_type_id: str) -> dict:
+        """Get an item type by id.
+
+        An item_type represents the class of spacecraft and/or processing level
+        of an item. All items have an associated item_type. Each item_type has
+        a set of supported asset_types which may be produced for a given item.
+
+        Parameters:
+            item_type_id: Item type identifier.
+
+        Returns:
+            Item type details.
+
+        Raises:
+            planet.exceptions.APIError: On API error.
+        """
+        raise NotImplementedError
+
+    async def get_item(
+        self,
+        item_type_id: str,
+        item_id: str,
+    ) -> dict:
+        """Get an item by id and item type id.
+
+        In the Planet API, an item is an entry in our catalog, and generally
+        represents a single logical observation (or scene) captured by a
+        satellite. Each item is defined by an item_type_id, which specifies the
+        class of spacecraft and/or processing level of the item. Assets (or
+        products, such as visual or analytic) can be derived from the item's
+        source data.
+
+        Parameters:
+            item_type_id: Item type identifier.
+
+        Returns:
+            Item details.
+
+        Raises:
+            planet.exceptions.APIError: On API error.
+        """
+        raise NotImplementedError
+
     async def list_item_assets(self, item_type_id: str, item_id: str) -> dict:
         """List all assets available for an item.
 
@@ -435,7 +518,7 @@ class DataClient:
                         item_type_id: str,
                         item_id: str,
                         asset_type_id: str) -> dict:
-        """Get an item asset description.
+        """Get an item asset.
 
         Parameters:
             item_type_id: Item type identifier.
diff --git a/planet/models.py b/planet/models.py
index e2e7761..ab38d8e 100644
--- a/planet/models.py
+++ b/planet/models.py
@@ -19,8 +19,7 @@ from pathlib import Path
 import random
 import re
 import string
-from typing import AsyncGenerator, Callable, List, Optional
-from urllib.parse import urlparse
+from typing import AsyncGenerator, Callable, List
 
 import httpx
 from tqdm.asyncio import tqdm
@@ -175,12 +174,13 @@ def _get_filename_from_headers(headers):
     return match.group(1) if match else None
 
 
-def _get_filename_from_url(url: str) -> Optional[str]:
-    """Get a filename from a url.
+def _get_filename_from_url(url):
+    """Get a filename from a URL.
 
-    Getting a name for Landsat imagery uses this function.
+    :returns: a filename (i.e. ``basename``)
+    :rtype: str or None
     """
-    path = urlparse(url).path
+    path = url.path
     name = path[path.rfind('/') + 1:]
     return name or None
 


Test patch:
diff --git a/tests/unit/test_models.py b/tests/unit/test_models.py
index 99cb11f..434c339 100644
--- a/tests/unit/test_models.py
+++ b/tests/unit/test_models.py
@@ -19,6 +19,7 @@ import os
 from pathlib import Path
 import re
 
+from httpx import URL
 import pytest
 
 from planet import models
@@ -29,7 +30,7 @@ LOGGER = logging.getLogger(__name__)
 
 def test_StreamingBody_name_filename():
     r = MagicMock(name='response')
-    r.url = 'https://planet.com/path/to/example.tif?foo=f6f1'
+    r.url = URL('https://planet.com/path/to/example.tif?foo=f6f1')
     r.headers = {
         'date': 'Thu, 14 Feb 2019 16:13:26 GMT',
         'last-modified': 'Wed, 22 Nov 2017 17:22:31 GMT',
@@ -44,7 +45,7 @@ def test_StreamingBody_name_filename():
 
 def test_StreamingBody_name_url():
     r = MagicMock(name='response')
-    r.url = 'https://planet.com/path/to/example.tif?foo=f6f1'
+    r.url = URL('https://planet.com/path/to/example.tif?foo=f6f1')
     r.headers = {
         'date': 'Thu, 14 Feb 2019 16:13:26 GMT',
         'last-modified': 'Wed, 22 Nov 2017 17:22:31 GMT',
@@ -59,7 +60,7 @@ def test_StreamingBody_name_url():
 
 def test_StreamingBody_name_content():
     r = MagicMock(name='response')
-    r.url = 'https://planet.com/path/to/noname/'
+    r.url = URL('https://planet.com/path/to/noname/')
     r.headers = {
         'date': 'Thu, 14 Feb 2019 16:13:26 GMT',
         'last-modified': 'Wed, 22 Nov 2017 17:22:31 GMT',
@@ -101,12 +102,12 @@ def test__get_filename_from_headers(headers, expected):
 @pytest.mark.parametrize(
     'url,expected',
     [
-        ('https://planet.com/', None),
-        ('https://planet.com/path/to/', None),
-        ('https://planet.com/path/to/example.tif', 'example.tif'),
-        ('https://planet.com/path/to/example.tif?foo=f6f1&bar=baz',
+        (URL('https://planet.com/'), None),
+        (URL('https://planet.com/path/to/'), None),
+        (URL('https://planet.com/path/to/example.tif'), 'example.tif'),
+        (URL('https://planet.com/path/to/example.tif?foo=f6f1&bar=baz'),
          'example.tif'),
-        ('https://planet.com/path/to/example.tif?foo=f6f1#quux',
+        (URL('https://planet.com/path/to/example.tif?foo=f6f1#quux'),
          'example.tif'),
     ])
 def test__get_filename_from_url(url, expected):