Skip to content

Commit 28435db

Browse files
Ihor DykhtaIhor Dykhta
authored andcommitted
chore: bump python bindings to latest kepler.gl
Signed-off-by: Ihor Dykhta <ihordykhta@Ihors-MacBook-Pro.local>
1 parent 854f6a5 commit 28435db

5 files changed

Lines changed: 106 additions & 44 deletions

File tree

bindings/python/DEVELOPMENT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This guide explains how to set up kepler.gl for Jupyter for local development.
55
## Prerequisites
66

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

1111
## Installation

bindings/python/keplergl/_html_export.py

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,14 @@
1212
import pandas as pd
1313
import geopandas as gpd
1414

15-
DEFAULT_KEPLER_GL_CDN_VERSION = "3"
15+
DEFAULT_KEPLER_GL_CDN_VERSION = "3.3.0-alpha.4"
16+
17+
REACT_VERSION = "19.1.0"
18+
REACT_DOM_VERSION = "19.1.0"
19+
REDUX_VERSION = "5.0.1"
20+
REACT_REDUX_VERSION = "9.3.0"
21+
STYLED_COMPONENTS_VERSION = "6.1.19"
22+
ES_MODULE_SHIMS_VERSION = "2.8.1"
1623

1724

1825
def _dataset_to_csv(data) -> Optional[str]:
@@ -191,19 +198,73 @@ def export_map_html(
191198
<!--Kepler css-->
192199
<link href="https://unpkg.com/kepler.gl@{kepler_gl_version}/umd/keplergl.min.css" rel="stylesheet">
193200
194-
<!--MapBox css-->
195-
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.1.1/mapbox-gl.css" rel="stylesheet">
196-
<link href="https://unpkg.com/maplibre-gl@^3/dist/maplibre-gl.css" rel="stylesheet">
201+
<!--MapLibre css-->
202+
<link href="https://unpkg.com/maplibre-gl@^4/dist/maplibre-gl.css" rel="stylesheet">
203+
204+
<!--
205+
React >= 19 no longer ships UMD builds, so we load React and the other
206+
peer dependencies as ES modules from esm.sh via an import map, then
207+
expose them as window globals that the kepler.gl UMD bundle expects.
197208
198-
<!-- Load React/Redux -->
199-
<script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js" crossorigin></script>
200-
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js" crossorigin></script>
201-
<script src="https://unpkg.com/redux@4.2.1/dist/redux.js" crossorigin></script>
202-
<script src="https://unpkg.com/react-redux@8.1.2/dist/react-redux.min.js" crossorigin></script>
203-
<script src="https://unpkg.com/styled-components@6.1.8/dist/styled-components.min.js" crossorigin></script>
209+
es-module-shims runs in "shim mode" so the page also works when opened
210+
as a local file:// (native import maps are blocked under file://).
211+
-->
212+
<script>
213+
window.esmsInitOptions = {{shimMode: true, version: '{ES_MODULE_SHIMS_VERSION}'}};
214+
</script>
215+
<script async src="https://ga.jspm.io/npm:es-module-shims@{ES_MODULE_SHIMS_VERSION}/dist/es-module-shims.js" crossorigin="anonymous"></script>
216+
217+
<script type="importmap-shim">
218+
{{
219+
"imports": {{
220+
"react": "https://esm.sh/react@{REACT_VERSION}",
221+
"react/jsx-runtime": "https://esm.sh/react@{REACT_VERSION}/jsx-runtime",
222+
"react-dom": "https://esm.sh/react-dom@{REACT_DOM_VERSION}?external=react",
223+
"react-dom/client": "https://esm.sh/react-dom@{REACT_DOM_VERSION}/client?external=react",
224+
"redux": "https://esm.sh/redux@{REDUX_VERSION}",
225+
"react-redux": "https://esm.sh/react-redux@{REACT_REDUX_VERSION}?external=react,react-dom,redux",
226+
"styled-components": "https://esm.sh/styled-components@{STYLED_COMPONENTS_VERSION}?external=react,react-dom"
227+
}}
228+
}}
229+
</script>
204230
205-
<!-- Load Kepler.gl -->
206-
<script src="https://unpkg.com/kepler.gl@{kepler_gl_version}/umd/keplergl.min.js" crossorigin></script>
231+
<!--
232+
Expose the ES modules as globals for the kepler.gl UMD bundle, then
233+
dynamically load that bundle and run the bootstrap scripts once ready.
234+
-->
235+
<script type="module-shim">
236+
import * as React from 'react';
237+
import * as ReactDOM from 'react-dom';
238+
import * as ReactDOMClient from 'react-dom/client';
239+
import * as Redux from 'redux';
240+
import * as ReactRedux from 'react-redux';
241+
import * as StyledComponents from 'styled-components';
242+
243+
window.React = React.default || React;
244+
window.ReactDOM = Object.assign({{}}, ReactDOM.default || ReactDOM, ReactDOMClient);
245+
window.Redux = Redux.default || Redux;
246+
window.ReactRedux = ReactRedux.default || ReactRedux;
247+
window.styled = Object.assign(StyledComponents.default, StyledComponents);
248+
249+
function loadScript(src) {{
250+
return new Promise(function(resolve, reject) {{
251+
var s = document.createElement('script');
252+
s.src = src; s.crossOrigin = 'anonymous';
253+
s.onload = resolve; s.onerror = reject;
254+
document.head.appendChild(s);
255+
}});
256+
}}
257+
258+
loadScript('https://unpkg.com/kepler.gl@{kepler_gl_version}/umd/keplergl.min.js')
259+
.then(function() {{
260+
document.querySelectorAll('script[type="text/kepler-bootstrap"]').forEach(function(node) {{
261+
var s = document.createElement('script');
262+
s.text = node.textContent;
263+
document.body.appendChild(s);
264+
}});
265+
}})
266+
.catch(function(err) {{ console.error('kepler.gl: failed to load UMD bundle', err); }});
267+
</script>
207268
208269
<style type="text/css">
209270
body {{margin: 0; padding: 0; overflow: hidden;}}
@@ -216,7 +277,7 @@ def export_map_html(
216277
<body>
217278
<div id="app"></div>
218279
219-
<script>
280+
<script type="text/kepler-bootstrap">
220281
/** STORE **/
221282
const reducers = (function createReducers(redux, keplerGl) {{
222283
return redux.combineReducers({{
@@ -245,7 +306,6 @@ def export_map_html(
245306
/** COMPONENTS **/
246307
var KeplerElement = (function makeKeplerElement(react, keplerGl, mapboxToken) {{
247308
return function App() {{
248-
var rootElm = react.useRef(null);
249309
var _useState = react.useState({{
250310
width: window.innerWidth,
251311
height: window.innerHeight
@@ -283,14 +343,13 @@ def export_map_html(
283343
/** END COMPONENTS **/
284344
285345
/** Render **/
286-
(function render(react, reactDOM, app) {{
287-
const container = document.getElementById('app');
288-
const root = reactDOM.createRoot(container);
346+
(function render(reactDOM, app) {{
347+
const root = reactDOM.createRoot(document.getElementById('app'));
289348
root.render(app);
290-
}}(React, ReactDOM, app));
349+
}}(ReactDOM, app));
291350
</script>
292351
293-
<script>
352+
<script type="text/kepler-bootstrap">
294353
(function customize(keplerGl, store) {{
295354
var datasets = [];
296355
{dataset_js}

bindings/python/package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,29 @@
1010
},
1111
"devDependencies": {
1212
"@anywidget/types": "^0.2.0",
13-
"@types/react": "^18.2.0",
14-
"@types/react-dom": "^18.2.0",
13+
"@types/react": "^19.0.0",
14+
"@types/react-dom": "^19.0.0",
1515
"@typescript-eslint/eslint-plugin": "^7.0.0",
1616
"@typescript-eslint/parser": "^7.0.0",
1717
"esbuild": "^0.20.0",
1818
"eslint": "^8.57.0",
1919
"prettier": "^3.2.0",
20-
"typescript": "^5.4.0"
20+
"typescript": "^5.6.0"
2121
},
2222
"dependencies": {
23-
"@kepler.gl/actions": "^3.2.0",
24-
"@kepler.gl/components": "^3.2.0",
25-
"@kepler.gl/processors": "^3.2.0",
26-
"@kepler.gl/reducers": "^3.2.0",
27-
"@kepler.gl/schemas": "^3.2.0",
28-
"@kepler.gl/styles": "^3.2.0",
23+
"@kepler.gl/actions": "^3.3.0-alpha.4",
24+
"@kepler.gl/components": "^3.3.0-alpha.4",
25+
"@kepler.gl/processors": "^3.3.0-alpha.4",
26+
"@kepler.gl/reducers": "^3.3.0-alpha.4",
27+
"@kepler.gl/schemas": "^3.3.0-alpha.4",
28+
"@kepler.gl/styles": "^3.3.0-alpha.4",
2929
"apache-arrow": "^21.0.0",
3030
"assert": "^2.1.0",
3131
"events": "^3.3.0",
32-
"react": "^18.2.0",
33-
"react-dom": "^18.2.0",
34-
"react-redux": "^8.0.5",
35-
"redux": "^4.2.1",
32+
"react": "^19.0.0",
33+
"react-dom": "^19.0.0",
34+
"react-redux": "^9.1.0",
35+
"redux": "^5.0.0",
3636
"styled-components": "^6.4.3"
3737
}
3838
}

bindings/python/src/store.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// Copyright contributors to the kepler.gl project
33

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

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

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

bindings/python/tests/test_html_export.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,20 @@ def test_contains_kepler_gl_cdn_script(self, sample_df):
248248

249249
def test_default_uses_latest_stable_cdn_tag(self, sample_df):
250250
html = export_map_html(data={"test": sample_df}, config={})
251-
assert "unpkg.com/kepler.gl@3/umd/keplergl.min.js" in html
252-
assert "unpkg.com/kepler.gl@3/umd/keplergl.min.css" in html
251+
assert "unpkg.com/kepler.gl@3.3.0-alpha.4/umd/keplergl.min.js" in html
252+
assert "unpkg.com/kepler.gl@3.3.0-alpha.4/umd/keplergl.min.css" in html
253253

254254
def test_contains_react_redux_deps(self, sample_df):
255255
html = export_map_html(data={"test": sample_df}, config={})
256-
assert "react.production.min.js" in html
257-
assert "react-dom.production.min.js" in html
258-
assert "redux.js" in html
259-
assert "react-redux.min.js" in html
260-
assert "styled-components.min.js" in html
256+
# React 19 dropped UMD builds; dependencies are now loaded via an ESM
257+
# import map (es-module-shims) rather than classic <script> UMD tags.
258+
assert "esm.sh/react@" in html
259+
assert "esm.sh/react-dom@" in html
260+
assert "esm.sh/redux@" in html
261+
assert "esm.sh/react-redux@" in html
262+
assert "esm.sh/styled-components@" in html
263+
assert "importmap-shim" in html
264+
assert "es-module-shims" in html
261265

262266
def test_contains_dataset(self, sample_df):
263267
html = export_map_html(data={"my_data": sample_df}, config={})
@@ -353,7 +357,7 @@ def test_saves_file(self, sample_df, tmp_path):
353357
content = f.read()
354358
assert "<!DOCTYPE html>" in content
355359
assert "cities" in content
356-
assert "unpkg.com/kepler.gl@3/umd/keplergl.min.js" in content
360+
assert "unpkg.com/kepler.gl@3.3.0-alpha.4/umd/keplergl.min.js" in content
357361

358362
def test_saves_with_config(self, sample_df, tmp_path):
359363
config = {"version": "v1", "config": {"mapState": {"zoom": 5}}}

0 commit comments

Comments
 (0)