From 4963d0857522fd36714aa76494468d7ed7eb6c19 Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Wed, 27 Mar 2024 15:43:36 +0100 Subject: [PATCH 1/2] avoid serializing and deserializing when not necessary --- tests/test_factories.py | 16 ++++++--- tipg/factory.py | 77 +++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/tests/test_factories.py b/tests/test_factories.py index 078b618d..35dd4076 100644 --- a/tests/test_factories.py +++ b/tests/test_factories.py @@ -30,7 +30,9 @@ def test_features_factory(): landing_link = [link for link in links if link["title"] == "Landing Page"][0] assert landing_link["href"] == "http://testserver/" queryables_link = [ - link for link in links if link["title"] == "Collection queryables" + link + for link in links + if link["title"] == "Collection queryables (Template URL)" ][0] assert ( queryables_link["href"] @@ -68,7 +70,9 @@ def test_features_factory(): landing_link = [link for link in links if link["title"] == "Landing Page"][0] assert landing_link["href"] == "http://testserver/features/" queryables_link = [ - link for link in links if link["title"] == "Collection queryables" + link + for link in links + if link["title"] == "Collection queryables (Template URL)" ][0] assert ( queryables_link["href"] @@ -214,7 +218,9 @@ def test_endpoints_factory(): landing_link = [link for link in links if link["title"] == "Landing Page"][0] assert landing_link["href"] == "http://testserver/" queryables_link = [ - link for link in links if link["title"] == "Collection queryables" + link + for link in links + if link["title"] == "Collection queryables (Template URL)" ][0] assert ( queryables_link["href"] @@ -256,7 +262,9 @@ def test_endpoints_factory(): landing_link = [link for link in links if link["title"] == "Landing Page"][0] assert landing_link["href"] == "http://testserver/ogc/" queryables_link = [ - link for link in links if link["title"] == "Collection queryables" + link + for link in links + if link["title"] == "Collection queryables (Template URL)" ][0] assert ( queryables_link["href"] diff --git a/tipg/factory.py b/tipg/factory.py index 8c540a8e..4071d2ac 100644 --- a/tipg/factory.py +++ b/tipg/factory.py @@ -2,7 +2,6 @@ import abc import csv -import json import re from dataclasses import dataclass, field from typing import Any, Callable, Dict, Generator, Iterable, List, Literal, Optional @@ -113,7 +112,7 @@ def write(self, line: str): def create_html_response( request: Request, - data: str, + data: Any, templates: Jinja2Templates, template_name: str, router_prefix: Optional[str] = None, @@ -142,7 +141,7 @@ def create_html_response( request, name=f"{template_name}.html", context={ - "response": orjson.loads(data), + "response": data, "template": { "api_root": baseurl, "params": request.query_params, @@ -207,7 +206,7 @@ def url_for(self, request: Request, name: str, **path_params: Any) -> str: def _create_html_response( self, request: Request, - data: str, + data: Any, template_name: str, ) -> _TemplateResponse: return create_html_response( @@ -262,7 +261,7 @@ def conformance( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="conformance", ) @@ -325,7 +324,7 @@ def landing( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="landing", ) @@ -354,7 +353,7 @@ def links(self, request: Request) -> List[model.Link]: rel="data", ), model.Link( - title="Collection metadata", + title="Collection metadata (Template URL)", href=self.url_for( request, "collection", @@ -362,9 +361,10 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.json, rel="data", + templated=True, ), model.Link( - title="Collection queryables", + title="Collection queryables (Template URL)", href=self.url_for( request, "queryables", @@ -372,15 +372,17 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.schemajson, rel="queryables", + templated=True, ), model.Link( - title="Collection Features", + title="Collection Features (Template URL)", href=self.url_for(request, "items", collectionId="{collectionId}"), type=MediaType.geojson, rel="data", + templated=True, ), model.Link( - title="Collection Feature", + title="Collection Feature (Template URL)", href=self.url_for( request, "item", @@ -389,6 +391,7 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.geojson, rel="data", + templated=True, ), ] @@ -515,7 +518,7 @@ def collections( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="collections", ) @@ -602,7 +605,7 @@ def collection( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="collection", ) @@ -647,7 +650,7 @@ def queryables( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="queryables", ) @@ -902,7 +905,9 @@ async def items( # noqa: C901 # HTML Response if output_type == MediaType.html: return self._create_html_response( - request, orjsonDumps(data).decode(), template_name="items" + request, + orjson.loads(orjsonDumps(data).decode()), + template_name="items", ) # GeoJSONSeq Response @@ -1067,7 +1072,7 @@ async def item( if output_type == MediaType.html: return self._create_html_response( request, - orjsonDumps(data).decode(), + orjson.loads(orjsonDumps(data).decode()), template_name="item", ) @@ -1091,7 +1096,7 @@ def links(self, request: Request) -> List[model.Link]: """OGC Tiles API links.""" return [ model.Link( - title="Collection Vector Tiles", + title="Collection Vector Tiles (Template URL)", href=self.url_for( request, "collection_get_tile", @@ -1102,9 +1107,10 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.mvt, rel="data", + templated=True, ), model.Link( - title="Collection TileSets", + title="Collection TileSets (Template URL)", href=self.url_for( request, "collection_tileset_list", @@ -1112,9 +1118,10 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.json, rel="data", + templated=True, ), model.Link( - title="Collection TileSet", + title="Collection TileSet (Template URL)", href=self.url_for( request, "collection_tileset", @@ -1123,6 +1130,7 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.json, rel="data", + templated=True, ), model.Link( title="TileMatrixSets", @@ -1134,7 +1142,7 @@ def links(self, request: Request) -> List[model.Link]: rel="data", ), model.Link( - title="TileMatrixSet", + title="TileMatrixSet (Template URL)", href=self.url_for( request, "tilematrixset", @@ -1142,6 +1150,7 @@ def links(self, request: Request) -> List[model.Link]: ), type=MediaType.json, rel="data", + templated=True, ), ] @@ -1201,7 +1210,7 @@ async def tilematrixsets( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="tilematrixsets", ) @@ -1234,23 +1243,20 @@ async def tilematrixset( """ OGC Specification: http://docs.opengeospatial.org/per/19-069.html#_tilematrixset """ - data = self.supported_tms.get(tileMatrixSetId) + tms = self.supported_tms.get(tileMatrixSetId) if output_type == MediaType.html: - # For visualization purpose we add the tms bbox - data = { - **data.model_dump(exclude_none=True, mode="json"), - "bbox": data.bbox, - } return self._create_html_response( request, - json.dumps( - data, - ), + { + **tms.model_dump(exclude_none=True, mode="json"), + # For visualization purpose we add the tms bbox + "bbox": tms.bbox, + }, template_name="tilematrixset", ) - return data + return tms def _tilesets_routes(self): @self.router.get( @@ -1338,7 +1344,7 @@ async def collection_tileset_list( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="tilesets", ) @@ -1452,7 +1458,7 @@ async def collection_tileset( if output_type == MediaType.html: return self._create_html_response( request, - data.model_dump_json(exclude_none=True), + data.model_dump(exclude_none=True, mode="json"), template_name="tileset", ) @@ -1713,12 +1719,7 @@ async def collection_stylejson( minzoom = minzoom if minzoom is not None else tms.minzoom maxzoom = maxzoom if maxzoom is not None else tms.maxzoom - bounds = collection.bounds or [ - 180, - -85.05112877980659, - 180, - 85.0511287798066, - ] + bounds = list(collection.bounds) or list(tms.bbox) style_json = { "name": "TiPg", From 8306684cf20dd0f89fbb58b8558273f969816c7f Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Wed, 27 Mar 2024 16:53:56 +0100 Subject: [PATCH 2/2] update changelog --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index dee98a25..a731db49 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,9 @@ Note: Minor version `0.X.0` update might break the API, It's recommended to pin ## [unreleased] - update leaflet version +- add `templated=True` in template URL links +- add `(Template URL)` in template URL links title +- remove *deserialization* in `tipg.factory.create_html_response` function ## [0.6.3] - 2024-02-02