From b415f687a85193aaa00c9d45031e990428b7dedb Mon Sep 17 00:00:00 2001 From: Christian Beilschmidt Date: Thu, 6 Nov 2025 08:51:03 +0100 Subject: [PATCH 1/2] build: update dependencies --- .coverage | Bin 0 -> 53248 bytes README.md | 6 +++--- mypy.ini | 2 +- pyproject.toml | 24 ++++++++++++------------ tests/test_ml.py | 26 +++++++++++++++++--------- 5 files changed, 33 insertions(+), 25 deletions(-) create mode 100644 .coverage diff --git a/.coverage b/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..3e0cd5a155e778eb04333ba3438cf095912c7c39 GIT binary patch literal 53248 zcmeI53v?4z8prP>)4Y@Ea|>Ho1`x`l4^k18ilrb36sIrCrjoY933zybt-01yBI|K9|H<1G5b z&Yh|9c{1np^0LIacqz2D4j(@vd*TRoV)n4HBiPVBwvUO$OKK{c%}U~Iwvd-tkKpB5 z!S5DaoGkeBSUI1MD4 zSCP!Suj^n6ffiXXy!PH;tr^6j8KIKlbG4(>R`@z4!`Z`yJ=i$E7{S_BkenJ9R&4ec z`J5Q}%pzYQsT^D)bYfY&QOO&XmBp~LH(fW^smnHhJ5*-`IjPZ5sUp8HtB7x{{1mpW zWQyX3Urb?%6F35TnRSWx#!(1IB|j%H%ZsnK99)qsDxV#=@*Q@(vOFDQ&?k25MlGDB z1Pa09a0+sub;H;pXj*sQAauy_8^;Z4B^`r=v?8yU6+KFmA*I<+<=|*;-)7PyFgS@c zG*%2}#FpODXd}jA8(61Tbasq2C1L_RZXmcXh-C8=`CX)`1c(nVv6z>*JU%UaG}JBJ z>OjJwV>jv&M|8VU=(L7_!``}S3U=1%6O)pta-$MP;o1r(`VJu!smbefqme^Co(mL7 zk&fh-I>|_hwq7#QM#4w1JE?kIVs_Gv+zID%*uxu!pq|zzCL~b7P>Ue_5_v~;aDwb< zYXUzT2yWi|LQc+SueF`*#)c65p%gUMu1 zo5?wRNoq0Y#l1-(CrG%-;yySu04`;Yr4xHhV(?ZJ#6Tajw2f zcHF!l5d#4M536L@3Ji|yWs~!{0O^GS$*fZpy*%d+jSaZO=m0*a5MUJ>t{s)K+B5_S+OZHxR7psB5rh%_JucmKF;qBk5^V4e=1lMZj7OR#u31Sx{r&P9sa245F|f4*cLCj zxWmO)JMH6yuxp2dd<>m|bZ(&kX4XekY)C-Z*|a}qHZ@Cp_n00e*l5C8%|00;m9AOHk_01yBIK;X6{ zV9{v1GLgUV7!XZqlRAh02H@^AyFG1y345hs&LZY4bLqBp5R3)_KmZ5;0U!VbfB+Bx z0zd!=00AHX1X>ALv|Xvl*8m!mHpv+N7J&TzA8*`?n61pCwoA6Z8gm_^~4!r0Rlh(2mk>f00e*l5V++8rp41Jn3bL{`uKDwFL?32 zpFY7Yr{@Xy&5NnLKM&u|Pc}nasf8tSzUXh;kuGronU@^1MXA8!6=ypnL3GTP@Pi5@ zd`s#9b~ z$+-#&MF~Gip|E6>4XY)nQIokq0Z|%lRm;oEmEc>kiHjDsF1kdoC<#w0fi=pk+QpJW zp4c_Xgq7@SU`c#HERtO0K`^{u7CeGt;loC(+g*(=ekP4i!1vwbCryw_HK_HNmn4xi z$_MpWNmXmYk08m%LL+rpC`OHoT%mwm&BEjqC zrF0S31SgA17*E$?`D`^lUnB3t4{*Q_4)QDJKcT_;Lw;3#hePlSvco}0Q))@K6C=O> z#~b${W}8i8-C-VUNw?i$BvKJ=l?Nd z>0pv7smMeCUzbNeLS zt_s%m=l`Z$I@n#6ZpZn*QMJdB`M*JRYYNZ*^$*g)7*#HY=Kng?O{v}dKT36v7HOB) zo&VDgI+(4>=WFCU%>T91=-`lFSHInqU6X@5Eu)(5zMU96{|_!8fB+Bx0zd!=00AHX z1b_e#00KY&2>hlAXelkSlHdO+<|@K3SbzW!00KY&2mk>f00e*l5C8%|00;nq-yi|4 z)@oGl|2Ho{%sHlxd6%hTN|_}5cmCxz-j->zST9(QSl3u;Ek`X6Snjj*z!_ly0zd!= z00AHX1b_e#00KZj4S`^n_$bO)eh+=VwrbV0TZ126)}rd(Noa$A>Xt)tqw7iy?|(i| z7+&$wOwWGjhz+Zoj7RF4Gnb#qdV5A=N~W$l@yL%kw8x_>%rx zv*q&2^p|pvwH|ru^0X(bH2t{Ob65&dL(lG#|8*+L5RHwBjqUNt+rj%8V%AgUXWpB7 z`QV~ICU8{MJZJ5h%stC9-}@kA+l#wiqN}6c-jc`LryI~KKa6xOuy%g+X#PMGi#n}% z(_Zfy@cWhP1m_bg->H=g9$MeHtfi`M=?RZ?;`oGN&FQE1lw7I!Y<}s5)9XIZIJjZT z?j3fj`tz%ulU#ghz@BB4(zD|9^c|7IpRbl&??k zF+a6_Qo^?6{9II@JFbjw{JOz~J)v0x-N%Hpk2hA%&GVtx_bor}S=M7YMaQ0ccgUlt z=KPv^=3KX9e?etPV@NXMocF|4&OLMgsmbqrT=!Moce%0IsB!E0^FL)t23$))x3zM2 zQ$R|e7ljNlUyNUQ;PrtO^E5xL`}fOPyXKE?m`)*dN3Ri4-JAM!svo2KPsNh?1IN1> z#yzK3Odo3d=DT^_CtR6z)r^|IZH_}j8!n!BZW9`cqEBYeUA6G(v~!Ce9{lQVw_MI% z$~i{$)MJB28NT#*1^bjcJ@L+XP0z&xoV0z|;;0yes{8ECZyM~>5yKvcs@z@2psC)| z`x8#S(7)!xH5;0$%A&mfft|K5+?jR4T(%Q=x9tdI{^H2<^0S8!-lOUAK<=~38_8J6>NcYG{;G<QHn((p5^DNlP;Qoi#sy-T^5Nh2)Dj=`m2)4@ zJT)1W?Qd>rDP7_BQDtk_uKn{cie8TTbf*j&l3n+Ak2Zm#jmEUWWnB%(fV!YAW!O;d zpNz`=|4cDr8kwh=c}y`=!_+h1GDn$R%p1%q{GGr-<`w2Nvxs?%S;Bn4Y*KK;3J3rJ zAOHk_01yBIKmZ5;0U!VbfB+D<2?9DiE2rpqCDFzyi6&M_qGOaKHd;x{jFQ-FN@B7q zNxVf#V$4cnG$~1(QAw-@B{ArgBub|wmMA4*XeH5Wl|-kZ@fQNh@Bb+JCQODbKmZ5; z0U!VbfB+Bx0zd!=00AHX1c1P8OMv|T5A*-qw)((uAOHk_01yBIKmZ5;0U!VbfB+Bx q0yjl~-2V^r|C>SunScNg00KY&2mk>f00e*l5C8%|00`W+1pWtqNzqRL literal 0 HcmV?d00001 diff --git a/README.md b/README.md index feb11d93..3359cfca 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ source env/bin/activate # go out of old venv deactivate # delete old venv -rm -r env +rm -r .venv # create new venv -python3 -m venv env +python3 -m venv .venv # activate new venv -source env/bin/activate +source .venv/bin/activate ``` ### Install dependencies diff --git a/mypy.ini b/mypy.ini index b3bd0382..e1376e8c 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,5 @@ [mypy] -plugins = numpy.typing.mypy_plugin, pydantic.mypy +plugins = pydantic.mypy [mypy-geopandas.*] ignore_missing_imports = True diff --git a/pyproject.toml b/pyproject.toml index 6c86b5f7..206c57d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,23 +16,23 @@ readme = { file = "README.md", content-type = "text/markdown" } license-files = ["LICENSE"] requires-python = ">=3.10" dependencies = [ - "geoengine-openapi-client == 0.0.26", + "geoengine-openapi-client == 0.0.27", "geopandas >=1.0,<2.0", "matplotlib >=3.5,<3.11", "numpy >=1.21,<2.4", - "owslib >=0.27,<0.35", - "pillow >=10.0,<12", - "pyarrow >=17.0,<21", - "python-dotenv >=0.19,<1.2", + "owslib >=0.27,<0.36", + "pillow >=10.0,<13", + "pyarrow >=17.0,<23", + "python-dotenv >=0.19,<1.3", "rasterio >=1.3,<2", "requests >= 2.26,<3", - "rioxarray >=0.9.1, <0.20", + "rioxarray >=0.9.1, <0.21", "StrEnum >=0.4.6,<0.5", # TODO: use from stdlib when `python_requires = >=3.11` "vega >= 3.5,<4.2", "websockets >= 14.2,<16", - "xarray >=0.19,<2025.8", + "xarray >=0.19,<2025.10", "urllib3 >= 2.1, < 2.6", - "pydantic >= 2.10.6, < 2.12", + "pydantic >= 2.10.6, < 2.13", 'skl2onnx >=1.19.1,<1.20', ] @@ -42,12 +42,12 @@ Repository = "https://github.com/geo-engine/geoengine-python" [project.optional-dependencies] # TODO: use [dependency-groups] in the future dev = [ - "build >=0.7,<1.3", + "build >=0.7,<1.4", "mypy >=1.14,<2.0", "pdoc3 >=0.10,<0.12", "ruff >=0.12.3,<0.13", # formatter & linter "setuptools >=62,<81", - "twine >=3.4,<6.2", # PyPI + "twine >=3.4,<6.3", # PyPI "types-requests >=2.26,<3", # mypy type hints "types-setuptools >=71.1,<81", # mypy type hints "wheel >=0.37,<0.46", @@ -55,12 +55,12 @@ dev = [ test = [ "psycopg >=3.2,<4", "pytest >=6.3,<9", - "pytest-cov >=6.0,<7", + "pytest-cov >=6.0,<7.1", "requests_mock >=1.9,<2", "scikit-learn >=1.5,<1.8", ] examples = [ - "cartopy >=0.22,<0.25", # for WMS example + "cartopy >=0.22,<0.26", # for WMS example "ipympl >=0.9.4,<0.10", # for ML example "ipyvuetify >=1.10,<1.12", # for ML app "ipywidgets >=8.1.5,<9", # for ML example diff --git a/tests/test_ml.py b/tests/test_ml.py index ad8e6597..d65d4434 100644 --- a/tests/test_ml.py +++ b/tests/test_ml.py @@ -27,22 +27,25 @@ class MlModelTests(unittest.TestCase): def setUp(self) -> None: ge.reset(False) - def test_model_dim_to_tensorshape(self): + def test_model_dim_to_tensorshape(self) -> None: """Test model_dim_to_tensorshape""" dim_1d: list[TSP.Dimension] = [TSP.Dimension(dim_value=7)] mts_1d = MlTensorShape3D(bands=7, y=1, x=1) self.assertEqual(model_dim_to_tensorshape(dim_1d), mts_1d) - dim_1d_v: list[TSP.Dimension] = [TSP.Dimension(dim_value=None), TSP.Dimension(dim_value=7)] + dim_1d_v: list[TSP.Dimension] = [TSP.Dimension( + dim_value=None), TSP.Dimension(dim_value=7)] mts_1d_v = MlTensorShape3D(bands=7, y=1, x=1) self.assertEqual(model_dim_to_tensorshape(dim_1d_v), mts_1d_v) - dim_2d_t: list[TSP.Dimension] = [TSP.Dimension(dim_value=512), TSP.Dimension(dim_value=512)] + dim_2d_t: list[TSP.Dimension] = [TSP.Dimension( + dim_value=512), TSP.Dimension(dim_value=512)] mts_2d_t = MlTensorShape3D(bands=1, y=512, x=512) self.assertEqual(model_dim_to_tensorshape(dim_2d_t), mts_2d_t) - dim_2d_1: list[TSP.Dimension] = [TSP.Dimension(dim_value=1), TSP.Dimension(dim_value=7)] + dim_2d_1: list[TSP.Dimension] = [TSP.Dimension( + dim_value=1), TSP.Dimension(dim_value=7)] mts_2d_1 = MlTensorShape3D(bands=7, y=1, x=1) self.assertEqual(model_dim_to_tensorshape(dim_2d_1), mts_2d_1) @@ -77,7 +80,8 @@ def test_uploading_onnx_model(self): training_y = np.array([0, 1], dtype=np.int64) clf.fit(training_x, training_y) - onnx_clf = to_onnx(clf, training_x[:1], options={"zipmap": False}, target_opset=9) + onnx_clf = to_onnx(clf, training_x[:1], options={ + "zipmap": False}, target_opset=9) # TODO: use `enterContext(cm)` instead of `with cm:` in Python 3.11 with GeoEngineTestInstance() as ge_instance: @@ -112,7 +116,8 @@ def test_uploading_onnx_model(self): self.assertEqual(str(res_name), model_name) # Now test permission setting and removal - ge.add_permission(ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name(res_name), ge.Permission.READ) + ge.add_permission(ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name( + res_name), ge.Permission.READ) expected = ge.permissions.PermissionListing( permission=ge.Permission.READ, @@ -120,13 +125,16 @@ def test_uploading_onnx_model(self): role=ge.permissions.Role(ge.REGISTERED_USER_ROLE_ID, "user"), ) - self.assertIn(expected, ge.permissions.list_permissions(ge.Resource.from_ml_model_name(res_name))) + self.assertIn(expected, ge.permissions.list_permissions( + ge.Resource.from_ml_model_name(res_name))) ge.remove_permission( - ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name(res_name), ge.Permission.READ + ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name( + res_name), ge.Permission.READ ) - self.assertNotIn(expected, ge.permissions.list_permissions(ge.Resource.from_ml_model_name(res_name))) + self.assertNotIn(expected, ge.permissions.list_permissions( + ge.Resource.from_ml_model_name(res_name))) # failing tests with self.assertRaises(ge.InputException) as exception: From 34d3077d6a9a2f501642fbbf767802e56bb46912 Mon Sep 17 00:00:00 2001 From: Christian Beilschmidt Date: Thu, 6 Nov 2025 08:53:22 +0100 Subject: [PATCH 2/2] format --- tests/test_ml.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/test_ml.py b/tests/test_ml.py index d65d4434..f10ddb18 100644 --- a/tests/test_ml.py +++ b/tests/test_ml.py @@ -34,18 +34,15 @@ def test_model_dim_to_tensorshape(self) -> None: mts_1d = MlTensorShape3D(bands=7, y=1, x=1) self.assertEqual(model_dim_to_tensorshape(dim_1d), mts_1d) - dim_1d_v: list[TSP.Dimension] = [TSP.Dimension( - dim_value=None), TSP.Dimension(dim_value=7)] + dim_1d_v: list[TSP.Dimension] = [TSP.Dimension(dim_value=None), TSP.Dimension(dim_value=7)] mts_1d_v = MlTensorShape3D(bands=7, y=1, x=1) self.assertEqual(model_dim_to_tensorshape(dim_1d_v), mts_1d_v) - dim_2d_t: list[TSP.Dimension] = [TSP.Dimension( - dim_value=512), TSP.Dimension(dim_value=512)] + dim_2d_t: list[TSP.Dimension] = [TSP.Dimension(dim_value=512), TSP.Dimension(dim_value=512)] mts_2d_t = MlTensorShape3D(bands=1, y=512, x=512) self.assertEqual(model_dim_to_tensorshape(dim_2d_t), mts_2d_t) - dim_2d_1: list[TSP.Dimension] = [TSP.Dimension( - dim_value=1), TSP.Dimension(dim_value=7)] + dim_2d_1: list[TSP.Dimension] = [TSP.Dimension(dim_value=1), TSP.Dimension(dim_value=7)] mts_2d_1 = MlTensorShape3D(bands=7, y=1, x=1) self.assertEqual(model_dim_to_tensorshape(dim_2d_1), mts_2d_1) @@ -80,8 +77,7 @@ def test_uploading_onnx_model(self): training_y = np.array([0, 1], dtype=np.int64) clf.fit(training_x, training_y) - onnx_clf = to_onnx(clf, training_x[:1], options={ - "zipmap": False}, target_opset=9) + onnx_clf = to_onnx(clf, training_x[:1], options={"zipmap": False}, target_opset=9) # TODO: use `enterContext(cm)` instead of `with cm:` in Python 3.11 with GeoEngineTestInstance() as ge_instance: @@ -116,8 +112,7 @@ def test_uploading_onnx_model(self): self.assertEqual(str(res_name), model_name) # Now test permission setting and removal - ge.add_permission(ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name( - res_name), ge.Permission.READ) + ge.add_permission(ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name(res_name), ge.Permission.READ) expected = ge.permissions.PermissionListing( permission=ge.Permission.READ, @@ -125,16 +120,13 @@ def test_uploading_onnx_model(self): role=ge.permissions.Role(ge.REGISTERED_USER_ROLE_ID, "user"), ) - self.assertIn(expected, ge.permissions.list_permissions( - ge.Resource.from_ml_model_name(res_name))) + self.assertIn(expected, ge.permissions.list_permissions(ge.Resource.from_ml_model_name(res_name))) ge.remove_permission( - ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name( - res_name), ge.Permission.READ + ge.REGISTERED_USER_ROLE_ID, ge.Resource.from_ml_model_name(res_name), ge.Permission.READ ) - self.assertNotIn(expected, ge.permissions.list_permissions( - ge.Resource.from_ml_model_name(res_name))) + self.assertNotIn(expected, ge.permissions.list_permissions(ge.Resource.from_ml_model_name(res_name))) # failing tests with self.assertRaises(ge.InputException) as exception: