Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2.0.0-rc.2 (TBD)

Added:
- The Session class can now construct clients by name with its client method
(#858).

2.0.0-rc.1 (2023-03-06)

User Interface Changes:
Expand Down
10 changes: 5 additions & 5 deletions docs/get-started/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The best way of doing this is wrapping any code that invokes a client class in a

```python
async with Session() as session:
client = OrdersClient(session)
client = session.client('orders')
result = await client.create_order(order)
# Process result
```
Expand All @@ -40,12 +40,12 @@ In V2, all `*Client` methods (for example, `DataClient().search`, `OrderClient()
```python
import asyncio
from datetime import datetime
from planet import Session, DataClient
from planet import Session
from planet import data_filter as filters

async def do_search():
async with Session() as session:
client = DataClient(session)
client = session.client('data')
date_filter = filters.date_range_filter('acquired', gte=datetime.fromisoformat("2022-11-18"), lte=datetime.fromisoformat("2022-11-21"))
cloud_filter = filters.range_filter('cloud_cover', lte=0.1)
download_filter = filters.permission_filter()
Expand Down Expand Up @@ -74,11 +74,11 @@ Is now

```python
async with Session() as session:
items = [i async for i in planet.DataClient(session).search(["PSScene"], all_filters)]
items = [i async for i in session.client('data').search(["PSScene"], all_filters)]
```

## Orders API

The Orders API capabilities in V1 were quite primitive, but those that did exist have been retained in much the same form; `ClientV1().create_order` becomes `OrderClient(session).create_order`. (As with the `DataClient`, you must also use `async` and `Session` with `OrderClient`.)
The Orders API capabilities in V1 were quite primitive, but those that did exist have been retained in much the same form; `ClientV1().create_order` becomes `OrdersClient(session).create_order`. (As with the `DataClient`, you must also use `async` and `Session` with `OrdersClient`.)

Additionally, there is now also an order builder in `planet.order_request`, similar to the preexisting search filter builder. For more details on this, refer to the [Creating an Order](../../python/sdk-guide/#creating-an-order).
14 changes: 7 additions & 7 deletions docs/python/sdk-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ from planet import OrdersClient

async def main():
async with Session() as sess:
client = OrdersClient(sess)
client = sess.client('orders')
# perform operations here

asyncio.run(main())
Expand Down Expand Up @@ -198,7 +198,7 @@ the context of a `Session` with the `OrdersClient`:
```python
async def main():
async with Session() as sess:
cl = OrdersClient(sess)
cl = sess.client('orders')
order = await cl.create_order(request)

asyncio.run(main())
Expand All @@ -222,7 +222,7 @@ from planet import reporting

async def create_wait_and_download():
async with Session() as sess:
cl = OrdersClient(sess)
cl = sess.client('orders')
with reporting.StateBar(state='creating') as bar:
# create order
order = await cl.create_order(request)
Expand Down Expand Up @@ -272,7 +272,7 @@ from planet import collect, OrdersClient, Session

async def main():
async with Session() as sess:
client = OrdersClient(sess)
client = sess.client('orders')
orders_list = collect(client.list_orders())

asyncio.run(main())
Expand All @@ -297,7 +297,7 @@ from planet import DataClient

async def main():
async with Session() as sess:
client = DataClient(sess)
client = sess.client('data')
# perform operations here

asyncio.run(main())
Expand Down Expand Up @@ -344,7 +344,7 @@ the context of a `Session` with the `DataClient`:
```python
async def main():
async with Session() as sess:
cl = DataClient(sess)
cl = sess.client('data')
items = [i async for i in cl.search(['PSScene'], sfilter)]

asyncio.run(main())
Expand All @@ -364,7 +364,7 @@ print command to report wait status. `download_asset` has reporting built in.
```python
async def download_and_validate():
async with Session() as sess:
cl = DataClient(sess)
cl = sess.client('data')

# get asset description
item_type_id = 'PSScene'
Expand Down
7 changes: 7 additions & 0 deletions planet/clients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@
from .subscriptions import SubscriptionsClient

__all__ = ['DataClient', 'OrdersClient', 'SubscriptionsClient']

# Organize client classes by their module name to allow lookup.
_client_directory = {
'data': DataClient,
'orders': OrdersClient,
'subscriptions': SubscriptionsClient
}
25 changes: 25 additions & 0 deletions planet/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import random
import time
from typing import AsyncGenerator, Optional

import httpx
from typing_extensions import Literal

from .auth import Auth, AuthType
from . import exceptions, models
Expand Down Expand Up @@ -413,6 +415,29 @@ async def stream(
finally:
await response.aclose()

def client(self,
name: Literal['data', 'orders', 'subscriptions'],
base_url: Optional[str] = None) -> object:
"""Get a client by its module name.

Parameters:
name: one of 'data', 'orders', or 'subscriptions'.

Returns:
A client instance.

Raises:
ClientError when no such client can be had.

"""
# To avoid circular dependency.
from planet.clients import _client_directory

try:
return _client_directory[name](self, base_url=base_url)
except KeyError:
raise exceptions.ClientError("No such client.")


class AuthSession(BaseSession):
"""Synchronous connection to the Planet Auth service."""
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'jsonschema',
'pyjwt>=2.1',
'tqdm>=4.56',
'typing-extensions',
]

test_requires = ['pytest', 'pytest-asyncio==0.16', 'pytest-cov', 'respx==0.19']
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/test_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Session module tests."""

import pytest

from planet import DataClient, OrdersClient, SubscriptionsClient, Session
from planet.exceptions import ClientError


@pytest.mark.parametrize("client_name,client_class",
[('data', DataClient), ('orders', OrdersClient),
('subscriptions', SubscriptionsClient)])
def test_session_get_client(client_name, client_class):
"""Get a client from a session."""
session = Session()
client = session.client(client_name)
assert isinstance(client, client_class)


def test_session_get_client_error():
"""Get an exception when no such client exists."""
session = Session()
with pytest.raises(ClientError):
_ = session.client('bogus')