This is an automated email from the ASF dual-hosted git repository.

hainenber pushed a commit to branch fix/migrate-to-dep-free-pygeohash
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 6714d2bd4a777a5f0ecf3ab48357c4e27635f4e1
Author: hainenber <[email protected]>
AuthorDate: Wed Jan 28 21:32:29 2026 +0700

    fix(build/backend): migrate to deps-free `pygeohash` with pre-built wheels 
if needed
    
    Signed-off-by: hainenber <[email protected]>
---
 pyproject.toml                                    |  4 +---
 requirements/base.txt                             |  4 ++--
 requirements/development.txt                      |  8 ++++----
 superset/utils/pandas_postprocessing/geography.py |  6 ++++--
 superset/viz.py                                   | 24 +++++++++++++++--------
 5 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/pyproject.toml b/pyproject.toml
index 0ba77ae3b1..beaf851bbe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -88,7 +88,7 @@ dependencies = [
     "pyparsing>=3.0.6, <4",
     "python-dateutil",
     "python-dotenv", # optional dependencies for Flask but required for 
Superset, see 
https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies
-    "python-geohash",
+    "pygeohash",
     "pyarrow>=16.1.0, <19", # before upgrading pyarrow, check that all db 
dependencies support this, see e.g. 
https://github.com/apache/superset/pull/34693
     "pyyaml>=6.0.0, <7.0.0",
     "PyJWT>=2.4.0, <3.0",
@@ -457,8 +457,6 @@ authorized_licenses = [
 # Seems ok, might need legal review
 # https://github.com/urschrei/pypolyline/blob/master/LICENSE.md
 polyline = "2"
-# Apache 2.0 https://github.com/hkwi/python-geohash
-python-geohash = "0"
 # --------------------------------------------------------------
 
 # TODO REMOVE THESE DEPS FROM CODEBASE
diff --git a/requirements/base.txt b/requirements/base.txt
index 9cf9e3c16f..54ac6c4e4c 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -303,6 +303,8 @@ pydantic==2.11.7
     #   apache-superset-core
 pydantic-core==2.33.2
     # via pydantic
+pygeohash==3.2.2
+    # via apache-superset (pyproject.toml)
 pygments==2.19.1
     # via rich
 pyjwt==2.10.1
@@ -330,8 +332,6 @@ python-dateutil==2.9.0.post0
     #   shillelagh
 python-dotenv==1.1.0
     # via apache-superset (pyproject.toml)
-python-geohash==0.8.5
-    # via apache-superset (pyproject.toml)
 pytz==2025.2
     # via
     #   croniter
diff --git a/requirements/development.txt b/requirements/development.txt
index 300c2df556..b5bee77b56 100644
--- a/requirements/development.txt
+++ b/requirements/development.txt
@@ -752,6 +752,10 @@ pydruid==0.6.9
     # via apache-superset
 pyfakefs==5.3.5
     # via apache-superset
+pygeohash==3.2.2
+    # via
+    #   -c requirements/base-constraint.txt
+    #   apache-superset
 pygments==2.19.1
     # via
     #   -c requirements/base-constraint.txt
@@ -827,10 +831,6 @@ python-dotenv==1.1.0
     #   apache-superset
     #   fastmcp
     #   pydantic-settings
-python-geohash==0.8.5
-    # via
-    #   -c requirements/base-constraint.txt
-    #   apache-superset
 python-json-logger==4.0.0
     # via pydocket
 python-ldap==3.4.4
diff --git a/superset/utils/pandas_postprocessing/geography.py 
b/superset/utils/pandas_postprocessing/geography.py
index c5f46cd490..cded3cbb82 100644
--- a/superset/utils/pandas_postprocessing/geography.py
+++ b/superset/utils/pandas_postprocessing/geography.py
@@ -16,7 +16,7 @@
 # under the License.
 from typing import Optional
 
-import geohash as geohash_lib
+import pygeohash as geohash_lib
 from flask_babel import gettext as _
 from geopy.point import Point
 from pandas import DataFrame
@@ -68,7 +68,9 @@ def geohash_encode(
         encode_df = df[[latitude, longitude]]
         encode_df.columns = ["latitude", "longitude"]
         encode_df["geohash"] = encode_df.apply(
-            lambda row: geohash_lib.encode(row["latitude"], row["longitude"]),
+            lambda row: geohash_lib.encode(
+                latitude=row["latitude"], longitude=row["longitude"]
+            ),
             axis=1,
         )
         return _append_columns(df, encode_df, {"geohash": geohash})
diff --git a/superset/viz.py b/superset/viz.py
index c6c7cf699b..023cdca114 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -32,10 +32,10 @@ from datetime import datetime, timedelta
 from itertools import product
 from typing import Any, cast, Optional, TYPE_CHECKING
 
-import geohash
 import numpy as np
 import pandas as pd
 import polyline
+import pygeohash
 from dateutil import relativedelta as rdelta
 from deprecation import deprecated
 from flask import current_app, request
@@ -1830,7 +1830,7 @@ class BaseDeckGLViz(BaseViz):
     @staticmethod
     @deprecated(deprecated_in="3.0")
     def reverse_geohash_decode(geohash_code: str) -> tuple[str, str]:
-        lat, lng = geohash.decode(geohash_code)
+        lat, lng = pygeohash.decode(geohash_code)
         return (lng, lat)
 
     @staticmethod
@@ -2133,13 +2133,21 @@ class DeckGrid(BaseDeckGLViz):
 
 @deprecated(deprecated_in="3.0")
 def geohash_to_json(geohash_code: str) -> list[list[float]]:
-    bbox = geohash.bbox(geohash_code)
+    # Get the center and the error margins
+    lat, lon, lat_err, lon_err = pygeohash.decode_exactly(geohash_code)
+    # Calculate the Bounding Box
+    bbox = {
+        "n": lat + lat_err,
+        "s": lat - lat_err,
+        "e": lon + lon_err,
+        "w": lon - lon_err,
+    }
     return [
-        [bbox.get("w"), bbox.get("n")],
-        [bbox.get("e"), bbox.get("n")],
-        [bbox.get("e"), bbox.get("s")],
-        [bbox.get("w"), bbox.get("s")],
-        [bbox.get("w"), bbox.get("n")],
+        [bbox["w"], bbox["n"]],
+        [bbox["e"], bbox["n"]],
+        [bbox["e"], bbox["s"]],
+        [bbox["w"], bbox["s"]],
+        [bbox["w"], bbox["n"]],
     ]
 
 

Reply via email to