← Back to team overview

sts-sponsors team mailing list archive

[Merge] ~ack/maas-site-manager:timezone-text into maas-site-manager:main

 

Alberto Donato has proposed merging ~ack/maas-site-manager:timezone-text into maas-site-manager:main.

Commit message:
change timezone field to text, validate with pytz



Requested reviews:
  MAAS Committers (maas-committers)

For more details, see:
https://code.launchpad.net/~ack/maas-site-manager/+git/site-manager/+merge/441547
-- 
Your team MAAS Committers is requested to review the proposed merge of ~ack/maas-site-manager:timezone-text into maas-site-manager:main.
diff --git a/backend/msm/db/_tables.py b/backend/msm/db/_tables.py
index ed63497..05ae82c 100644
--- a/backend/msm/db/_tables.py
+++ b/backend/msm/db/_tables.py
@@ -6,7 +6,6 @@ from sqlalchemy import (
     ForeignKey,
     Integer,
     MetaData,
-    Numeric,
     Table,
     Text,
 )
@@ -27,8 +26,7 @@ Site = Table(
     Column("note", Text),
     Column("region", Text),
     Column("street", Text),
-    # Timezones need be up to x.25 accuracy
-    Column("timezone", Numeric(precision=3, scale=2)),
+    Column("timezone", Text),
     Column("url", Text),
 )
 
diff --git a/backend/msm/db/queries.py b/backend/msm/db/queries.py
index c8369f9..60ecee9 100644
--- a/backend/msm/db/queries.py
+++ b/backend/msm/db/queries.py
@@ -82,7 +82,7 @@ async def get_filtered_sites(
     note: list[str] | None = None,
     region: list[str] | None = None,
     street: list[str] | None = None,
-    timezone: list[float] | None = None,
+    timezone: list[str] | None = None,
     url: list[str] | None = None,
 ) -> tuple[int, Iterable[SiteSchema]]:
     filters = filters_from_arguments(
diff --git a/backend/msm/schema/_models.py b/backend/msm/schema/_models.py
index 6128eec..9a80683 100644
--- a/backend/msm/schema/_models.py
+++ b/backend/msm/schema/_models.py
@@ -10,9 +10,14 @@ from pydantic import (
     SecretStr,
 )
 from pydantic.fields import Field
+import pytz
+from strenum import StrEnum
 
 from ._pagination import PaginatedResults
 
+# Enum with timezones accepted by pytz.
+TimeZone = StrEnum("TimeZone", pytz.all_timezones)
+
 
 class CreateUser(BaseModel):
     """
@@ -43,7 +48,7 @@ class CreateSite(BaseModel):
     note: str | None
     region: str | None
     street: str | None
-    timezone: str | None
+    timezone: TimeZone | None  # type: ignore
     url: str
     # TODO: we will need to add tags
 
diff --git a/backend/msm/user_api/_forms.py b/backend/msm/user_api/_forms.py
index 0f2d9b6..d6d2cf7 100644
--- a/backend/msm/user_api/_forms.py
+++ b/backend/msm/user_api/_forms.py
@@ -12,7 +12,7 @@ class SiteFilterParams(NamedTuple):
     note: list[str] | None
     region: list[str] | None
     street: list[str] | None
-    timezone: list[float] | None
+    timezone: list[str] | None
     url: list[str] | None
 
 
@@ -24,7 +24,7 @@ async def site_filter_parameters(
     note: list[str] | None = Query(default=None, title="Filter for notes"),
     region: list[str] | None = Query(default=None, title="Filter for regions"),
     street: list[str] | None = Query(default=None, title="Filter for streets"),
-    timezone: list[float]
+    timezone: list[str]
     | None = Query(default=None, title="Filter for timezones"),
     url: list[str] | None = Query(default=None, title="Filter for urls"),
 ) -> SiteFilterParams:
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index 74f6260..6a7a46a 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -19,7 +19,9 @@ requires-python = ">=3.10"
 dependencies = [
   "fastapi",
   "pydantic[email]",
+  "pytz",
   "SQLAlchemy[postgresql_asyncpg]",
+  "StrEnum", # emulate enum.StrEnum, which is available in Python3.11
 ]
 [project.optional-dependencies]
 testing = [
@@ -59,9 +61,10 @@ junit_logging = "all"
 junit_suite_name = "maas-site-manager backend tests"
 
 [tool.mypy]
+ignore_missing_imports = true
 install_types = true
 non_interactive = true
-strict = true
 plugins = [
   "pydantic.mypy"
 ]
+strict = true
diff --git a/backend/tests/user_api/test_handlers.py b/backend/tests/user_api/test_handlers.py
index 9a2511e..9ff4dde 100644
--- a/backend/tests/user_api/test_handlers.py
+++ b/backend/tests/user_api/test_handlers.py
@@ -50,17 +50,20 @@ async def test_list_sites(
         "note": "the first site",
         "region": "Blue Fin Bldg",
         "street": "110 Southwark St",
-        "timezone": "0.00",
+        "timezone": "Europe/London",
         "url": "https://londoncalling.example.com";,
     }
     site2 = site1.copy()
-    site2["name"] = "BerlinHQ"
-    site2["timezone"] = "1.00"
-    site2["city"] = "Berlin"
-    site2["country"] = "de"
+    site2.update(
+        {
+            "name": "BerlinHQ",
+            "timezone": "Europe/Berlin",
+            "city": "Berlin",
+            "country": "de",
+        }
+    )
     sites = await fixture.create("site", [site1, site2])
     for site in sites:
-        site["timezone"] = str(site["timezone"])
         site["stats"] = None
     page1 = await user_app_client.get("/sites")
     assert page1.status_code == 200
@@ -101,18 +104,21 @@ async def test_list_sites_filter_timezone(
         "note": "the first site",
         "region": "Blue Fin Bldg",
         "street": "110 Southwark St",
-        "timezone": "3.00",
+        "timezone": "Europe/London",
         "url": "https://londoncalling.example.com";,
     }
     site2 = site1.copy()
-    site2["name"] = "BerlinHQ"
-    site2["timezone"] = "1.00"
-    site2["city"] = "Berlin"
-    site2["country"] = "de"
+    site2.update(
+        {
+            "name": "BerlinHQ",
+            "timezone": "Europe/Berlin",
+            "city": "Berlin",
+            "country": "de",
+        }
+    )
     [created_site, _] = await fixture.create("site", [site1, site2])
-    created_site["timezone"] = str(created_site["timezone"])
     created_site["stats"] = None
-    page1 = await user_app_client.get("/sites?timezone=3.0")
+    page1 = await user_app_client.get("/sites?timezone=Europe/London")
     assert page1.status_code == 200
     assert page1.json() == {
         "page": 1,
@@ -138,7 +144,7 @@ async def test_list_sites_with_stats(
                 "note": "the first site",
                 "region": "Blue Fin Bldg",
                 "street": "110 Southwark St",
-                "timezone": "0.00",
+                "timezone": "Europe/London",
                 "url": "https://londoncalling.example.com";,
             }
         ],
@@ -159,7 +165,6 @@ async def test_list_sites_with_stats(
     del site_data["id"]
     del site_data["site_id"]
     site_data["last_seen"] = site_data["last_seen"].isoformat()
-    site["timezone"] = str(site["timezone"])
     site["stats"] = site_data
 
     page = await user_app_client.get("/sites")
diff --git a/test-data/sites.csv b/test-data/sites.csv
index 1218db3..9798eba 100644
--- a/test-data/sites.csv
+++ b/test-data/sites.csv
@@ -1,9 +1,9 @@
 id,city, country, latitude, longitude, name, note, region, street, timezone, url
-1,London,GB,51.501990,-0.092200,Canonical Group Limited,4th Floor,,201 Borough High Street,0.0,https://london.canonical.example.com
-2,Austin,US,30.269612,-97.741057,Canonical USA Inc.,Perry Brooks Building - Suite 300,,720 Brazos Street,-5.0,https://austin.canonical.example.com
-3,Boston,US,42.358859,-71.059615,Canonical USA Inc. 001,Suite 210,,18 Tremont Street,-4.0,https://boston.canonical.example.com
-4,Shanghai,CN,31.187270,121.436829,Canonical China,上海市漕溪北路331号12楼1246室,,No. 331 North Caoxi Road,+8.0,https://shanghai.canonical.example.com
-5,Beijing,CN,39.908447,116.448690,Canonical China 001,China World Office 1; 北京市朝阳区建国门外大街1号国贸写字楼1座11层1118-19室 100004,Chaoyang District,1 Jianguomenwai Avenue,+8.0,https://shanghai.canonical.example.com
-6,Taipei City,TW,25.058098,121.543406,Canonical Group Limited - Taiwan Branch,105402 台北市松山區民生東路三段100號12樓,Songshan Dist.,"12F.,No. 100,Sec. 3,Minsheng E. Rd.",+8.0,https://taiwan.canonical.example.com
-7,Douglas,IM,54.153072,-4.481012,Canonical Limited,2nd Floor - Clarendon House,,Victoria Street,0,https://canonical.example.com
-8,Tokyo,JP,35.673242,139.740669,Canonical Japan K.K,3rd Floor - Sanno Park Tower,,2-11-1 Nagata-cho Chiyoda-ku,9.0,https://japan.canonical.example.com
+1,London,GB,51.501990,-0.092200,Canonical Group Limited,4th Floor,,201 Borough High Street,Europe/London,https://london.canonical.example.com
+2,Austin,US,30.269612,-97.741057,Canonical USA Inc.,Perry Brooks Building - Suite 300,,720 Brazos Street,America/Chicago,https://austin.canonical.example.com
+3,Boston,US,42.358859,-71.059615,Canonical USA Inc. 001,Suite 210,,18 Tremont Street,America/Chicago,https://boston.canonical.example.com
+4,Shanghai,CN,31.187270,121.436829,Canonical China,上海市漕溪北路331号12楼1246室,,No. 331 North Caoxi Road,Asia/Shanghai,https://shanghai.canonical.example.com
+5,Beijing,CN,39.908447,116.448690,Canonical China 001,China World Office 1; 北京市朝阳区建国门外大街1号国贸写字楼1座11层1118-19室 100004,Chaoyang District,1 Jianguomenwai Avenue,Asia/Shanghai,https://shanghai.canonical.example.com
+6,Taipei City,TW,25.058098,121.543406,Canonical Group Limited - Taiwan Branch,105402 台北市松山區民生東路三段100號12樓,Songshan Dist.,"12F.,No. 100,Sec. 3,Minsheng E. Rd.",Asia/Taipei,https://taiwan.canonical.example.com
+7,Douglas,IM,54.153072,-4.481012,Canonical Limited,2nd Floor - Clarendon House,,Victoria Street,Europe/London,https://canonical.example.com
+8,Tokyo,JP,35.673242,139.740669,Canonical Japan K.K,3rd Floor - Sanno Park Tower,,2-11-1 Nagata-cho Chiyoda-ku,Japan,https://japan.canonical.example.com

Follow ups