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
19 changes: 19 additions & 0 deletions felt_python/__init__.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,16 @@
update_source,
delete_source,
sync_source,
create_source_credential,
update_source_credential,
delete_source_credential,
)
from .components import (
list_layer_components,
create_layer_component,
get_layer_component,
update_layer_component,
delete_layer_component,
)
from .library import list_library_layers
from .comments import export_comments, resolve_comment, delete_comment
Expand DownExpand Up@@ -138,6 +148,15 @@
"update_source",
"delete_source",
"sync_source",
"create_source_credential",
"update_source_credential",
"delete_source_credential",
# Layer components
"list_layer_components",
"create_layer_component",
"get_layer_component",
"update_layer_component",
"delete_layer_component",
# Library
"list_library_layers",
# Comments
Expand Down
175 changes: 175 additions & 0 deletions felt_python/components.py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
"""Layer components"""

import json

from urllib.parse import urljoin

from .api import make_request, BASE_URL


COMPONENTS = urljoin(BASE_URL, "maps/{map_id}/layers/{layer_id}/components")
COMPONENT = urljoin(
BASE_URL, "maps/{map_id}/layers/{layer_id}/components/{component_id}"
)


def list_layer_components(map_id: str, layer_id: str, api_token: str | None = None):
"""List all components on a layer

Args:
map_id: The ID of the map containing the layer
layer_id: The ID of the layer to list components from
api_token: Optional API token

Returns:
List of layer components
"""
response = make_request(
url=COMPONENTS.format(map_id=map_id, layer_id=layer_id),
method="GET",
api_token=api_token,
)
return json.load(response)


def create_layer_component(
map_id: str,
layer_id: str,
component_type: str,
data: dict,
title: str | None = None,
config: dict | None = None,
api_token: str | None = None,
):
"""Create a component on a layer

Args:
map_id: The ID of the map containing the layer
layer_id: The ID of the layer to create the component on
component_type: The type of component to create. Immutable after
creation. Options are "statistic", "histogram", "bar_chart",
"time_series", or "filter".
data: How the component computes its result. The expected shape
depends on the component type. For example, a "statistic"
component takes either a feature count
({"aggregate": "count"}) or an attribute aggregation
({"aggregate": "avg", "aggregate_by": "some_attribute"}).
title: Optional display title (max 256 characters)
config: Optional component configuration. Common keys include
"reactive" (whether the component reacts to other components'
selections) and "viewport_mode" ("global" or "viewport").
api_token: Optional API token

Returns:
The created layer component
"""
json_payload: dict = {"type": component_type, "data": data}
if title is not None:
json_payload["title"] = title
if config is not None:
json_payload["config"] = config

response = make_request(
url=COMPONENTS.format(map_id=map_id, layer_id=layer_id),
method="POST",
json=json_payload,
api_token=api_token,
)
return json.load(response)


def get_layer_component(
map_id: str,
layer_id: str,
component_id: str,
api_token: str | None = None,
):
"""Get details of a layer component

Args:
map_id: The ID of the map containing the layer
layer_id: The ID of the layer containing the component
component_id: The ID of the component to get details for
api_token: Optional API token

Returns:
Layer component details
"""
response = make_request(
url=COMPONENT.format(
map_id=map_id, layer_id=layer_id, component_id=component_id
),
method="GET",
api_token=api_token,
)
return json.load(response)


def update_layer_component(
map_id: str,
layer_id: str,
component_id: str,
data: dict | None = None,
title: str | None = None,
config: dict | None = None,
api_token: str | None = None,
):
"""Update a layer component

The component's type is immutable after creation.

Args:
map_id: The ID of the map containing the layer
layer_id: The ID of the layer containing the component
component_id: The ID of the component to update
data: Optionally change how the component computes its result.
Replaces the current value as a unit when provided; partial
updates are not supported.
title: Optional new display title (max 256 characters)
config: Optional component configuration updates. Provided keys are
updated; omitted keys keep their current value.
api_token: Optional API token

Returns:
The updated layer component
"""
json_payload: dict = {}
if data is not None:
json_payload["data"] = data
if title is not None:
json_payload["title"] = title
if config is not None:
json_payload["config"] = config

response = make_request(
url=COMPONENT.format(
map_id=map_id, layer_id=layer_id, component_id=component_id
),
method="POST",
json=json_payload,
api_token=api_token,
)
return json.load(response)


def delete_layer_component(
map_id: str,
layer_id: str,
component_id: str,
api_token: str | None = None,
):
"""Delete a component from a layer

Args:
map_id: The ID of the map containing the layer
layer_id: The ID of the layer containing the component
component_id: The ID of the component to delete
api_token: Optional API token
"""
make_request(
url=COMPONENT.format(
map_id=map_id, layer_id=layer_id, component_id=component_id
),
method="DELETE",
api_token=api_token,
)
14 changes: 12 additions & 2 deletions felt_python/layer_groups.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -66,7 +66,8 @@ def update_layer_groups(
map_id: The ID of the map containing the layer groups
layer_group_params_list: List of layer group parameters to update.
Each dict must contain at least "name" key.
Optional keys include "id", "caption", "ordering_key".
Optional keys include "id", "caption", "subtitle", "ordering_key",
"legend_visibility" and "visibility_interaction".
api_token: Optional API token

Returns:
Expand DownExpand Up@@ -105,7 +106,9 @@ def update_layer_group(
layer_group_id: str,
name: str | None = None,
caption: str | None = None,
subtitle: str | None = None,
ordering_key: int | None = None,
legend_visibility: str | None = None,
visibility_interaction: str | None = None,
api_token: str | None = None,
):
Expand All@@ -116,9 +119,12 @@ def update_layer_group(
layer_group_id: The ID of the layer group to update
name: Optional new name for the layer group
caption: Optional new caption for the layer group
subtitle: Optional new subtitle for the layer group
ordering_key: Optional new ordering key for positioning
legend_visibility: Optional legend visibility setting
("show", "hide")
visibility_interaction: Optional visibility interaction setting
("default", "slider")
("default", "slider", "select", "multi_select")
api_token: Optional API token

Returns:
Expand All@@ -130,8 +136,12 @@ def update_layer_group(
json_payload["name"] = name
if caption is not None:
json_payload["caption"] = caption
if subtitle is not None:
json_payload["subtitle"] = subtitle
if ordering_key is not None:
json_payload["ordering_key"] = ordering_key
if legend_visibility is not None:
json_payload["legend_visibility"] = legend_visibility
if visibility_interaction is not None:
json_payload["visibility_interaction"] = visibility_interaction

Expand Down
8 changes: 5 additions & 3 deletions felt_python/layers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -298,8 +298,9 @@ def update_layers(
map_id: The ID of the map containing the layers
layer_params_list: List of layer parameters to update.
Each dict must contain at least an "id" key.
Optional keys include "name", "caption",
"metadata", "ordering_key", "refresh_period".
Optional keys include "name", "subtitle", "caption",
"metadata", "layer_group_id", "ordering_key", "refresh_period",
"legend_display" and "legend_visibility".
api_token: Optional API token

Returns:
Expand DownExpand Up@@ -371,7 +372,8 @@ def create_custom_export(
map_id: The ID of the map containing the layer
layer_id: The ID of the layer to export
output_format: The format to export in.
Options are "csv", "gpkg", or "geojson"
Options are "csv", "gpkg", "geojson", "geotiff", "pmtiles",
"shapefile", "kml", or "geoparquet"
filters: Optional list of filters in Felt Style Language filter format
email_on_completion: Whether to send an email when the export completes.
Defaults to True.
Expand Down
Loading
Loading