Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pydeck): support v9 in bindings #8577

Merged
merged 14 commits into from Apr 26, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 4 additions & 12 deletions bindings/pydeck-carto/pydeck_carto/__init__.py
@@ -1,19 +1,11 @@
from ._version import __version__
from .layer import (
MapType,
CartoConnection,
GeoColumnType,
register_carto_layer,
get_layer_credentials,
)
from .layer import register_layers
from . import sources
from . import styles

__all__ = [
"__version__",
"MapType",
"CartoConnection",
"GeoColumnType",
"register_carto_layer",
"get_layer_credentials",
"register_layers",
"sources",
"styles",
]
2 changes: 1 addition & 1 deletion bindings/pydeck-carto/pydeck_carto/_version.py
@@ -1 +1 @@
__version__ = "0.1.0"
__version__ = "0.2.0b0"
47 changes: 8 additions & 39 deletions bindings/pydeck-carto/pydeck_carto/layer.py
@@ -1,7 +1,7 @@
import pydeck as pdk

H3_VERSION = "~4.1.*"
DECKGL_VERSION = "~8.8.*"
DECKGL_VERSION = "~9.0.0-beta.*"

LIBRARIES_TO_INCLUDE = [
f"npm/h3-js@{H3_VERSION}/dist/h3-js.umd.js",
Expand All @@ -12,33 +12,18 @@
CARTO_LAYER_BUNDLE_URL = f"https://cdn.jsdelivr.net/combine/{SELECTED_LIBRARIES}"


class MapType:
QUERY = pdk.types.String("query")
TABLE = pdk.types.String("table")
TILESET = pdk.types.String("tileset")


class CartoConnection:
CARTO_DW = pdk.types.String("carto_dw")


class GeoColumnType:
H3 = pdk.types.String("h3")
QUADBIN = pdk.types.String("quadbin")


def register_carto_layer():
"""Add CartoLayer JS bundle to pydeck's custom libraries."""
library_name = "CartoLayerLibrary"
def register_layers():
"""Add carto layers JS bundle to pydeck's custom libraries."""
library_name = "CartoLibrary"
custom_library = {
"libraryName": library_name,
"resourceUri": CARTO_LAYER_BUNDLE_URL,
}
default_layer_attributes = {
"CartoLayer": {
"client_id": pdk.types.String("pydeck-carto"),
"on_data_error": pdk.types.Function("notifyError"),
}
"VectorTileLayer": {"on_data_error": pdk.types.Function("notifyError")},
"H3TileLayer": {"on_data_error": pdk.types.Function("notifyError")},
"QuadbinTileLayer": {"on_data_error": pdk.types.Function("notifyError")},
"RasterTileLayer": {"on_data_error": pdk.types.Function("notifyError")},
}
configuration = """{
functions: {
Expand Down Expand Up @@ -73,19 +58,3 @@ def register_carto_layer():
)
if not exists:
pdk.settings.custom_libraries.append(custom_library)


def get_layer_credentials(carto_auth) -> dict:
"""Get the layer credentials object to gather information
from carto warehouses.

The return object has the following structure:
``{"apiVersion": "v3", "apiBaseUrl": "...", "accessToken": "...",}``
"""
api_base_url = carto_auth.get_api_base_url()
access_token = carto_auth.get_access_token()
return {
"apiVersion": "v3",
"apiBaseUrl": api_base_url,
"accessToken": access_token,
}
49 changes: 49 additions & 0 deletions bindings/pydeck-carto/pydeck_carto/sources.py
@@ -0,0 +1,49 @@
import pydeck as pdk


def base_source(connection_name: str, access_token: str, api_base_url: str):
return {
"connectionName": connection_name,
"accessToken": access_token,
"apiBaseUrl": api_base_url,
donmccurdy marked this conversation as resolved.
Show resolved Hide resolved
"clientId": "pydeck-carto",
}


def vector_table_source(table_name: str, spatial_data_column: str, **kwargs):
return pdk.types.Function(
"vectorTableSource",
**{
"tableName": table_name,
"spatialDataColumn": spatial_data_column,
**base_source(**kwargs),
}
)


def vector_query_source(sql_query: str, spatial_data_column: str, **kwargs):
return pdk.types.Function(
"vectorQuerySource",
**{
"sqlQuery": sql_query,
"spatialDataColumn": spatial_data_column,
**base_source(**kwargs),
}
)


def vector_tileset_source(table_name: str, **kwargs):
return pdk.types.Function(
"vectorTilesetSource", **{"tableName": table_name, **base_source(**kwargs)}
)


# TODO: Implement all the source functions and parameters
# https://felixpalmer.github.io/deck.gl/docs/api-reference/carto/data-sources
# h3_table_source
# h3_query_source
# h3_tileset_source
# quadbin_table_source
# quadbin_query_source
# quadbin_tileset_source
# raster_tileset_source (experimental)
50 changes: 8 additions & 42 deletions bindings/pydeck-carto/tests/test_layer.py
@@ -1,50 +1,16 @@
import json
import pydeck as pdk

from carto_auth import CartoAuth
from pydeck_carto import register_carto_layer, get_layer_credentials
from pydeck_carto.layer import MapType, CartoConnection
from pydeck_carto import register_layers


def test_register_carto_layer():
def test_register_layers():
pdk.settings.configuration = None
pdk.settings.default_layer_attributes = None
pdk.settings.custom_libraries == []
register_carto_layer()
register_layers()
assert "notifyError" in pdk.settings.configuration
assert "CartoLayer" in pdk.settings.default_layer_attributes
assert pdk.settings.custom_libraries[0]["libraryName"] == "CartoLayerLibrary"


def test_get_layer_credentials():
carto_auth = CartoAuth(
mode="oauth",
api_base_url="https://api.carto.com",
access_token="1234567890",
expiration=10000000000,
)
assert get_layer_credentials(carto_auth) == {
"apiVersion": "v3",
"apiBaseUrl": "https://api.carto.com",
"accessToken": "1234567890",
}


def test_carto_layer_json():
layer = pdk.Layer(
"CartoLayer",
data="carto-demo-data.demo_tables.wrong_table",
type_=MapType.TABLE,
connection=CartoConnection.CARTO_DW,
credentials={},
)
json_input = json.loads(layer.to_json())

assert json_input["@@type"] == "CartoLayer"
assert json_input["data"] == "carto-demo-data.demo_tables.wrong_table"
assert json_input["type"] == "table"
assert json_input["connection"] == "carto_dw"
assert json_input["credentials"] == {}
# Default attributes
assert json_input["clientId"] == "pydeck-carto"
assert json_input["onDataError"] == {"@@function": "notifyError"}
assert "VectorTileLayer" in pdk.settings.default_layer_attributes
assert "H3TileLayer" in pdk.settings.default_layer_attributes
assert "QuadbinTileLayer" in pdk.settings.default_layer_attributes
assert "RasterTileLayer" in pdk.settings.default_layer_attributes
assert pdk.settings.custom_libraries[0]["libraryName"] == "CartoLibrary"
57 changes: 57 additions & 0 deletions bindings/pydeck-carto/tests/test_sources.py
@@ -0,0 +1,57 @@
from pydeck_carto.sources import (
vector_table_source,
vector_query_source,
vector_tileset_source,
)


def test_vector_table_source():
assert vector_table_source(
table_name="project.database.table",
spatial_data_column="geom",
connection_name="carto_dw",
access_token="1234",
api_base_url="https://carto.com",
).serialize() == {
"@@function": "vectorTableSource",
"tableName": "project.database.table",
"spatialDataColumn": "geom",
"connectionName": "carto_dw",
"accessToken": "1234",
"apiBaseUrl": "https://carto.com",
"clientId": "pydeck-carto",
}


def vector_query_source():
assert vector_query_source(
sql_query="select * from project.database.table",
spatial_data_column="geom",
connection_name="carto_dw",
access_token="1234",
api_base_url="https://carto.com",
).serialize() == {
"@@function": "vectorQuerySource",
"sqlQuery": "select * from project.database.table",
"spatialDataColumn": "geom",
"connectionName": "carto_dw",
"accessToken": "1234",
"apiBaseUrl": "https://carto.com",
"clientId": "pydeck-carto",
}


def test_vector_tileset_source():
assert vector_tileset_source(
table_name="project.database.table",
connection_name="carto_dw",
access_token="1234",
api_base_url="https://carto.com",
).serialize() == {
"@@function": "vectorTilesetSource",
"tableName": "project.database.table",
"connectionName": "carto_dw",
"accessToken": "1234",
"apiBaseUrl": "https://carto.com",
"clientId": "pydeck-carto",
}
2 changes: 1 addition & 1 deletion bindings/pydeck/pydeck/frontend_semver.py
@@ -1 +1 @@
DECKGL_SEMVER = "~8.8.*"
DECKGL_SEMVER = "~9.0.0-beta.*"