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 .github/workflows/lint_type_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Linting And Type Checking


on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
lint_type_check:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install Dependencies
run: pip install mypy certifi ruff

- name: Run mypy
run: mypy .

- name: Lint
run: ruff check

- name: Format
run: ruff format --diff
2 changes: 2 additions & 0 deletions felt_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"create_embed_token",
"add_source_layer",
"duplicate_map",
"get_map",
# Layers
"list_layers",
"upload_file",
Expand Down Expand Up @@ -120,6 +121,7 @@
# Elements
"list_elements",
"list_element_groups",
"get_element_group",
"upsert_elements",
"delete_element",
"upsert_element_groups",
Expand Down
13 changes: 8 additions & 5 deletions felt_python/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
def make_request(
url: str,
method: typing.Literal["GET", "POST", "PATCH", "DELETE"],
json: dict | None = None,
json: dict | list | None = None,
api_token: str | None = None,
) -> http.client.HTTPResponse:
"""Basic wrapper for requests that adds auth"""
Expand All @@ -40,10 +40,13 @@ def make_request(
except PackageNotFoundError:
package_version = "local"

data, headers = None, {
"Authorization": f"Bearer {api_token}",
"User-Agent": f"felt-python/{package_version}",
}
data, headers = (
None,
{
"Authorization": f"Bearer {api_token}",
"User-Agent": f"felt-python/{package_version}",
},
)
if json is not None:
data = json_.dumps(json).encode("utf8")
headers["Content-Type"] = "application/json"
Expand Down
12 changes: 10 additions & 2 deletions felt_python/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ def upsert_elements(
"""
if isinstance(geojson_feature_collection, str):
geojson_feature_collection = json.loads(geojson_feature_collection)
assert isinstance(geojson_feature_collection, dict), (
"geojson_feature_collection must be a valid GeoJSON"
)
response = make_request(
url=ELEMENTS.format(map_id=map_id),
method="POST",
Expand Down Expand Up @@ -132,12 +135,17 @@ def post_element_group(
json_element: dict | str,
api_token: str | None = None,
):
upsert_element_groups(map_id, json_element, api_token)
if isinstance(json_element, str):
json_element = json.loads(json_element)
assert isinstance(json_element, dict), (
"json_element must be a valid JSON object"
)
upsert_element_groups(map_id, [json_element], api_token)


def upsert_element_groups(
map_id: str,
element_groups: list[dict[str, str]],
element_groups: list[dict],
api_token: str | None = None,
):
"""Post multiple element groups
Expand Down
12 changes: 6 additions & 6 deletions felt_python/layer_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ def delete_layer_group(
def update_layer_group(
map_id: str,
layer_group_id: str,
name: str = None,
caption: str = None,
ordering_key: int = None,
visibility_interaction: str = None,
name: str | None = None,
caption: str | None = None,
ordering_key: int | None = None,
visibility_interaction: str | None = None,
api_token: str | None = None,
):
"""Update a single layer group
Expand All @@ -124,7 +124,7 @@ def update_layer_group(
Returns:
The updated layer group
"""
json_payload = {}
json_payload: dict = {}

if name is not None:
json_payload["name"] = name
Expand All @@ -147,7 +147,7 @@ def update_layer_group(
def publish_layer_group(
map_id: str,
layer_group_id: str,
name: str = None,
name: str | None = None,
api_token: str | None = None,
):
"""Publish a layer group to the Felt library
Expand Down
43 changes: 21 additions & 22 deletions felt_python/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import typing
import urllib.request
import uuid
import typing

from urllib.parse import urljoin

Expand Down Expand Up @@ -43,11 +42,11 @@ def upload_file(
map_id: str,
file_name: str,
layer_name: str,
metadata: dict[str, str] = None,
hints: list[dict[str, str]] = None,
lat: float = None,
lng: float = None,
zoom: float = None,
metadata: dict[str, str] | None = None,
hints: list[dict[str, str]] | None = None,
lat: float | None = None,
lng: float | None = None,
zoom: float | None = None,
api_token: str | None = None,
):
"""Upload a file to a Felt map
Expand All @@ -66,7 +65,7 @@ def upload_file(
Returns:
The upload response including layer ID and presigned upload details
"""
json_payload = {"name": layer_name}
json_payload: dict = {"name": layer_name}

if metadata is not None:
json_payload["metadata"] = metadata
Expand All @@ -91,10 +90,10 @@ def upload_file(

def upload_dataframe(
map_id: str,
dataframe: "pd.DataFrame",
dataframe: "pandas.DataFrame", # type: ignore[name-defined] # noqa: F821
layer_name: str,
metadata: dict[str, str] = None,
hints: list[dict[str, str]] = None,
metadata: dict[str, str] | None = None,
hints: list[dict[str, str]] | None = None,
api_token: str | None = None,
):
"""Upload a Pandas DataFrame to a Felt map"""
Expand All @@ -113,10 +112,10 @@ def upload_dataframe(

def upload_geodataframe(
map_id: str,
geodataframe: "gpd.GeoDataFrame",
geodataframe: "geopandas.GeoDataFrame", # type: ignore[name-defined] # noqa: F821
layer_name: str,
metadata: dict[str, str] = None,
hints: list[dict[str, str]] = None,
metadata: dict[str, str] | None = None,
hints: list[dict[str, str]] | None = None,
api_token: str | None = None,
):
"""Upload a GeoPandas GeoDataFrame to a Felt map"""
Expand Down Expand Up @@ -159,8 +158,8 @@ def upload_url(
map_id: str,
layer_url: str,
layer_name: str,
metadata: dict[str, str] = None,
hints: list[dict[str, str]] = None,
metadata: dict[str, str] | None = None,
hints: list[dict[str, str]] | None = None,
api_token: str | None = None,
):
"""Upload a URL to a Felt map
Expand All @@ -176,7 +175,7 @@ def upload_url(
Returns:
The upload response
"""
json_payload = {
json_payload: dict = {
"import_url": layer_url,
"name": layer_name,
}
Expand Down Expand Up @@ -209,8 +208,8 @@ def refresh_url_layer(map_id: str, layer_id: str, api_token: str | None = None):


@deprecated(reason="Please use `get_layer` instead")
def get_layer_details(map_id: str, api_token: str | None = None):
get_layer(map_id, api_token)
def get_layer_details(map_id: str, layer_id: str, api_token: str | None = None):
get_layer(map_id, layer_id, api_token)


def get_layer(
Expand Down Expand Up @@ -331,7 +330,7 @@ def delete_layer(
def publish_layer(
map_id: str,
layer_id: str,
name: str = None,
name: str | None = None,
api_token: str | None = None,
):
"""Publish a layer to the Felt library
Expand All @@ -345,7 +344,7 @@ def publish_layer(
Returns:
The published layer
"""
json_payload = {}
json_payload: dict = {}
if name is not None:
json_payload["name"] = name

Expand All @@ -362,7 +361,7 @@ def create_custom_export(
map_id: str,
layer_id: str,
output_format: str,
filters: list = None,
filters: list | None = None,
email_on_completion: bool = True,
api_token: str | None = None,
):
Expand All @@ -381,7 +380,7 @@ def create_custom_export(
Returns:
Export request details including ID and polling endpoint
"""
json_payload = {
json_payload: dict = {
"output_format": output_format,
"email_on_completion": email_on_completion,
}
Expand Down
55 changes: 30 additions & 25 deletions felt_python/maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@


def create_map(
title: str = None,
description: str = None,
public_access: str = None,
basemap: str = None,
lat: float = None,
lon: float = None,
zoom: float = None,
layer_urls: list[str] = None,
workspace_id: str = None,
api_token: str = None,
title: str | None = None,
description: str | None = None,
public_access: str | None = None,
basemap: str | None = None,
lat: float | None = None,
lon: float | None = None,
zoom: float | None = None,
layer_urls: list[str] | None = None,
workspace_id: str | None = None,
api_token: str | None = None,
):
"""Create a new Felt map

Expand Down Expand Up @@ -56,7 +56,7 @@ def create_map(
Returns:
The created map
"""
json_args = {}
json_args: dict = {}

if title is not None:
json_args["title"] = title
Expand Down Expand Up @@ -112,10 +112,10 @@ def get_map_details(map_id: str, api_token: str | None = None):

def update_map(
map_id: str,
title: str = None,
description: str = None,
public_access: str = None,
api_token: str = None,
title: str | None = None,
description: str | None = None,
public_access: str | None = None,
api_token: str | None = None,
):
"""Update a map's details

Expand All @@ -124,8 +124,8 @@ def update_map(
title: Optional new title for the map
description: Optional new description for the map
public_access: Optional new public access setting
Options are "private", "view_only", "view_and_comment",
or "view_comment_and_edit"
Options are "private", "view_only", "view_and_comment",
or "view_comment_and_edit"
api_token: Optional API token

Returns:
Expand All @@ -149,7 +149,10 @@ def update_map(


def move_map(
map_id: str, project_id: str = None, folder_id: str = None, api_token: str = None
map_id: str,
project_id: str | None = None,
folder_id: str | None = None,
api_token: str | None = None,
):
"""Move a map to a different project or folder

Expand Down Expand Up @@ -182,7 +185,9 @@ def move_map(
return json.load(response)


def create_embed_token(map_id: str, user_email: str = None, api_token: str = None):
def create_embed_token(
map_id: str, user_email: str | None = None, api_token: str | None = None
):
"""Create an embed token for a map

Args:
Expand All @@ -208,7 +213,7 @@ def create_embed_token(map_id: str, user_email: str = None, api_token: str = Non


def add_source_layer(
map_id: str, source_layer_params: dict[str, str], api_token: str = None
map_id: str, source_layer_params: dict[str, str], api_token: str | None = None
):
"""Add a layer from a source to a map

Expand All @@ -235,10 +240,10 @@ def add_source_layer(

def duplicate_map(
map_id: str,
title: str = None,
project_id: str = None,
folder_id: str = None,
api_token: str = None,
title: str | None = None,
project_id: str | None = None,
folder_id: str | None = None,
api_token: str | None = None,
):
"""Duplicate a map

Expand All @@ -257,7 +262,7 @@ def duplicate_map(
if project_id is not None and folder_id is not None:
raise ValueError("Cannot specify both project_id and folder_id")

json_args = {}
json_args: dict = {}
if title is not None:
json_args["title"] = title

Expand Down
Loading