Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
32 changes: 32 additions & 0 deletions docs/cli/cli-destinations.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,19 @@ The `list` command supports filtering on a variety of fields. You can discover a
requesting user, false to exclude them.
* `--can-write`: Set to true to include only destinations the user can
modify, false to exclude them.
* `--is-default`: Set to true to include only the default destination,
false to exclude it.

For example, issue the following command to list destinations that are not archived and you as the user have permission to modify:
```sh
planet destinations list --archived false --can-write true
```

To list only the default destination (if one is set):
```sh
planet destinations list --is-default true
```

### Modify Destinations
The CLI conveniently moves all modify actions to first class commands on the destination. The supported actions are archive, unarchive, rename, and update credentials. To discover all update actions run `planet destinations --help`.

Expand All @@ -47,6 +54,31 @@ Credential updating might be done if credentials expire or need to be rotated. F
planet destinations update s3 my-destination-id --access-key-id NEW_ACCESS_KEY --secret-access-key NEW_SECRET_KEY
```

### Manage Default Destinations
Default destinations are globally available to all members of an organization. An organization can have zero or one default destination at any time. Managing default destinations (setting, unsetting) is restricted to organization administrators and destination owners.

#### Set a Default Destination
To set a destination as the default for your organization:
```sh
planet destinations default set my-destination-id
```

#### Get the Current Default Destination
To retrieve the current default destination (if one is set):
```sh
planet destinations default get
```

If no default destination is set, this command will return an error indicating that no default destination is configured.

#### Unset the Default Destination
To remove the current default destination:
```sh
planet destinations default unset
```

This command returns no content on success (HTTP 204). Only organization administrators and destination owners can unset the default destination.

## Using destinations in Subscriptions API
After creating a destination, it can be used as the delivery location for subscriptions. Use the destination reference in the delivery block instead of credentials.

Expand Down
110 changes: 106 additions & 4 deletions planet/cli/destinations.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ async def _patch_destination(ctx, destination_id, data, pretty):
raise ClickException(f"Failed to patch destination: {e}")


async def _list_destinations(ctx, archived, is_owner, can_write, pretty):
async def _list_destinations(ctx,
archived,
is_owner,
can_write,
is_default,
pretty):
async with destinations_client(ctx) as cl:
try:
response = await cl.list_destinations(archived,
is_owner,
can_write)
can_write,
is_default)
echo_json(response, pretty)
except Exception as e:
raise ClickException(f"Failed to list destinations: {e}")
Expand All @@ -65,6 +71,33 @@ async def _create_destination(ctx, data, pretty):
raise ClickException(f"Failed to create destination: {e}")


async def _set_default_destination(ctx, destination_id, pretty):
async with destinations_client(ctx) as cl:
try:
response = await cl.set_default_destination(destination_id)
echo_json(response, pretty)
except Exception as e:
raise ClickException(f"Failed to set default destination: {e}")


async def _unset_default_destination(ctx, pretty):
async with destinations_client(ctx) as cl:
try:
response = await cl.unset_default_destination()
echo_json(response, pretty)
except Exception as e:
raise ClickException(f"Failed to unset default destination: {e}")


async def _get_default_destination(ctx, pretty):
async with destinations_client(ctx) as cl:
try:
response = await cl.get_default_destination()
echo_json(response, pretty)
except Exception as e:
raise ClickException(f"Failed to get default destination: {e}")


@command(destinations, name="list")
@click.option('--archived',
type=bool,
Expand All @@ -82,7 +115,17 @@ async def _create_destination(ctx, data, pretty):
default=None,
help="""Set to true to include only destinations the user can modify,
false to exclude them.""")
async def list_destinations(ctx, archived, is_owner, can_write, pretty):
@click.option('--is-default',
type=bool,
default=None,
help="""Set to true to include only the default destination,
false to exclude it.""")
async def list_destinations(ctx,
archived,
is_owner,
can_write,
is_default,
pretty):
"""
List destinations with optional filters

Expand All @@ -93,7 +136,12 @@ async def list_destinations(ctx, archived, is_owner, can_write, pretty):

planet destinations list --archived false --is-owner true --can-write true
"""
await _list_destinations(ctx, archived, is_owner, can_write, pretty)
await _list_destinations(ctx,
archived,
is_owner,
can_write,
is_default,
pretty)


@command(destinations, name="get")
Expand Down Expand Up @@ -590,3 +638,57 @@ async def update_s3_compatible(ctx,
data["parameters"]["use_path_style"] = True

await _patch_destination(ctx, destination_id, data, pretty)


@destinations.group()
def default():
"""Commands for interacting with default destinations."""
pass


@command(default, name="set")
@click.argument("destination_id")
async def set_default_destination(ctx, destination_id, pretty):
"""
Set a default destination.

This command sets a specified destination as the default for the organization. Default destinations
are globally available to all members of an organization. An organization can have zero or one default
destination at any time. Ability to set a default destination is restricted to organization
administrators and destination owners.

Example:

planet destinations default set my-destination-id
"""
await _set_default_destination(ctx, destination_id, pretty)


@command(default, name="unset")
async def unset_default_destination(ctx, pretty):
"""
Unset the current default destination.

This command unsets the current default destination. Ability to unset a default destination is restricted
to organization administrators and destination owners. Returns None (HTTP 204, No Content) on success.

Example:

planet destinations default unset
"""
await _unset_default_destination(ctx, pretty)


@command(default, name="get")
async def get_default_destination(ctx, pretty):
"""
Get the current default destination.

This command gets the current default destination for the organization, if one is set. The default
destination is globally available to all members of an organization.

Example:

planet destinations default get
"""
await _get_default_destination(ctx, pretty)
80 changes: 79 additions & 1 deletion planet/clients/destinations.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

T = TypeVar("T")

DEFAULT_DESTINATION_REF = "pl:destinations/default"


class DestinationsClient(_BaseClient):
"""Asynchronous Destinations API client.
Expand Down Expand Up @@ -58,14 +60,16 @@ def __init__(self,
async def list_destinations(self,
archived: Optional[bool] = None,
is_owner: Optional[bool] = None,
can_write: Optional[bool] = None) -> Dict:
can_write: Optional[bool] = None,
is_default: Optional[bool] = None) -> Dict:
"""
List all destinations. By default, all non-archived destinations in the requesting user's org are returned.

Args:
archived (bool): If True, include archived destinations.
is_owner (bool): If True, include only destinations owned by the requesting user.
can_write (bool): If True, include only destinations the requesting user can modify.
is_default (bool): If True, include only the default destination.

Returns:
dict: A dictionary containing the list of destinations inside the 'destinations' key.
Expand All @@ -81,6 +85,8 @@ async def list_destinations(self,
params["is_owner"] = is_owner
if can_write is not None:
params["can_write"] = can_write
if is_default is not None:
params["is_default"] = is_default

try:
response = await self._session.request(method='GET',
Expand Down Expand Up @@ -174,3 +180,75 @@ async def create_destination(self, request: Dict[str, Any]) -> Dict:
else:
dest = response.json()
return dest

async def set_default_destination(self, destination_id: str) -> Dict:
"""
Set an existing destination as the default destination. Default destinations are globally available
to all members of an organization. An organization can have zero or one default destination at any time.
Ability to set a default destination is restricted to organization administrators and destination owners.

Args:
destination_id (str): The ID of the destination to set as default.

Returns:
dict: A dictionary containing the default destination details.

Raises:
APIError: If the API returns an error response.
ClientError: If there is an issue with the client request.
"""
url = f'{self._base_url}/default'
request = {"destination_id": destination_id}
try:
response = await self._session.request(method='PUT',
url=url,
json=request)
except APIError:
raise
except ClientError: # pragma: no cover
raise
else:
return response.json()

async def unset_default_destination(self) -> None:
"""
Unset the current default destination. Ability to unset a default destination is restricted to
organization administrators and destination owners. Returns None (HTTP 204, No Content) on success.

Returns:
None

Raises:
APIError: If the API returns an error response.
ClientError: If there is an issue with the client request.
"""
url = f'{self._base_url}/default'
try:
await self._session.request(method='DELETE', url=url)
except APIError:
raise
except ClientError: # pragma: no cover
raise

async def get_default_destination(self) -> Dict:
"""
Get the current default destination. The default destination is globally available to all members of an
organization.

Returns:
dict: A dictionary containing the default destination details.

Raises:
APIError: If the API returns an error response.
ClientError: If there is an issue with the client request.
"""
url = f'{self._base_url}/default'
try:
response = await self._session.request(method='GET', url=url)
except APIError:
raise
except ClientError: # pragma: no cover
raise
else:
dest = response.json()
return dest
31 changes: 31 additions & 0 deletions planet/order_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from typing import Any, Dict, List, Mapping, Optional, Union

from . import geojson, specs
from .clients.destinations import DEFAULT_DESTINATION_REF
from .exceptions import ClientError

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -392,6 +393,36 @@ def s3_compatible(endpoint: str,
return {'s3_compatible': parameters}


def destination(destination_ref: str,
path_prefix: Optional[str] = None) -> dict:
"""Destinations API configuration.
Parameters:
destination_ref: Reference to an existing Destinations API
destination.
path_prefix: Path prefix for deliveries.
"""
cloud_details: Dict[str, Any] = {'ref': destination_ref}

if path_prefix:
cloud_details['path_prefix'] = path_prefix

return {'destination': cloud_details}


def default_destination(path_prefix: Optional[str] = None) -> dict:
"""Default Destinations API configuration.

Parameters:
path_prefix: Path prefix for deliveries.
"""
parameters: Dict[str, Any] = {'ref': DEFAULT_DESTINATION_REF}

if path_prefix:
parameters['path_prefix'] = path_prefix

return {'destination': parameters}


def _tool(name: str, parameters: dict) -> dict:
"""Create the API spec representation of a tool.

Expand Down
31 changes: 31 additions & 0 deletions planet/subscription_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from typing_extensions import Literal

from . import geojson, specs
from .clients.destinations import DEFAULT_DESTINATION_REF
from .exceptions import ClientError

NOTIFICATIONS_TOPICS = ('delivery.success',
Expand Down Expand Up @@ -528,6 +529,36 @@ def s3_compatible(endpoint: str,
return _delivery('s3_compatible', parameters)


def destination(destination_ref: str,
path_prefix: Optional[str] = None) -> dict:
"""Specify a Destinations API destination by its ref.

Parameters:
destination_ref: The ID of the destination to deliver to.
path_prefix: Path prefix for deliveries.
"""
parameters: Dict[str, Any] = {"ref": destination_ref}

if path_prefix:
parameters['path_prefix'] = path_prefix

return _delivery('destination', parameters)


def default_destination(path_prefix: Optional[str] = None) -> dict:
"""Specify the organization's default Destinations API destination.

Parameters:
path_prefix: Path prefix for deliveries.
"""
parameters: Dict[str, Any] = {"ref": DEFAULT_DESTINATION_REF}

if path_prefix:
parameters['path_prefix'] = path_prefix

return _delivery('destination', parameters)


def notifications(url: str, topics: List[str]) -> dict:
"""Specify a subscriptions API notification.

Expand Down
Loading