Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
- master
jobs:
test-on-pr:
runs-on: windows-latest
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
Expand All @@ -18,12 +18,49 @@ jobs:
with:
python-version: '3.12'

- name: Start pygeoapi container
run: |
docker run --rm -d \
-p 5000:80 \
--rm --name=pygeoapi \
geopython/pygeoapi:latest run-with-hot-reload

- name: Wait for service to be ready
run: |
# This gives the container a few seconds to initialize
timeout 60s bash -c 'until curl -s localhost:5000 > /dev/null; do sleep 2; done'
echo "pygeoapi is up and running"

- name: Enable admin api
run: |
docker exec pygeoapi sed -i 's/admin: .*/admin: true/' /pygeoapi/local.config.yml

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements_dev.txt

- name: Install GUI dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libgl1 \
libegl1 \
libglx-mesa0 \
libglib2.0-0t64 \
libdbus-1-3 \
libxkbcommon-x11-0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-xinerama0 \
libxcb-xinput0 \
libxcb-xfixes0 \
libxcb-shape0

- name: Run unit tests (headless PyQt)
env:
QT_QPA_PLATFORM: offscreen
Expand Down
13 changes: 3 additions & 10 deletions models/ConfigData.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass, field, fields, is_dataclass
from datetime import datetime, timezone
from datetime import datetime
from enum import Enum

from .utils import update_dataclass_from_dict
Expand All @@ -9,6 +9,7 @@
MetadataConfig,
ResourceConfigTemplate,
)
from ..utils.helper_functions import datetime_to_string
from .top_level.utils import InlineList
from .top_level.providers import ProviderTemplate
from .top_level.providers.records import ProviderTypes
Expand Down Expand Up @@ -141,14 +142,6 @@ def all_missing_props(self):
return self._all_missing_props
return []

def datetime_to_string(self, data: datetime):
# normalize to UTC and format with Z
if data.tzinfo is None:
data = data.replace(tzinfo=timezone.utc)
else:
data = data.astimezone(timezone.utc)
return data.strftime("%Y-%m-%dT%H:%M:%SZ")

def asdict_enum_safe(self, obj, datetime_to_str=False):
"""Overwriting dataclass 'asdict' fuction to replace Enums with strings."""
if is_dataclass(obj):
Expand Down Expand Up @@ -177,7 +170,7 @@ def asdict_enum_safe(self, obj, datetime_to_str=False):
}
else:
if isinstance(obj, datetime) and datetime_to_str:
return self.datetime_to_string(obj)
return datetime_to_string(obj)
else:
return obj

Expand Down
14 changes: 0 additions & 14 deletions models/top_level/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,3 @@ def bbox_from_list(raw_bbox_list: list):
)

return InlineList(list_bbox_val)


def to_iso8601(dt: datetime) -> str:
"""
Convert datetime to UTC ISO 8601 string, for both naive and aware datetimes.
"""
if dt.tzinfo is None:
# Treat naive datetime as UTC
dt = dt.replace(tzinfo=timezone.utc)
else:
# Convert to UTC
dt = dt.astimezone(timezone.utc)

return dt.strftime("%Y-%m-%dT%H:%M:%SZ")
20 changes: 9 additions & 11 deletions models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
from types import UnionType
from typing import Any, get_origin, get_args, Union, get_type_hints

from .top_level.utils import InlineList, get_enum_value_from_string
from .top_level.utils import (
InlineList,
get_enum_value_from_string,
)
from ..utils.helper_functions import datetime_from_string


def update_dataclass_from_dict(
Expand Down Expand Up @@ -67,12 +71,7 @@ def update_dataclass_from_dict(
if (datetime in args or expected_type is datetime) and isinstance(
new_value, str
):
try:
new_value = datetime.strptime(
new_value, "%Y-%m-%dT%H:%M:%SZ"
)
except:
pass
new_value = datetime_from_string(new_value)

# Exception: remap str to Enum
elif isinstance(expected_type, type) and issubclass(
Expand Down Expand Up @@ -294,11 +293,10 @@ def _is_instance_of_type(value, expected_type) -> bool:

# Exception: try cast str to datetime manually
if expected_type is datetime:
try:
datetime.strptime(value, "%Y-%m-%dT%H:%M:%SZ")
if datetime_from_string(value) is not None:
return True
except:
pass
else:
return False

# Fallback for normal types
return isinstance(value, expected_type)
Expand Down
Loading