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
5 changes: 3 additions & 2 deletions .github/workflows/build-publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ jobs:
run: |
MAJOR=$(node -p "require('./package.json').version.split('.')[0]")
CDN=$(grep -Po '(?<=DEFAULT_KEPLER_GL_CDN_VERSION = ")[^"]+' bindings/python/keplergl/_html_export.py)
CDN_MAJOR=$(echo "$CDN" | cut -d'.' -f1)
echo "package.json major: $MAJOR"
echo "Python CDN version: $CDN"
if [ "$MAJOR" != "$CDN" ]; then
echo "Python CDN version: $CDN (major: $CDN_MAJOR)"
if [ "$MAJOR" != "$CDN_MAJOR" ]; then
echo "::error::DEFAULT_KEPLER_GL_CDN_VERSION ($CDN) in _html_export.py does not match major version ($MAJOR) from package.json. Please update it."
exit 1
fi
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This guide explains how to set up kepler.gl for Jupyter for local development.
## Prerequisites

- Python >= 3.9
- Node.js (for building the frontend)
- Node.js >= 20 (for building the frontend)
- JupyterLab >= 4.0 or Notebook >= 7.0

## Installation
Expand Down
99 changes: 79 additions & 20 deletions bindings/python/keplergl/_html_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@
import pandas as pd
import geopandas as gpd

DEFAULT_KEPLER_GL_CDN_VERSION = "3"
DEFAULT_KEPLER_GL_CDN_VERSION = "3.3.0-alpha.4"

REACT_VERSION = "19.1.0"
REACT_DOM_VERSION = "19.1.0"
REDUX_VERSION = "5.0.1"
REACT_REDUX_VERSION = "9.3.0"
STYLED_COMPONENTS_VERSION = "6.1.19"
ES_MODULE_SHIMS_VERSION = "2.8.1"


def _dataset_to_csv(data) -> Optional[str]:
Expand Down Expand Up @@ -191,19 +198,73 @@ def export_map_html(
<!--Kepler css-->
<link href="https://unpkg.com/kepler.gl@{kepler_gl_version}/umd/keplergl.min.css" rel="stylesheet">

<!--MapBox css-->
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.1/mapbox-gl.css" rel="stylesheet">
<link href="https://unpkg.com/maplibre-gl@^3/dist/maplibre-gl.css" rel="stylesheet">
<!--MapLibre css-->
<link href="https://unpkg.com/maplibre-gl@^4/dist/maplibre-gl.css" rel="stylesheet">

<!--
React >= 19 no longer ships UMD builds, so we load React and the other
peer dependencies as ES modules from esm.sh via an import map, then
expose them as window globals that the kepler.gl UMD bundle expects.

<!-- Load React/Redux -->
<script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js" crossorigin></script>
<script src="https://unpkg.com/redux@4.2.1/dist/redux.js" crossorigin></script>
<script src="https://unpkg.com/react-redux@8.1.2/dist/react-redux.min.js" crossorigin></script>
<script src="https://unpkg.com/styled-components@6.1.8/dist/styled-components.min.js" crossorigin></script>
es-module-shims runs in "shim mode" so the page also works when opened
as a local file:// (native import maps are blocked under file://).
-->
<script>
window.esmsInitOptions = {{shimMode: true, version: '{ES_MODULE_SHIMS_VERSION}'}};
</script>
<script async src="https://ga.jspm.io/npm:es-module-shims@{ES_MODULE_SHIMS_VERSION}/dist/es-module-shims.js" crossorigin="anonymous"></script>

<script type="importmap-shim">
{{
"imports": {{
"react": "https://esm.sh/react@{REACT_VERSION}",
"react/jsx-runtime": "https://esm.sh/react@{REACT_VERSION}/jsx-runtime",
"react-dom": "https://esm.sh/react-dom@{REACT_DOM_VERSION}?external=react",
"react-dom/client": "https://esm.sh/react-dom@{REACT_DOM_VERSION}/client?external=react",
"redux": "https://esm.sh/redux@{REDUX_VERSION}",
"react-redux": "https://esm.sh/react-redux@{REACT_REDUX_VERSION}?external=react,react-dom,redux",
"styled-components": "https://esm.sh/styled-components@{STYLED_COMPONENTS_VERSION}?external=react,react-dom"
}}
}}
</script>

<!-- Load Kepler.gl -->
<script src="https://unpkg.com/kepler.gl@{kepler_gl_version}/umd/keplergl.min.js" crossorigin></script>
<!--
Expose the ES modules as globals for the kepler.gl UMD bundle, then
dynamically load that bundle and run the bootstrap scripts once ready.
-->
<script type="module-shim">
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as ReactDOMClient from 'react-dom/client';
import * as Redux from 'redux';
import * as ReactRedux from 'react-redux';
import * as StyledComponents from 'styled-components';

window.React = React.default || React;
window.ReactDOM = Object.assign({{}}, ReactDOM.default || ReactDOM, ReactDOMClient);
window.Redux = Redux.default || Redux;
window.ReactRedux = ReactRedux.default || ReactRedux;
Comment thread
igorDykhta marked this conversation as resolved.
window.styled = Object.assign(StyledComponents.default, StyledComponents);

function loadScript(src) {{
return new Promise(function(resolve, reject) {{
var s = document.createElement('script');
s.src = src; s.crossOrigin = 'anonymous';
s.onload = resolve; s.onerror = reject;
document.head.appendChild(s);
}});
}}

loadScript('https://unpkg.com/kepler.gl@{kepler_gl_version}/umd/keplergl.min.js')
.then(function() {{
document.querySelectorAll('script[type="text/kepler-bootstrap"]').forEach(function(node) {{
var s = document.createElement('script');
s.text = node.textContent;
document.body.appendChild(s);
}});
}})
.catch(function(err) {{ console.error('kepler.gl: failed to load UMD bundle', err); }});
</script>

<style type="text/css">
body {{margin: 0; padding: 0; overflow: hidden;}}
Expand All @@ -216,7 +277,7 @@ def export_map_html(
<body>
<div id="app"></div>

<script>
<script type="text/kepler-bootstrap">
/** STORE **/
const reducers = (function createReducers(redux, keplerGl) {{
return redux.combineReducers({{
Expand All @@ -238,14 +299,13 @@ def export_map_html(
}}(Redux, middleWares));

const store = (function createStore(redux, enhancers) {{
return redux.createStore(reducers, {{}}, redux.compose(enhancers));
return redux.legacy_createStore(reducers, {{}}, redux.compose(enhancers));
}}(Redux, enhancers));
/** END STORE **/

/** COMPONENTS **/
var KeplerElement = (function makeKeplerElement(react, keplerGl, mapboxToken) {{
return function App() {{
var rootElm = react.useRef(null);
var _useState = react.useState({{
width: window.innerWidth,
height: window.innerHeight
Expand Down Expand Up @@ -283,14 +343,13 @@ def export_map_html(
/** END COMPONENTS **/

/** Render **/
(function render(react, reactDOM, app) {{
const container = document.getElementById('app');
const root = reactDOM.createRoot(container);
(function render(reactDOM, app) {{
const root = reactDOM.createRoot(document.getElementById('app'));
root.render(app);
}}(React, ReactDOM, app));
}}(ReactDOM, app));
</script>

<script>
<script type="text/kepler-bootstrap">
(function customize(keplerGl, store) {{
var datasets = [];
{dataset_js}
Expand Down
26 changes: 13 additions & 13 deletions bindings/python/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@
},
"devDependencies": {
"@anywidget/types": "^0.2.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"esbuild": "^0.20.0",
"eslint": "^8.57.0",
"prettier": "^3.2.0",
"typescript": "^5.4.0"
"typescript": "^5.6.0"
},
"dependencies": {
"@kepler.gl/actions": "^3.2.0",
"@kepler.gl/components": "^3.2.0",
"@kepler.gl/processors": "^3.2.0",
"@kepler.gl/reducers": "^3.2.0",
"@kepler.gl/schemas": "^3.2.0",
"@kepler.gl/styles": "^3.2.0",
"@kepler.gl/actions": "^3.3.0-alpha.4",
"@kepler.gl/components": "^3.3.0-alpha.4",
"@kepler.gl/processors": "^3.3.0-alpha.4",
"@kepler.gl/reducers": "^3.3.0-alpha.4",
"@kepler.gl/schemas": "^3.3.0-alpha.4",
"@kepler.gl/styles": "^3.3.0-alpha.4",
"apache-arrow": "^21.0.0",
"assert": "^2.1.0",
"events": "^3.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"redux": "^4.2.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-redux": "^9.1.0",
"redux": "^5.0.0",
"styled-components": "^6.4.3"
}
}
5 changes: 2 additions & 3 deletions bindings/python/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

import {createStore as createReduxStore, combineReducers, applyMiddleware, compose} from 'redux';
import {legacy_createStore as createReduxStore, combineReducers, applyMiddleware, compose, type StoreEnhancer} from 'redux';
import {keplerGlReducer, enhanceReduxMiddleware} from '@kepler.gl/reducers';

export const KEPLER_ID = 'jupyter_kepler';
Expand All @@ -21,6 +21,5 @@ export function createStore() {
const middlewares = enhanceReduxMiddleware([]);
const enhancers = [applyMiddleware(...middlewares)];

// @ts-expect-error Redux types are not compatible with TypeScript
return createReduxStore(reducers, {}, compose(...enhancers));
return createReduxStore(reducers, {}, compose(...enhancers) as StoreEnhancer);
}
Loading
Loading