From 85aed438adb62c71d5fce23676e1cb6ec271018d Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Fri, 8 Mar 2024 16:07:21 -0500 Subject: [PATCH 1/9] Working RPC --- lonboard/_layer.py | 23 ++++++++++++++++++ src/dispatch.ts | 30 +++++++++++++++++++++++ src/model/base.ts | 2 +- src/model/layer.ts | 60 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/dispatch.ts diff --git a/lonboard/_layer.py b/lonboard/_layer.py index 30d83862..27439c69 100644 --- a/lonboard/_layer.py +++ b/lonboard/_layer.py @@ -16,6 +16,7 @@ Optional, Sequence, Tuple, + Union, ) import geopandas as gpd @@ -443,7 +444,29 @@ class BitmapTileLayer(BaseLayer): ``` """ + called = 0 + def __init__(self, **kwargs: BitmapTileLayerKwargs): + def _handle_anywidget_dispatch( + widget: ipywidgets.Widget, msg: Union[str, list, dict], buffers: List[bytes] + ) -> None: + self.called += 1 + print(msg) + if not isinstance(msg, dict) or msg.get("kind") != "anywidget-dispatch": + return + + print("test") + print(msg) + self.send( + { + "id": msg["id"], + "kind": "anywidget-dispatch-response", + "response": "hello world", + } + ) + + print("before on msg") + self.on_msg(_handle_anywidget_dispatch) super().__init__(**kwargs) # type: ignore _layer_type = traitlets.Unicode("bitmap-tile").tag(sync=True) diff --git a/src/dispatch.ts b/src/dispatch.ts new file mode 100644 index 00000000..4711113c --- /dev/null +++ b/src/dispatch.ts @@ -0,0 +1,30 @@ +import { AnyModel } from "@anywidget/types"; + +type Message = { + id: string; + kind: "anywidget-dispatch-response"; + response: T; +}; + +export function dispatch( + model: AnyModel, + action: any, + { timeout = 3000 } = {}, +) { + let id = Date.now().toString(36); + return new Promise((resolve, reject) => { + let timer = setTimeout(() => { + reject(new Error(`Promise timed out after ${timeout} ms`)); + model.off("msg:custom", handler); + }, timeout); + + function handler(msg: Message, buffers: DataView[]) { + if (!(msg.id === id)) return; + clearTimeout(timer); + resolve([msg.response, buffers]); + model.off("msg:custom", handler); + } + model.on("msg:custom", handler); + model.send({ id, kind: "anywidget-dispatch", action }); + }); +} diff --git a/src/model/base.ts b/src/model/base.ts index f7f9da2c..c2cb6134 100644 --- a/src/model/base.ts +++ b/src/model/base.ts @@ -4,7 +4,7 @@ import { parseAccessor } from "../accessor.js"; import type { WidgetModel } from "@jupyter-widgets/base"; export abstract class BaseModel { - protected model: WidgetModel; + model: WidgetModel; protected callbacks: Map void>; protected updateStateCallback: () => void; diff --git a/src/model/layer.ts b/src/model/layer.ts index 0ab3c02e..422e594f 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -23,6 +23,7 @@ import { BaseLayerModel } from "./base-layer.js"; import { BitmapLayer, BitmapLayerProps } from "@deck.gl/layers/typed"; import { TileLayer, TileLayerProps } from "@deck.gl/geo-layers/typed"; import { isDefined } from "../util.js"; +import { dispatch } from "../dispatch.js"; /** * An abstract base class for a layer that uses an Arrow Table as the data prop. @@ -172,6 +173,37 @@ export class BitmapModel extends BaseLayerModel { } } +export type ZRange = [minZ: number, maxZ: number]; + +export type Bounds = [minX: number, minY: number, maxX: number, maxY: number]; + +export type GeoBoundingBox = { + west: number; + north: number; + east: number; + south: number; +}; +export type NonGeoBoundingBox = { + left: number; + top: number; + right: number; + bottom: number; +}; + +export type TileBoundingBox = NonGeoBoundingBox | GeoBoundingBox; + +export type TileIndex = { x: number; y: number; z: number }; + +export type TileLoadProps = { + index: TileIndex; + id: string; + bbox: TileBoundingBox; + url?: string | null; + signal?: AbortSignal; + userData?: Record; + zoom?: number; +}; + export class BitmapTileModel extends BaseLayerModel { static layerType = "bitmap-tile"; @@ -238,11 +270,37 @@ export class BitmapTileModel extends BaseLayerModel { }; } + async getTileData(tile: TileLoadProps) { + // const { data, getTileData, fetch } = this.props; + const { signal } = tile; + + console.log(tile); + console.log("making dispatch"); + console.log("this"); + console.log(this); + const x = await dispatch(this.model, "getTileData"); + console.log("received dispatch"); + console.log(x); + + // // tile.url = + // // typeof data === "string" || Array.isArray(data) + // // ? getURLFromTemplate(data, tile) + // // : null; + + // if (getTileData) { + // return getTileData(tile); + // } + // if (fetch && tile.url) { + // return fetch(tile.url, { propName: "data", layer: this, signal }); + // } + return null; + } + render(): TileLayer { return new TileLayer({ ...this.baseLayerProps(), ...this.layerProps(), - + getTileData: this.getTileData.bind(this), renderSubLayers: (props) => { const [min, max] = props.tile.boundingBox; From 032864719d531ff056fc71a6a488b5832ae28934 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 15:59:20 -0400 Subject: [PATCH 2/9] Pass down anywidgetExperimental --- package-lock.json | 156 ++++++++++++++++++++++----------------------- src/index.tsx | 17 ++++- src/model/layer.ts | 29 +++++++-- 3 files changed, 117 insertions(+), 85 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5da25ec1..c500b178 100644 --- a/package-lock.json +++ b/package-lock.json @@ -143,9 +143,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-4.2.1.tgz", - "integrity": "sha512-CEypeeykO9AN7JWkr1OEOQb0HRzZlPWGwV0Ya6DuVgFdDi6g3ma/cPZ5ZPZM4AWQikDpq/0llnGGlIL+j8afzw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", + "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", "dev": true, "funding": [ { @@ -158,7 +158,7 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" } }, "node_modules/@csstools/css-calc": { @@ -185,9 +185,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.0.tgz", - "integrity": "sha512-F/A1Z3ZXH4fU6+29Up4QAZtewLmWLI4hVz6hyODMFvorx4AEC/03tu+gFq0nMZSDafC0lmapNOj9f4ctHMNaqQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.1.tgz", + "integrity": "sha512-++7I+Z7S/BWedPlR4z8aW1zsvtJFufFbpdPwdx5+W50dq5EYLV3sulitSNMry0BNmNMzeczdQij/f4C+ch01vQ==", "dev": true, "funding": [ { @@ -200,7 +200,7 @@ } ], "dependencies": { - "@csstools/color-helpers": "^4.2.1", + "@csstools/color-helpers": "^5.0.1", "@csstools/css-calc": "^2.0.0" }, "engines": { @@ -302,9 +302,9 @@ } }, "node_modules/@csstools/postcss-color-function": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.0.tgz", - "integrity": "sha512-e0RohXUxMsSzIS5s4xh218NiOYXAfby17L8KYe/6ITI8i4BiSFLpywMvpA/d6xPUGUfT20O+7JLBDHF3heYZRA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.1.tgz", + "integrity": "sha512-nRnwVdqdMUIsE7cGbI+La4fxME6tT9bVDRYfBHW/0QTLwCVJN4+DC/3kqiU6AdTne31hUBGPwcH1uzkuc4fO5A==", "dev": true, "funding": [ { @@ -317,7 +317,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -331,9 +331,9 @@ } }, "node_modules/@csstools/postcss-color-mix-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.0.tgz", - "integrity": "sha512-MWuSfaLKe1By/hSnjH/Hj7ZOIRZaLMNshCTkVuuqtZ0nfp+QRGUwf9nb2uPVKySYjKqNERANdA9Q0citA9hK1Q==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.1.tgz", + "integrity": "sha512-RRdu3CppF9dTn3AvDkeEkOL8ZDpDh/TF6YLV1JKl768BQk0XJ026xWfttoL911k0g8yprES3wFujjLsK0XhsEg==", "dev": true, "funding": [ { @@ -346,7 +346,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -441,9 +441,9 @@ } }, "node_modules/@csstools/postcss-gamut-mapping": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.0.tgz", - "integrity": "sha512-JftxHVGt6PFfV/vWTDVKrrO0XyUA8OtuVykXhhMxue9qCzCCTSWqMHjZOvaOCCbxG1v2tGKV2FxBLQhzsZZPJg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.1.tgz", + "integrity": "sha512-bCQ609PZsGUmrTVeGaPgYF27DFQ7gg2no3j6qXY3MOAVjfPRvMIlGdpLejhgYra1VUoTNA1SUqHLNgFWoJ/pRA==", "dev": true, "funding": [ { @@ -456,7 +456,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0" }, @@ -468,9 +468,9 @@ } }, "node_modules/@csstools/postcss-gradients-interpolation-method": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.0.tgz", - "integrity": "sha512-jmgh7C6ANVRPdFNMNIp426UFNuy01XXYwxbbyYV2fZBbmZleVLp6imxjw2XoaeHMdSiYoq8vOeX+GVzCyC7oOQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.1.tgz", + "integrity": "sha512-ZINUsXxFrJ5bpfpq772BQzu5K23dDFoQwvyeQRHHQpDOS8hMIoBMmjDjtZV5fGJ/gtL/blKUvytAyrgBzaqvUQ==", "dev": true, "funding": [ { @@ -483,7 +483,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -497,9 +497,9 @@ } }, "node_modules/@csstools/postcss-hwb-function": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.0.tgz", - "integrity": "sha512-Swb2CK/wKnsXEgT5GNlIO2C2h3lePn0Nmbsy48Z6yAht1XwQiDcxDAhqojg9LfonJVics+pzLM+IEQjPdgICNg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.1.tgz", + "integrity": "sha512-1SluTV2F2WiWPw5CHQ/UOsUrO5y89VDQlOICzHIF3Mx50YdTf0qYZ/dTXL/Fa+1AgzSn4IYt51XXjgxI7pe/jw==", "dev": true, "funding": [ { @@ -512,7 +512,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -601,9 +601,9 @@ } }, "node_modules/@csstools/postcss-light-dark-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.0.tgz", - "integrity": "sha512-1CHfwwckSJ4xYZYOgJD5u1NNlP85/6VqsQPL1geagvfpwm47hcGRDW+O3CD7KdexWGL45E5qKmL1bC2siqjmkg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.1.tgz", + "integrity": "sha512-RHliBdalIg7KZNwv5B1VwF1qFEhmz3ZIbZXyxOH1g7W72S0oazMKIvYVgHenCxHCxWOxSR0ipZ+8kHa+fm4O5A==", "dev": true, "funding": [ { @@ -852,9 +852,9 @@ } }, "node_modules/@csstools/postcss-oklab-function": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.0.tgz", - "integrity": "sha512-4dwot1KLiFRFbYZV2XeeNoXQETK/3MaNCi4BpDlJ5J4XHF+VRwcppfCcqCC+TRucWanPFFlbt+X53nIuK7JVNg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.1.tgz", + "integrity": "sha512-hEJ83YhqNII3/TBGcJLjSkNx65p4Zbz6YFm6ww2BRRO223/GTFOHT2ElicWmnBtoZWKORgysI4wtLv3p6LZSFQ==", "dev": true, "funding": [ { @@ -867,7 +867,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -906,9 +906,9 @@ } }, "node_modules/@csstools/postcss-relative-color-syntax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.0.tgz", - "integrity": "sha512-iE/mgtuUeFMpMJhhrze9pu5xSEaueCTijs7lTnJ6MoTL50H9fquQp3bFVd2haAb/fDhO/nXTu67tzsm+zXsFzA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.1.tgz", + "integrity": "sha512-GbcQPmfBOjKomHuOVB6troujQg65ykCMt4OGot75Bdev7jAHC9hd0AX5qMprpG9AF0dA012curAVqY0ehmdYwQ==", "dev": true, "funding": [ { @@ -921,7 +921,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -987,9 +987,9 @@ } }, "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.0.tgz", - "integrity": "sha512-vyJpbr2emWy8AOmBT+41LcAaaS8Q3jOMiMZRzrdV8uZgKI1I0NiB+UM7vJuwkFPhC3oXl7XPIPtajsyEAvI3kw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.1.tgz", + "integrity": "sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw==", "dev": true, "funding": [ { @@ -1002,7 +1002,7 @@ } ], "dependencies": { - "@csstools/color-helpers": "^4.2.1", + "@csstools/color-helpers": "^5.0.1", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -6279,12 +6279,12 @@ } }, "node_modules/@types/node": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", - "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", "peer": true, "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.18.2" } }, "node_modules/@types/offscreencanvas": { @@ -7828,9 +7828,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.6.tgz", - "integrity": "sha512-jwXWsM5RPf6j9dPYzaorcBSUg6AiqocPEyMpkchkvntaH9HGfOOMZwxMJjDY/XEs3T5dM7uyH1VhRMkqUU9qVw==", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.7.tgz", + "integrity": "sha512-6FTNWIWMxMy/ZY6799nBlPtF1DFDQ6VQJ7yyDP27SJNt5lwtQ5ufqVvHylb3fdQefvRcgA3fKcFMJi9OLwBRNw==", "dev": true }, "node_modules/emoji-regex": { @@ -8584,9 +8584,9 @@ } }, "node_modules/framer-motion": { - "version": "11.3.24", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.24.tgz", - "integrity": "sha512-kl0YI7HwAtyV0VOAWuU/rXoOS8+z5qSkMN6rZS+a9oe6fIha6SC3vjJN6u/hBpvjrg5MQNdSnqnjYxm0WYTX9g==", + "version": "11.3.27", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.27.tgz", + "integrity": "sha512-Uf72PFEZuei/1IeCmGJ236EIl6VUri7SLovtTGg/cOAzMHG01CXXg1aL3ofuTuYr6Sq1QALlcEDaTig0PXb4Dw==", "dependencies": { "tslib": "^2.4.0" }, @@ -10666,9 +10666,9 @@ } }, "node_modules/postcss-color-functional-notation": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.0.tgz", - "integrity": "sha512-WjOCE1FJb2xIeFvF40CISn9yUMtzwkgjdbjXmWjbrC1wAgQiB763h7bsip9piGtAkbeM5Pi9hVIDSmtbWrlqLw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.1.tgz", + "integrity": "sha512-8/wf01pTH3XHT37wre+E2GNcsttZ62PWSJ0DE66GO+Uzk+uyr9DH+V3cdJG+BqezCD/T5lBC1s5/t7Y12ps8QQ==", "dev": true, "funding": [ { @@ -10681,7 +10681,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -11025,9 +11025,9 @@ } }, "node_modules/postcss-lab-function": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.0.tgz", - "integrity": "sha512-Qyrlog4fAJcbwiWHiwkpDLlSRnvk2dFYqygQ29sMbhCoq6B/Jtj89u89VFNaAatW8KkDDAeNzVvabK9NBD9hJA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.1.tgz", + "integrity": "sha512-G9ecsdU+TtdHJvaTrfbIyOa3iHHJMZXdvsLXJSN8IP4cfg3XraozacAt6P7xzaILIC3XPGMM149oKhf2tjPubg==", "dev": true, "funding": [ { @@ -11040,7 +11040,7 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^3.0.0", + "@csstools/css-color-parser": "^3.0.1", "@csstools/css-parser-algorithms": "^3.0.0", "@csstools/css-tokenizer": "^3.0.0", "@csstools/postcss-progressive-custom-properties": "^4.0.0", @@ -11334,9 +11334,9 @@ } }, "node_modules/postcss-preset-env": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.0.0.tgz", - "integrity": "sha512-zoLkIGK30hkLhHVD6jNqcO6gDVDzyo10s42XG++Gsy9z6gk1X/UpI2Zn28ylGD9VnQSSdQMzuk535rRq2JmWkg==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.0.1.tgz", + "integrity": "sha512-I8m4pBJWcUmPLu1z8HySEiAROKIMA0nwUYCGr1gJOGFP9BdwPWPBSYvA2KGH0VjUZ8AAAvwwXXWnxHTWq3f7UQ==", "dev": true, "funding": [ { @@ -11350,18 +11350,18 @@ ], "dependencies": { "@csstools/postcss-cascade-layers": "^5.0.0", - "@csstools/postcss-color-function": "^4.0.0", - "@csstools/postcss-color-mix-function": "^3.0.0", + "@csstools/postcss-color-function": "^4.0.1", + "@csstools/postcss-color-mix-function": "^3.0.1", "@csstools/postcss-content-alt-text": "^2.0.0", "@csstools/postcss-exponential-functions": "^2.0.0", "@csstools/postcss-font-format-keywords": "^4.0.0", - "@csstools/postcss-gamut-mapping": "^2.0.0", - "@csstools/postcss-gradients-interpolation-method": "^5.0.0", - "@csstools/postcss-hwb-function": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.1", + "@csstools/postcss-gradients-interpolation-method": "^5.0.1", + "@csstools/postcss-hwb-function": "^4.0.1", "@csstools/postcss-ic-unit": "^4.0.0", "@csstools/postcss-initial": "^2.0.0", "@csstools/postcss-is-pseudo-class": "^5.0.0", - "@csstools/postcss-light-dark-function": "^2.0.0", + "@csstools/postcss-light-dark-function": "^2.0.1", "@csstools/postcss-logical-float-and-clear": "^3.0.0", "@csstools/postcss-logical-overflow": "^2.0.0", "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", @@ -11371,12 +11371,12 @@ "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.0", "@csstools/postcss-nested-calc": "^4.0.0", "@csstools/postcss-normalize-display-values": "^4.0.0", - "@csstools/postcss-oklab-function": "^4.0.0", + "@csstools/postcss-oklab-function": "^4.0.1", "@csstools/postcss-progressive-custom-properties": "^4.0.0", - "@csstools/postcss-relative-color-syntax": "^3.0.0", + "@csstools/postcss-relative-color-syntax": "^3.0.1", "@csstools/postcss-scope-pseudo-class": "^4.0.0", "@csstools/postcss-stepped-value-functions": "^4.0.0", - "@csstools/postcss-text-decoration-shorthand": "^4.0.0", + "@csstools/postcss-text-decoration-shorthand": "^4.0.1", "@csstools/postcss-trigonometric-functions": "^4.0.0", "@csstools/postcss-unset-value": "^4.0.0", "autoprefixer": "^10.4.19", @@ -11387,7 +11387,7 @@ "cssdb": "^8.1.0", "postcss-attribute-case-insensitive": "^7.0.0", "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^7.0.0", + "postcss-color-functional-notation": "^7.0.1", "postcss-color-hex-alpha": "^10.0.0", "postcss-color-rebeccapurple": "^10.0.0", "postcss-custom-media": "^11.0.0", @@ -11400,7 +11400,7 @@ "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^6.0.0", "postcss-image-set-function": "^7.0.0", - "postcss-lab-function": "^7.0.0", + "postcss-lab-function": "^7.0.1", "postcss-logical": "^8.0.0", "postcss-nesting": "^13.0.0", "postcss-opacity-percentage": "^2.0.0", @@ -13329,9 +13329,9 @@ "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==" }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==", "peer": true }, "node_modules/union-value": { diff --git a/src/index.tsx b/src/index.tsx index bb40d914..eb308108 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,12 @@ import * as React from "react"; import { useEffect, useCallback, useState } from "react"; -import { createRender, useModelState, useModel } from "@anywidget/react"; -import type { Initialize, Render } from "@anywidget/types"; +import { + createRender, + useModelState, + useModel, + useExperimental, +} from "@anywidget/react"; +import type { Experimental, Initialize, Render } from "@anywidget/types"; import Map from "react-map-gl/maplibre"; import DeckGL from "@deck.gl/react"; import { MapViewState, PickingInfo, type Layer } from "@deck.gl/core"; @@ -42,6 +47,7 @@ async function getChildModelState( childLayerIds: string[], previousSubModelState: Record, setStateCounter: React.Dispatch>, + anywidgetExperimental: Experimental, ): Promise> { const newSubModelState: Record = {}; const updateStateCallback = () => setStateCounter(new Date()); @@ -59,7 +65,10 @@ async function getChildModelState( continue; } - const childLayer = await initializeLayer(childModel, updateStateCallback); + const childLayer = await initializeLayer(childModel, { + updateStateCallback, + anywidgetExperimental, + }); newSubModelState[childLayerId] = childLayer; } @@ -103,6 +112,7 @@ function App() { ); const [parameters] = useModelState("parameters"); const [customAttribution] = useModelState("custom_attribution"); + const anywidgetExperimental = useExperimental(); // initialViewState is the value of view_state on the Python side. This is // called `initial` here because it gets passed in to deck's @@ -152,6 +162,7 @@ function App() { childLayerIds, subModelState, setStateCounter, + anywidgetExperimental, ); setSubModelState(newSubModelState); diff --git a/src/model/layer.ts b/src/model/layer.ts index bf9af876..e8a46b63 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -28,6 +28,7 @@ import { BitmapLayer, BitmapLayerProps } from "@deck.gl/layers"; import { TileLayer, TileLayerProps } from "@deck.gl/geo-layers"; import { isDefined } from "../util.js"; import { dispatch } from "../dispatch.js"; +import { Experimental } from "@anywidget/types"; /** * An abstract base class for a layer that uses an Arrow Table as the data prop. @@ -226,7 +227,13 @@ export class BitmapTileModel extends BaseLayerModel { protected transparentColor: BitmapLayerProps["transparentColor"]; protected tintColor: BitmapLayerProps["tintColor"]; - constructor(model: WidgetModel, updateStateCallback: () => void) { + protected anywidgetExperimental: Experimental; + + constructor( + model: WidgetModel, + updateStateCallback: () => void, + anywidgetExperimental: Experimental, + ) { super(model, updateStateCallback); this.initRegularAttribute("data", "data"); @@ -243,6 +250,8 @@ export class BitmapTileModel extends BaseLayerModel { this.initRegularAttribute("desaturate", "desaturate"); this.initRegularAttribute("transparent_color", "transparentColor"); this.initRegularAttribute("tint_color", "tintColor"); + + this.anywidgetExperimental = anywidgetExperimental; } bitmapLayerProps(): Omit { @@ -275,8 +284,13 @@ export class BitmapTileModel extends BaseLayerModel { } async getTileData(tile: TileLoadProps) { + const { invoke } = this.anywidgetExperimental; + console.log(invoke); + const out = await invoke("helloworld"); + console.log(out); + // const { data, getTileData, fetch } = this.props; - const { signal } = tile; + // const { signal } = tile; console.log(tile); console.log("making dispatch"); @@ -962,7 +976,10 @@ export class TextModel extends BaseArrowLayerModel { export async function initializeLayer( model: WidgetModel, - updateStateCallback: () => void, + { + updateStateCallback, + anywidgetExperimental, + }: { updateStateCallback: () => void; anywidgetExperimental: Experimental }, ): Promise { const layerType = model.get("_layer_type"); let layerModel: BaseLayerModel; @@ -976,7 +993,11 @@ export async function initializeLayer( break; case BitmapTileModel.layerType: - layerModel = new BitmapTileModel(model, updateStateCallback); + layerModel = new BitmapTileModel( + model, + updateStateCallback, + anywidgetExperimental, + ); break; case ColumnModel.layerType: From a8d267ade547c2c04d35a26547ca0dc90ecfd13a Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 16:07:40 -0400 Subject: [PATCH 3/9] try to call hello world --- lonboard/_layer.py | 5 +++++ lonboard/_map.py | 5 +++++ poetry.lock | 2 +- src/model/layer.ts | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lonboard/_layer.py b/lonboard/_layer.py index 0cfa30e8..1df4961f 100644 --- a/lonboard/_layer.py +++ b/lonboard/_layer.py @@ -21,6 +21,7 @@ Union, ) +import anywidget import ipywidgets import traitlets from arro3.core import Table @@ -538,6 +539,10 @@ def _handle_anywidget_dispatch( self.on_msg(_handle_anywidget_dispatch) super().__init__(**kwargs) # type: ignore + @anywidget.experimental.command + def helloworld(self, msg, buffers): + return "hello world", buffers + _layer_type = traitlets.Unicode("bitmap-tile").tag(sync=True) data = traitlets.Union( diff --git a/lonboard/_map.py b/lonboard/_map.py index a18318cd..d52c5214 100644 --- a/lonboard/_map.py +++ b/lonboard/_map.py @@ -5,6 +5,7 @@ from pathlib import Path from typing import IO, TYPE_CHECKING, Optional, Sequence, TextIO, Union, overload +import anywidget import ipywidgets import traitlets from ipywidgets.embed import embed_minimal_html @@ -96,6 +97,10 @@ def __init__( super().__init__(layers=layers, **kwargs) + @anywidget.experimental.command + def helloworld(self, msg, buffers): + return "hello world from top-level map component", buffers + _esm = bundler_output_dir / "index.js" _css = bundler_output_dir / "index.css" diff --git a/poetry.lock b/poetry.lock index beb61edf..aa52232f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2721,8 +2721,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" diff --git a/src/model/layer.ts b/src/model/layer.ts index e8a46b63..b60ab155 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -284,9 +284,13 @@ export class BitmapTileModel extends BaseLayerModel { } async getTileData(tile: TileLoadProps) { + console.log("in getTileData"); const { invoke } = this.anywidgetExperimental; + console.log(invoke); + console.log("calling invoke"); const out = await invoke("helloworld"); + console.log("returned from invoke"); console.log(out); // const { data, getTileData, fetch } = this.props; From 6091dc56b2c6006c140891fb685ff562f9b160ae Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 16:34:25 -0400 Subject: [PATCH 4/9] Don't use anywidget command directly --- lonboard/_layer.py | 18 +++++++-------- lonboard/_map.py | 5 ----- src/model/invoke.ts | 53 +++++++++++++++++++++++++++++++++++++++++++++ src/model/layer.ts | 5 +++-- 4 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 src/model/invoke.ts diff --git a/lonboard/_layer.py b/lonboard/_layer.py index 1df4961f..42bc8542 100644 --- a/lonboard/_layer.py +++ b/lonboard/_layer.py @@ -21,7 +21,6 @@ Union, ) -import anywidget import ipywidgets import traitlets from arro3.core import Table @@ -522,27 +521,28 @@ def _handle_anywidget_dispatch( ) -> None: self.called += 1 print(msg) - if not isinstance(msg, dict) or msg.get("kind") != "anywidget-dispatch": + + if not isinstance(msg, dict) or msg.get("kind") != "anywidget-command": return print("test") print(msg) + + response = "helloworld from init" + buffers = [b"hello world"] self.send( { "id": msg["id"], - "kind": "anywidget-dispatch-response", - "response": "hello world", - } + "kind": "anywidget-command-response", + "response": response, + }, + buffers, ) print("before on msg") self.on_msg(_handle_anywidget_dispatch) super().__init__(**kwargs) # type: ignore - @anywidget.experimental.command - def helloworld(self, msg, buffers): - return "hello world", buffers - _layer_type = traitlets.Unicode("bitmap-tile").tag(sync=True) data = traitlets.Union( diff --git a/lonboard/_map.py b/lonboard/_map.py index d52c5214..a18318cd 100644 --- a/lonboard/_map.py +++ b/lonboard/_map.py @@ -5,7 +5,6 @@ from pathlib import Path from typing import IO, TYPE_CHECKING, Optional, Sequence, TextIO, Union, overload -import anywidget import ipywidgets import traitlets from ipywidgets.embed import embed_minimal_html @@ -97,10 +96,6 @@ def __init__( super().__init__(layers=layers, **kwargs) - @anywidget.experimental.command - def helloworld(self, msg, buffers): - return "hello world from top-level map component", buffers - _esm = bundler_output_dir / "index.js" _css = bundler_output_dir / "index.css" diff --git a/src/model/invoke.ts b/src/model/invoke.ts new file mode 100644 index 00000000..2cce1f4d --- /dev/null +++ b/src/model/invoke.ts @@ -0,0 +1,53 @@ +// Invoke is vendored from anywidget because we want to ensure we're using the +// widget messages on the **specific** widget layer, not the top-level Map +// layer. E.g. when the JS BitmapTileLayer is requesting tiles, we want to make +// sure that the same, specific BitmapTileLayer on the Python side is receiving +// the requests. +// +// For now, it's simplest to vendor this code and implement our own responses on +// the Python side. + +import { AnyModel } from "@anywidget/types"; +import { v4 } from "uuid"; + +type InvokeOptions = { + buffers?: DataView[]; + signal?: AbortSignal; +}; + +export async function invoke( + model: AnyModel, + name: string, + msg: object, + options: InvokeOptions = {}, +): Promise<[T, DataView[]]> { + // crypto.randomUUID() is not available in non-secure contexts (i.e., http://) + // so we use simple (non-secure) polyfill. + const id = v4(); + const signal = options.signal ?? AbortSignal.timeout(3000); + + return new Promise((resolve, reject) => { + if (signal.aborted) { + reject(signal.reason); + } + signal.addEventListener("abort", () => { + model.off("msg:custom", handler); + reject(signal.reason); + }); + + function handler( + msg: { id: string; kind: "anywidget-command-response"; response: T }, + buffers: DataView[], + ) { + if (!(msg.id === id)) return; + resolve([msg.response, buffers]); + model.off("msg:custom", handler); + } + model.on("msg:custom", handler); + model.send( + { id, kind: "anywidget-command", name, msg }, + undefined, + options.buffers ?? [], + ); + }); +} diff --git a/src/model/layer.ts b/src/model/layer.ts index b60ab155..c59de6b4 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -29,6 +29,7 @@ import { TileLayer, TileLayerProps } from "@deck.gl/geo-layers"; import { isDefined } from "../util.js"; import { dispatch } from "../dispatch.js"; import { Experimental } from "@anywidget/types"; +import { invoke } from "./invoke.js"; /** * An abstract base class for a layer that uses an Arrow Table as the data prop. @@ -285,11 +286,11 @@ export class BitmapTileModel extends BaseLayerModel { async getTileData(tile: TileLoadProps) { console.log("in getTileData"); - const { invoke } = this.anywidgetExperimental; + // const { invoke } = this.anywidgetExperimental; console.log(invoke); console.log("calling invoke"); - const out = await invoke("helloworld"); + const out = await invoke(this.model, "helloworld", {}); console.log("returned from invoke"); console.log(out); From e04727bfa3a21e58602b526bd36198db7e420977 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 16:40:25 -0400 Subject: [PATCH 5/9] Remove dispatch code --- src/dispatch.ts | 30 ------------------------------ src/model/layer.ts | 12 ++---------- 2 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 src/dispatch.ts diff --git a/src/dispatch.ts b/src/dispatch.ts deleted file mode 100644 index 4711113c..00000000 --- a/src/dispatch.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { AnyModel } from "@anywidget/types"; - -type Message = { - id: string; - kind: "anywidget-dispatch-response"; - response: T; -}; - -export function dispatch( - model: AnyModel, - action: any, - { timeout = 3000 } = {}, -) { - let id = Date.now().toString(36); - return new Promise((resolve, reject) => { - let timer = setTimeout(() => { - reject(new Error(`Promise timed out after ${timeout} ms`)); - model.off("msg:custom", handler); - }, timeout); - - function handler(msg: Message, buffers: DataView[]) { - if (!(msg.id === id)) return; - clearTimeout(timer); - resolve([msg.response, buffers]); - model.off("msg:custom", handler); - } - model.on("msg:custom", handler); - model.send({ id, kind: "anywidget-dispatch", action }); - }); -} diff --git a/src/model/layer.ts b/src/model/layer.ts index c59de6b4..9267a5bd 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -27,7 +27,6 @@ import { BaseLayerModel } from "./base-layer.js"; import { BitmapLayer, BitmapLayerProps } from "@deck.gl/layers"; import { TileLayer, TileLayerProps } from "@deck.gl/geo-layers"; import { isDefined } from "../util.js"; -import { dispatch } from "../dispatch.js"; import { Experimental } from "@anywidget/types"; import { invoke } from "./invoke.js"; @@ -206,7 +205,7 @@ export type TileLoadProps = { bbox: TileBoundingBox; url?: string | null; signal?: AbortSignal; - userData?: Record; + userData?: Record; // eslint-disable-line @typescript-eslint/no-explicit-any zoom?: number; }; @@ -293,18 +292,11 @@ export class BitmapTileModel extends BaseLayerModel { const out = await invoke(this.model, "helloworld", {}); console.log("returned from invoke"); console.log(out); + console.log(tile); // const { data, getTileData, fetch } = this.props; // const { signal } = tile; - console.log(tile); - console.log("making dispatch"); - console.log("this"); - console.log(this); - const x = await dispatch(this.model, "getTileData"); - console.log("received dispatch"); - console.log(x); - // // tile.url = // // typeof data === "string" || Array.isArray(data) // // ? getURLFromTemplate(data, tile) From efea59ddfd0d2e10eca0214970fe565ae549fb8d Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 16:42:55 -0400 Subject: [PATCH 6/9] Remove anywidget experimental --- src/index.tsx | 17 +++-------------- src/model/layer.ts | 22 +++------------------- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index eb308108..bb40d914 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,12 +1,7 @@ import * as React from "react"; import { useEffect, useCallback, useState } from "react"; -import { - createRender, - useModelState, - useModel, - useExperimental, -} from "@anywidget/react"; -import type { Experimental, Initialize, Render } from "@anywidget/types"; +import { createRender, useModelState, useModel } from "@anywidget/react"; +import type { Initialize, Render } from "@anywidget/types"; import Map from "react-map-gl/maplibre"; import DeckGL from "@deck.gl/react"; import { MapViewState, PickingInfo, type Layer } from "@deck.gl/core"; @@ -47,7 +42,6 @@ async function getChildModelState( childLayerIds: string[], previousSubModelState: Record, setStateCounter: React.Dispatch>, - anywidgetExperimental: Experimental, ): Promise> { const newSubModelState: Record = {}; const updateStateCallback = () => setStateCounter(new Date()); @@ -65,10 +59,7 @@ async function getChildModelState( continue; } - const childLayer = await initializeLayer(childModel, { - updateStateCallback, - anywidgetExperimental, - }); + const childLayer = await initializeLayer(childModel, updateStateCallback); newSubModelState[childLayerId] = childLayer; } @@ -112,7 +103,6 @@ function App() { ); const [parameters] = useModelState("parameters"); const [customAttribution] = useModelState("custom_attribution"); - const anywidgetExperimental = useExperimental(); // initialViewState is the value of view_state on the Python side. This is // called `initial` here because it gets passed in to deck's @@ -162,7 +152,6 @@ function App() { childLayerIds, subModelState, setStateCounter, - anywidgetExperimental, ); setSubModelState(newSubModelState); diff --git a/src/model/layer.ts b/src/model/layer.ts index 9267a5bd..7fc5aa55 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -27,7 +27,6 @@ import { BaseLayerModel } from "./base-layer.js"; import { BitmapLayer, BitmapLayerProps } from "@deck.gl/layers"; import { TileLayer, TileLayerProps } from "@deck.gl/geo-layers"; import { isDefined } from "../util.js"; -import { Experimental } from "@anywidget/types"; import { invoke } from "./invoke.js"; /** @@ -227,13 +226,7 @@ export class BitmapTileModel extends BaseLayerModel { protected transparentColor: BitmapLayerProps["transparentColor"]; protected tintColor: BitmapLayerProps["tintColor"]; - protected anywidgetExperimental: Experimental; - - constructor( - model: WidgetModel, - updateStateCallback: () => void, - anywidgetExperimental: Experimental, - ) { + constructor(model: WidgetModel, updateStateCallback: () => void) { super(model, updateStateCallback); this.initRegularAttribute("data", "data"); @@ -250,8 +243,6 @@ export class BitmapTileModel extends BaseLayerModel { this.initRegularAttribute("desaturate", "desaturate"); this.initRegularAttribute("transparent_color", "transparentColor"); this.initRegularAttribute("tint_color", "tintColor"); - - this.anywidgetExperimental = anywidgetExperimental; } bitmapLayerProps(): Omit { @@ -973,10 +964,7 @@ export class TextModel extends BaseArrowLayerModel { export async function initializeLayer( model: WidgetModel, - { - updateStateCallback, - anywidgetExperimental, - }: { updateStateCallback: () => void; anywidgetExperimental: Experimental }, + updateStateCallback: () => void, ): Promise { const layerType = model.get("_layer_type"); let layerModel: BaseLayerModel; @@ -990,11 +978,7 @@ export async function initializeLayer( break; case BitmapTileModel.layerType: - layerModel = new BitmapTileModel( - model, - updateStateCallback, - anywidgetExperimental, - ); + layerModel = new BitmapTileModel(model, updateStateCallback); break; case ColumnModel.layerType: From 2daac4b87dc97995f35d51b5057702ea71ecfba5 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 16:46:58 -0400 Subject: [PATCH 7/9] remove vendored types --- src/model/layer.ts | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/model/layer.ts b/src/model/layer.ts index 7fc5aa55..244e16ce 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -177,37 +177,6 @@ export class BitmapModel extends BaseLayerModel { } } -export type ZRange = [minZ: number, maxZ: number]; - -export type Bounds = [minX: number, minY: number, maxX: number, maxY: number]; - -export type GeoBoundingBox = { - west: number; - north: number; - east: number; - south: number; -}; -export type NonGeoBoundingBox = { - left: number; - top: number; - right: number; - bottom: number; -}; - -export type TileBoundingBox = NonGeoBoundingBox | GeoBoundingBox; - -export type TileIndex = { x: number; y: number; z: number }; - -export type TileLoadProps = { - index: TileIndex; - id: string; - bbox: TileBoundingBox; - url?: string | null; - signal?: AbortSignal; - userData?: Record; // eslint-disable-line @typescript-eslint/no-explicit-any - zoom?: number; -}; - export class BitmapTileModel extends BaseLayerModel { static layerType = "bitmap-tile"; @@ -274,7 +243,8 @@ export class BitmapTileModel extends BaseLayerModel { }; } - async getTileData(tile: TileLoadProps) { + // Alternate function form so that we can assign the upstream getTileData type + getTileData: TileLayerProps["getTileData"] = async (tile) => { console.log("in getTileData"); // const { invoke } = this.anywidgetExperimental; @@ -300,13 +270,13 @@ export class BitmapTileModel extends BaseLayerModel { // return fetch(tile.url, { propName: "data", layer: this, signal }); // } return null; - } + }; render(): TileLayer { return new TileLayer({ ...this.baseLayerProps(), ...this.layerProps(), - getTileData: this.getTileData.bind(this), + getTileData: this.getTileData?.bind(this), renderSubLayers: (props) => { const [min, max] = props.tile.boundingBox; From 8bcc1bbca0942111be9ed68dde37f21deb4ca698 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 16:53:38 -0400 Subject: [PATCH 8/9] Move file --- lonboard/_layer/__init__.py | 13 +++++++++++++ lonboard/{_layer.py => _layer/core.py} | 0 2 files changed, 13 insertions(+) create mode 100644 lonboard/_layer/__init__.py rename lonboard/{_layer.py => _layer/core.py} (100%) diff --git a/lonboard/_layer/__init__.py b/lonboard/_layer/__init__.py new file mode 100644 index 00000000..b4141fd1 --- /dev/null +++ b/lonboard/_layer/__init__.py @@ -0,0 +1,13 @@ +from .core import ( + BaseArrowLayer, + BaseLayer, + BitmapLayer, + BitmapTileLayer, + ColumnLayer, + HeatmapLayer, + PathLayer, + PointCloudLayer, + PolygonLayer, + ScatterplotLayer, + SolidPolygonLayer, +) diff --git a/lonboard/_layer.py b/lonboard/_layer/core.py similarity index 100% rename from lonboard/_layer.py rename to lonboard/_layer/core.py From 601b770ad74b25993b355f42169267c6de131731 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Wed, 14 Aug 2024 18:37:59 -0400 Subject: [PATCH 9/9] Working RioTilerLayer --- lonboard/_layer/core.py | 8 +- lonboard/_layer/rasterio_layer.py | 105 ++++++++ poetry.lock | 405 +++++++++++++++++++++++++++++- pyproject.toml | 1 + src/model/invoke.ts | 5 +- src/model/layer.ts | 38 ++- 6 files changed, 551 insertions(+), 11 deletions(-) create mode 100644 lonboard/_layer/rasterio_layer.py diff --git a/lonboard/_layer/core.py b/lonboard/_layer/core.py index 42bc8542..d24478e3 100644 --- a/lonboard/_layer/core.py +++ b/lonboard/_layer/core.py @@ -515,7 +515,7 @@ class BitmapTileLayer(BaseLayer): called = 0 - def __init__(self, **kwargs: BitmapTileLayerKwargs): + def __init__(self, **kwargs: Unpack[BitmapTileLayerKwargs]): def _handle_anywidget_dispatch( widget: ipywidgets.Widget, msg: Union[str, list, dict], buffers: List[bytes] ) -> None: @@ -541,12 +541,14 @@ def _handle_anywidget_dispatch( print("before on msg") self.on_msg(_handle_anywidget_dispatch) - super().__init__(**kwargs) # type: ignore + super().__init__(**kwargs) _layer_type = traitlets.Unicode("bitmap-tile").tag(sync=True) data = traitlets.Union( - [traitlets.Unicode(), traitlets.List(traitlets.Unicode(), minlen=1)] + [traitlets.Unicode(), traitlets.List(traitlets.Unicode(), minlen=1)], + default_value=None, + allow_none=True, ).tag(sync=True) """ Either a URL template or an array of URL templates from which the tile data should diff --git a/lonboard/_layer/rasterio_layer.py b/lonboard/_layer/rasterio_layer.py new file mode 100644 index 00000000..dd4995ae --- /dev/null +++ b/lonboard/_layer/rasterio_layer.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +import traceback +from typing import Unpack + +from rio_tiler.io.base import BaseReader + +# from rio_tiler.io import Reader +# from rio_tiler.models import ImageData +from lonboard.types.layer import BitmapTileLayerKwargs + +from .core import BitmapTileLayer + +# # path = "/Users/kyle/Downloads/m_1806551_nw_20_030_20221212_20230329.tif" +# path = "/Users/kyle/github/developmentseed/lonboard/m_4007307_sw_18_060_20220803.tif" +# reader = Reader(path) +# reader.geographic_bounds +# reader.tms +# reader.bounds +# test = reader.tile(2601, 3674, 13) +# dir(test) +# # test.mask.all() +# attrs.evolve(test, data=test.data[:3, :, :]) +# ImageData() +# image_data = reader.tile(0, 0, 0) + +# with open("tmp.png", "wb") as f: +# f.write(image_data.render()) + + +def handle_anywidget_dispatch( + widget: RioTilerLayer, msg: str | list | dict, buffers: list[bytes] +) -> None: + # widget.called += 1 + print(msg) + + if not isinstance(msg, dict) or msg.get("kind") != "anywidget-command": + return + + try: + content = msg["msg"] + tile_id = content["tile_id"] + tile_x, tile_y, tile_z = tile_id.split("-") + tile_x = int(tile_x) + tile_y = int(tile_y) + tile_z = int(tile_z) + + if tile_z < widget.min_zoom: + return widget.send( + { + "id": msg["id"], + "kind": "anywidget-command-response", + "response": {}, + }, + [], + ) + + image_data = widget.reader.tile(int(tile_x), int(tile_y), int(tile_z)) + + # test.evolve + # rio_tiler. + image_buf = image_data.render(add_mask=True) + buffers = [image_buf] + + response = "helloworld from init" + widget.send( + { + "id": msg["id"], + "kind": "anywidget-command-response", + "response": response, + }, + buffers, + ) + except: # noqa: E722 + response = traceback.format_exc() + widget.send( + { + "id": msg["id"], + "kind": "anywidget-command-response", + "response": response, + }, + buffers, + ) + + +class RioTilerLayer(BitmapTileLayer): + reader: BaseReader + + def __init__( + self, + reader: BaseReader, + *, + min_zoom: int = 10, + **kwargs: Unpack[BitmapTileLayerKwargs], + ): + self.reader = reader + self.min_zoom = min_zoom + + extent = reader.geographic_bounds + kwargs["extent"] = tuple(extent) + + self.on_msg(handle_anywidget_dispatch) + super().__init__(**kwargs) # type: ignore + + pass diff --git a/poetry.lock b/poetry.lock index aa52232f..ffa565c3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,34 @@ # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +[[package]] +name = "affine" +version = "2.4.0" +description = "Matrices describing affine transformation of the plane" +optional = false +python-versions = ">=3.7" +files = [ + {file = "affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92"}, + {file = "affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea"}, +] + +[package.extras] +dev = ["coveralls", "flake8", "pydocstyle"] +test = ["pytest (>=4.6)", "pytest-cov"] + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + [[package]] name = "anyio" version = "4.4.0" @@ -371,6 +400,17 @@ webencodings = "*" [package.extras] css = ["tinycss2 (>=1.1.0,<1.3)"] +[[package]] +name = "cachetools" +version = "5.4.0" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.4.0-py3-none-any.whl", hash = "sha256:3ae3b49a3d5e28a77a0be2b37dbcb89005058959cb2323858c2657c4a8cab474"}, + {file = "cachetools-5.4.0.tar.gz", hash = "sha256:b8adc2e7c07f105ced7bc56dbb6dfbe7c4a00acce20e2227b3f355be89bc6827"}, +] + [[package]] name = "cairocffi" version = "1.7.1" @@ -630,7 +670,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." -optional = true +optional = false python-versions = "*" files = [ {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, @@ -647,7 +687,7 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] name = "cligj" version = "0.7.2" description = "Click params for commmand line interfaces to GeoJSON" -optional = true +optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" files = [ {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, @@ -660,6 +700,53 @@ click = ">=4.0" [package.extras] test = ["pytest-cov"] +[[package]] +name = "color-operations" +version = "0.1.5" +description = "Apply basic color-oriented image operations." +optional = false +python-versions = ">=3.8" +files = [ + {file = "color-operations-0.1.5.tar.gz", hash = "sha256:8d4479532acbd4be2b90858274a0810dcaa3146e192a785f6a4b3f8f3da6ea85"}, + {file = "color_operations-0.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:651893f735f5cb716bf60065183b337df00fd94251dac5a00fe3c6dd1d7127df"}, + {file = "color_operations-0.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1b37808b8f94db8bf5168543e7c08d6de6ed9723ba4c04be8a6ff53f32c00d6"}, + {file = "color_operations-0.1.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a7c515506498fbdfdb970f2fe6a6f4dc3e41552d844568232e0b2f630d44b238"}, + {file = "color_operations-0.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e8767d91e5ee8eb259a25c2c72ff1a9fc6c1fd4ef9dfc1aba110cbb9b7397e"}, + {file = "color_operations-0.1.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3df23676c96720659f3dc934cbf6eb10d07d9f3e2560109227da3d4004ae3348"}, + {file = "color_operations-0.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:f423ddc4ac8057894a69af4f91d6862710574e759aa6b525a0483ed8c788f11e"}, + {file = "color_operations-0.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e70982db5304a2147b62abf2ab18c45b683e2f3c68c8a71da0622afc5fcf3a43"}, + {file = "color_operations-0.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4aaec777a97768f6862d016895a6cbafd9a43b0fb1d741638b38ba579e79dd1b"}, + {file = "color_operations-0.1.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:238eb331ce03d4a5d2da106029e1b4fd04ba82995c9c6b58b100ab3ab909ce00"}, + {file = "color_operations-0.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:484049262f6632a16ecf48e776e609281522ec5a9cd1a150a68084412a115c98"}, + {file = "color_operations-0.1.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb0e507043b2ef614742fdd46b4ced80ed5f71b333a2437c168c062a36d6973"}, + {file = "color_operations-0.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:38e177320b53d9ed8c3aa96fa837046a4d5f3cac98241685751afb4ab63e1912"}, + {file = "color_operations-0.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c51875759fb6bcde97a18dfda892ca08c179636d41e3f696427fcaa834304f80"}, + {file = "color_operations-0.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:34e33f8f6a580b69713d3ea695a15716ccce136390f753ff9cfe13a49f723a8f"}, + {file = "color_operations-0.1.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b5c71b0c5d30461244788f841984135e1d2dd057c80b9570a12d131aec286b2"}, + {file = "color_operations-0.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86b661572406df2ffda34e09409d3cb8dd46e513652232d469aebc3aa69654be"}, + {file = "color_operations-0.1.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6044648d1bbd3c42e098e4c9a54886c16c44d0da4ae5c1c1b61a17760b98a4b"}, + {file = "color_operations-0.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:4456a123586711d193d5982ce89e826477f0422c84036574da66e49381bce299"}, + {file = "color_operations-0.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6338fab2d186773edf5adc7b1f93aea1844c707821f2753e15f7216a36e94ce2"}, + {file = "color_operations-0.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9586a29853991123627eb10f0da3c43aa9bf7ce3a0eb7f3a145b11d7d3c2289"}, + {file = "color_operations-0.1.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:38e3f49a565f1606b8d11374dd60952d40443156014c2c0eedcfa0a9f06ada32"}, + {file = "color_operations-0.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ddeb4ba6047704617f49bb9286a6cdd70d656e9607d8af76ad94776c645069b"}, + {file = "color_operations-0.1.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c485cf3e29d1377f5251d06b53dc0a99d3a3b6c3ffd246c2f60ec9558e3ce5c0"}, + {file = "color_operations-0.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:78ede58b626cf7b63dd6c6a22712d65c5642e5b2d32dd3a90084ddbeee8a84b6"}, + {file = "color_operations-0.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c452f9fb1a323c688623e245158f55236483425eb8e14a5f83347c4b35592374"}, + {file = "color_operations-0.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:581403d6114a29cefe8dd1857ee37b8794c1992a3aaf13f7ccd0267fda4f856a"}, + {file = "color_operations-0.1.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:15a73c9f2eb0045367c5d45e5931286e5cf42c5601098b4cfb66448df51d3478"}, + {file = "color_operations-0.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8352a2354178f9fdafee38df3ecacea06fcd894c511a6cce3b50590f830ef6"}, + {file = "color_operations-0.1.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:274ae1839c7f1068669d81acf8256b09cfa310a8ea0f255f9c5a04d9e2a6c59f"}, + {file = "color_operations-0.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:a557ce3d8b610b5c10a5f096fdff89d3850ce549fee256aa37728472d67d628c"}, +] + +[package.dependencies] +numpy = "*" + +[package.extras] +dev = ["pre-commit"] +test = ["colormath (==2.0.2)", "pytest", "pytest-cov"] + [[package]] name = "colorama" version = "0.4.6" @@ -2473,6 +2560,28 @@ files = [ griffe = ">=0.47" mkdocstrings = ">=0.25" +[[package]] +name = "morecantile" +version = "5.3.1" +description = "Construct and use map tile grids (a.k.a TileMatrixSet / TMS)." +optional = false +python-versions = ">=3.8" +files = [ + {file = "morecantile-5.3.1-py3-none-any.whl", hash = "sha256:35785988b8f6f1699e2c0136bfda4815dcaf8ae1200b035ba5eb1cb1f0453650"}, + {file = "morecantile-5.3.1.tar.gz", hash = "sha256:49a1d4239f30a033a3188e32ea1d218c7fd05c00821311b3797e1e7d56b67a40"}, +] + +[package.dependencies] +attrs = "*" +pydantic = ">=2.0,<3.0" +pyproj = ">=3.1,<4.0" + +[package.extras] +dev = ["bump-my-version", "pre-commit"] +docs = ["mkdocs", "mkdocs-material", "pygments"] +rasterio = ["rasterio (>=1.2.1)"] +test = ["mercantile", "pytest", "pytest-cov", "rasterio (>=1.2.1)"] + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -2604,6 +2713,48 @@ jupyter-server = ">=1.8,<3" [package.extras] test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] +[[package]] +name = "numexpr" +version = "2.8.6" +description = "Fast numerical expression evaluator for NumPy" +optional = false +python-versions = ">=3.7" +files = [ + {file = "numexpr-2.8.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80acbfefb68bd92e708e09f0a02b29e04d388b9ae72f9fcd57988aca172a7833"}, + {file = "numexpr-2.8.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6e884687da8af5955dc9beb6a12d469675c90b8fb38b6c93668c989cfc2cd982"}, + {file = "numexpr-2.8.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ef7e8aaa84fce3aba2e65f243d14a9f8cc92aafd5d90d67283815febfe43eeb"}, + {file = "numexpr-2.8.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dee04d72307c09599f786b9231acffb10df7d7a74b2ce3681d74a574880d13ce"}, + {file = "numexpr-2.8.6-cp310-cp310-win32.whl", hash = "sha256:211804ec25a9f6d188eadf4198dd1a92b2f61d7d20993c6c7706139bc4199c5b"}, + {file = "numexpr-2.8.6-cp310-cp310-win_amd64.whl", hash = "sha256:18b1804923cfa3be7bbb45187d01c0540c8f6df4928c22a0f786e15568e9ebc5"}, + {file = "numexpr-2.8.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95b9da613761e4fc79748535b2a1f58cada22500e22713ae7d9571fa88d1c2e2"}, + {file = "numexpr-2.8.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:47b45da5aa25600081a649f5e8b2aa640e35db3703f4631f34bb1f2f86d1b5b4"}, + {file = "numexpr-2.8.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84979bf14143351c2db8d9dd7fef8aca027c66ad9df9cb5e75c93bf5f7b5a338"}, + {file = "numexpr-2.8.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d36528a33aa9c23743b3ea686e57526a4f71e7128a1be66210e1511b09c4e4e9"}, + {file = "numexpr-2.8.6-cp311-cp311-win32.whl", hash = "sha256:681812e2e71ff1ba9145fac42d03f51ddf6ba911259aa83041323f68e7458002"}, + {file = "numexpr-2.8.6-cp311-cp311-win_amd64.whl", hash = "sha256:27782177a0081bd0aab229be5d37674e7f0ab4264ef576697323dd047432a4cd"}, + {file = "numexpr-2.8.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ef6e8896457a60a539cb6ba27da78315a9bb31edb246829b25b5b0304bfcee91"}, + {file = "numexpr-2.8.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e640bc0eaf1b59f3dde52bc02bbfda98e62f9950202b0584deba28baf9f36bbb"}, + {file = "numexpr-2.8.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d126938c2c3784673c9c58d94e00b1570aa65517d9c33662234d442fc9fb5795"}, + {file = "numexpr-2.8.6-cp37-cp37m-win32.whl", hash = "sha256:e93d64cd20940b726477c3cb64926e683d31b778a1e18f9079a5088fd0d8e7c8"}, + {file = "numexpr-2.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:31cf610c952eec57081171f0b4427f9bed2395ec70ec432bbf45d260c5c0cdeb"}, + {file = "numexpr-2.8.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5f96c89aa0b1f13685ec32fa3d71028db0b5981bfd99a0bbc271035949136b3"}, + {file = "numexpr-2.8.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c8f37f7a6af3bdd61f2efd1cafcc083a9525ab0aaf5dc641e7ec8fc0ae2d3aa1"}, + {file = "numexpr-2.8.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38b8b90967026bbc36c7aa6e8ca3b8906e1990914fd21f446e2a043f4ee3bc06"}, + {file = "numexpr-2.8.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1967c16f61c27df1cdc43ba3c0ba30346157048dd420b4259832276144d0f64e"}, + {file = "numexpr-2.8.6-cp38-cp38-win32.whl", hash = "sha256:15469dc722b5ceb92324ec8635411355ebc702303db901ae8cc87f47c5e3a124"}, + {file = "numexpr-2.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:95c09e814b0d6549de98b5ded7cdf7d954d934bb6b505432ff82e83a6d330bda"}, + {file = "numexpr-2.8.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aa0f661f5f4872fd7350cc9895f5d2594794b2a7e7f1961649a351724c64acc9"}, + {file = "numexpr-2.8.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8e3e6f1588d6c03877cb3b3dcc3096482da9d330013b886b29cb9586af5af3eb"}, + {file = "numexpr-2.8.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8564186aad5a2c88d597ebc79b8171b52fd33e9b085013e1ff2208f7e4b387e3"}, + {file = "numexpr-2.8.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6a88d71c166e86b98d34701285d23e3e89d548d9f5ae3f4b60919ac7151949f"}, + {file = "numexpr-2.8.6-cp39-cp39-win32.whl", hash = "sha256:c48221b6a85494a7be5a022899764e58259af585dff031cecab337277278cc93"}, + {file = "numexpr-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:6d7003497d82ef19458dce380b36a99343b96a3bd5773465c2d898bf8f5a38f9"}, + {file = "numexpr-2.8.6.tar.gz", hash = "sha256:6336f8dba3f456e41a4ffc3c97eb63d89c73589ff6e1707141224b930263260d"}, +] + +[package.dependencies] +numpy = ">=1.13.3" + [[package]] name = "numpy" version = "1.24.4" @@ -3185,6 +3336,129 @@ files = [ {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] +[[package]] +name = "pydantic" +version = "2.8.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, +] + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + [[package]] name = "pygments" version = "2.18.0" @@ -3324,6 +3598,30 @@ files = [ [package.dependencies] certifi = "*" +[[package]] +name = "pystac" +version = "1.8.4" +description = "Python library for working with the SpatioTemporal Asset Catalog (STAC) specification" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pystac-1.8.4-py3-none-any.whl", hash = "sha256:0d9917bf3abc71fca3edfb2dd5f66be44b22a63774cda520c81484a126fa780e"}, + {file = "pystac-1.8.4.tar.gz", hash = "sha256:ab9b93d16c4cca80e3c225cd5815dbaec610ee9320e2119857db17481b9bd2e5"}, +] + +[package.dependencies] +importlib-resources = {version = ">=5.12.0", markers = "python_version < \"3.9\""} +python-dateutil = ">=2.7.0" + +[package.extras] +bench = ["asv (>=0.6.0,<0.7.0)", "packaging (>=23.1,<24.0)", "virtualenv (>=20.22,<21.0)"] +docs = ["Sphinx (>=6.2,<7.0)", "ipython (>=8.12,<9.0)", "jinja2 (<4.0)", "jupyter (>=1.0,<2.0)", "nbsphinx (>=0.9.0,<0.10.0)", "pydata-sphinx-theme (>=0.13,<1.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-design (>=0.5.0,<0.6.0)", "sphinxcontrib-fulltoc (>=1.2,<2.0)"] +jinja2 = ["jinja2 (<4.0)"] +orjson = ["orjson (>=3.5)"] +test = ["black (>=23.3,<24.0)", "codespell (>=2.2,<3.0)", "coverage (>=7.2,<8.0)", "doc8 (>=1.1,<2.0)", "html5lib (>=1.1,<2.0)", "jinja2 (<4.0)", "jsonschema (>=4.18,<5.0)", "mypy (>=1.2,<2.0)", "orjson (>=3.8,<4.0)", "pre-commit (>=3.2,<4.0)", "pytest (>=7.3,<8.0)", "pytest-cov (>=4.0,<5.0)", "pytest-mock (>=3.10,<4.0)", "pytest-recording (>=0.13.0,<0.14.0)", "ruff (==0.0.291)", "types-html5lib (>=1.1,<2.0)", "types-orjson (>=3.6,<4.0)", "types-python-dateutil (>=2.8,<3.0)", "types-urllib3 (>=1.26,<2.0)"] +urllib3 = ["urllib3 (>=1.26)"] +validation = ["jsonschema (>=4.18,<5.0)"] + [[package]] name = "pytest" version = "7.4.4" @@ -3617,6 +3915,56 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "rasterio" +version = "1.3.10" +description = "Fast and direct raster I/O for use with Numpy and SciPy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rasterio-1.3.10-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:2ef27c3eff6f44f8b5d5de228003367c1843593edf648d85c0dc1319c00dc57d"}, + {file = "rasterio-1.3.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c711b497e9ef0c4f5e1c01e34ba910708e066e1c4a69c25df18d1bcc04481287"}, + {file = "rasterio-1.3.10-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:d1ac85857144cb8075e332e9d908b65426d30ddc1f59f7a04bcf6ed6fd3c0d47"}, + {file = "rasterio-1.3.10-cp310-cp310-win_amd64.whl", hash = "sha256:ef8a496740df1e68f7a3d3449aa3be9c3210c22f4bb78a4a9e1c290183abd9b1"}, + {file = "rasterio-1.3.10-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:97d867cada29f16cb83f1743217f775f8b982676fcdda77671d25abb26698159"}, + {file = "rasterio-1.3.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:505b3e659eb3b137192c25233bf7954bc4997b1a474bae9e129fbd5ac2619404"}, + {file = "rasterio-1.3.10-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:30f27e309a14a70c821d10a0ea18b110968dc2e2186b06a900aebd92094f4e00"}, + {file = "rasterio-1.3.10-cp311-cp311-win_amd64.whl", hash = "sha256:cbb2eea127328302f9e3158a000363a7d9eea22537378dee4f824a7fa2d78c05"}, + {file = "rasterio-1.3.10-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:3a9c4fb63e050e11bcd23e53f084ca186b445f976df1f70e7abd851c4072837f"}, + {file = "rasterio-1.3.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7c7ddca79444fd3b933f4cd1a1773e9f7839d0ce5d76e600bdf92ee9a79b95f8"}, + {file = "rasterio-1.3.10-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:f9cd757e11cfb07ef39b1cc79a32497bf22aff7fec41fe330b868cb3043b4db5"}, + {file = "rasterio-1.3.10-cp312-cp312-win_amd64.whl", hash = "sha256:7e653968f64840654d277e0f86f8666ed8f3030ba36fa865f420f9bc38d619ee"}, + {file = "rasterio-1.3.10-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:7a22c0e0cf07dbed6576faf9a49bc4afa1afedd5a14441b64a3d3dd6d10dc274"}, + {file = "rasterio-1.3.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d29d30c2271fa265913bd3db93fa213d3a0894362ec704e7273cf30443098a90"}, + {file = "rasterio-1.3.10-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:287e8d0d0472c778aa0b6392e9c00894a80f2bace28fa6eddb76c0a895097947"}, + {file = "rasterio-1.3.10-cp38-cp38-win_amd64.whl", hash = "sha256:a420e5f25108b1c92c5d071cfd6518b3766f20a6eddb1b322d06c3d46a89fab6"}, + {file = "rasterio-1.3.10-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:73ea4d0e584f696ef115601bbb97ba8d2b68a67c2bb3b40999414d31b6c7cf89"}, + {file = "rasterio-1.3.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e6eece6420d7d6ef9b9830633b8fcd15e86b8702cb13419abe251c16ca502cf3"}, + {file = "rasterio-1.3.10-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:0bbd62b45a35cab53cb7fe72419e823e47ab31ee2d055af8e21dc7f37fe5ed6c"}, + {file = "rasterio-1.3.10-cp39-cp39-win_amd64.whl", hash = "sha256:450f2bd45335308829da90566fbcbdb8e8aa0251a9d1f6ebb60667855dfb7554"}, + {file = "rasterio-1.3.10.tar.gz", hash = "sha256:ce182c735b4f9e8735d90600607ecab15ef895eb8aa660bf665751529477e326"}, +] + +[package.dependencies] +affine = "*" +attrs = "*" +certifi = "*" +click = ">=4.0" +click-plugins = "*" +cligj = ">=0.5" +importlib-metadata = {version = "*", markers = "python_version < \"3.10\""} +numpy = "*" +setuptools = "*" +snuggs = ">=1.4.1" + +[package.extras] +all = ["boto3 (>=1.2.4)", "ghp-import", "hypothesis", "ipython (>=2.0)", "matplotlib", "numpydoc", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely", "sphinx", "sphinx-rtd-theme"] +docs = ["ghp-import", "numpydoc", "sphinx", "sphinx-rtd-theme"] +ipython = ["ipython (>=2.0)"] +plot = ["matplotlib"] +s3 = ["boto3 (>=1.2.4)"] +test = ["boto3 (>=1.2.4)", "hypothesis", "packaging", "pytest (>=2.8.2)", "pytest-cov (>=2.2.0)", "shapely"] + [[package]] name = "referencing" version = "0.35.1" @@ -3766,6 +4114,39 @@ files = [ {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, ] +[[package]] +name = "rio-tiler" +version = "6.6.1" +description = "User friendly Rasterio plugin to read raster datasets." +optional = false +python-versions = ">=3.8" +files = [ + {file = "rio_tiler-6.6.1-py3-none-any.whl", hash = "sha256:4613964ff824a3cb14b6033746f0e8c936c0e1f119dff54cf841528f24285412"}, + {file = "rio_tiler-6.6.1.tar.gz", hash = "sha256:75ce0fc3011cb8c7ee282b19807e7e7e9042da65a18a922d04c8bba9f3b65ce2"}, +] + +[package.dependencies] +attrs = "*" +cachetools = "*" +color-operations = "*" +httpx = "*" +importlib-resources = {version = ">=1.1.0", markers = "python_version < \"3.9\""} +morecantile = ">=5.0,<6.0" +numexpr = "*" +numpy = "*" +pydantic = ">=2.0,<3.0" +pystac = ">=0.5.4" +rasterio = ">=1.3.0" + +[package.extras] +benchmark = ["pytest", "pytest-benchmark"] +dev = ["pre-commit"] +docs = ["mkdocs", "mkdocs-jupyter", "mkdocs-material", "nbconvert", "pygments"] +s3 = ["boto3"] +test = ["boto3", "pytest", "pytest-cov", "rioxarray", "xarray"] +tilebench = ["pytest", "tilebench"] +xarray = ["rioxarray", "xarray"] + [[package]] name = "rpds-py" version = "0.20.0" @@ -3984,6 +4365,24 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] +[[package]] +name = "snuggs" +version = "1.4.7" +description = "Snuggs are s-expressions for Numpy" +optional = false +python-versions = "*" +files = [ + {file = "snuggs-1.4.7-py3-none-any.whl", hash = "sha256:988dde5d4db88e9d71c99457404773dabcc7a1c45971bfbe81900999942d9f07"}, + {file = "snuggs-1.4.7.tar.gz", hash = "sha256:501cf113fe3892e14e2fee76da5cd0606b7e149c411c271898e6259ebde2617b"}, +] + +[package.dependencies] +numpy = "*" +pyparsing = ">=2.1.6" + +[package.extras] +test = ["hypothesis", "pytest"] + [[package]] name = "soupsieve" version = "2.6" @@ -4431,4 +4830,4 @@ geopandas = ["geopandas", "pandas", "shapely"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "302872d35c02634170267467d629a73189a40407864386e278b52e231d318ffc" +content-hash = "2104e31c7a45528919359242824d149ebabedf57f91b172cbee97f14c83c382c" diff --git a/pyproject.toml b/pyproject.toml index 4bebf4d9..07108bcd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ pyogrio = "^0.8" geoarrow-pyarrow = "^0.1.1" duckdb = "^0.10.2" pyarrow = ">=14.0.1" +rio-tiler = "^6.6.1" [tool.poetry.group.docs.dependencies] # We use ruff format ourselves, but mkdocstrings requires black to be installed diff --git a/src/model/invoke.ts b/src/model/invoke.ts index 2cce1f4d..8e5b1ecd 100644 --- a/src/model/invoke.ts +++ b/src/model/invoke.ts @@ -17,7 +17,6 @@ type InvokeOptions = { export async function invoke( model: AnyModel, - name: string, msg: object, options: InvokeOptions = {}, ): Promise<[T, DataView[]]> { @@ -28,9 +27,11 @@ export async function invoke( return new Promise((resolve, reject) => { if (signal.aborted) { + console.log("signal already aborted"); reject(signal.reason); } signal.addEventListener("abort", () => { + console.log("aborting from signal again"); model.off("msg:custom", handler); reject(signal.reason); }); @@ -45,7 +46,7 @@ export async function invoke( } model.on("msg:custom", handler); model.send( - { id, kind: "anywidget-command", name, msg }, + { id, kind: "anywidget-command", msg }, undefined, options.buffers ?? [], ); diff --git a/src/model/layer.ts b/src/model/layer.ts index 244e16ce..70cf6ef4 100644 --- a/src/model/layer.ts +++ b/src/model/layer.ts @@ -245,16 +245,47 @@ export class BitmapTileModel extends BaseLayerModel { // Alternate function form so that we can assign the upstream getTileData type getTileData: TileLayerProps["getTileData"] = async (tile) => { + const { signal } = tile; + const signals: AbortSignal[] = [AbortSignal.timeout(10_000)]; + if (signal !== undefined) { + signals.push(signal); + } + + const compositeSignal = AbortSignal.any(signals); console.log("in getTileData"); // const { invoke } = this.anywidgetExperimental; - console.log(invoke); console.log("calling invoke"); - const out = await invoke(this.model, "helloworld", {}); + console.log(tile); + const [message, buffer] = await invoke( + this.model, + { + tile_id: tile.id, + }, + { signal: compositeSignal }, + ); + + if (compositeSignal.aborted) { + return null; + } + + if (buffer.length === 0) { + return null; + } + console.log("returned from invoke"); - console.log(out); + console.log(message); + console.log(buffer.length); + console.log(buffer[0]); + console.log(buffer[0].byteLength); console.log(tile); + const blob = new Blob([buffer[0]], { type: "image/png" }); + const url = URL.createObjectURL(blob); + return url; + const image = new Response(buffer[0]); + return image; + // const { data, getTileData, fetch } = this.props; // const { signal } = tile; @@ -278,6 +309,7 @@ export class BitmapTileModel extends BaseLayerModel { ...this.layerProps(), getTileData: this.getTileData?.bind(this), renderSubLayers: (props) => { + console.log("in renderSubLayers", props); const [min, max] = props.tile.boundingBox; return new BitmapLayer(props, {