Skip to content

Commit

Permalink
Merge pull request #172 from developmentseed/feature/avoid-serializat…
Browse files Browse the repository at this point in the history
…ion-deserialization

avoid serializing and deserializing when not necessary
  • Loading branch information
vincentsarago authored Mar 27, 2024
2 parents 9a42606 + 8306684 commit 1edfab5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 42 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 12 additions & 4 deletions tests/test_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down Expand Up @@ -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"]
Expand Down Expand Up @@ -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"]
Expand Down Expand Up @@ -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"]
Expand Down
77 changes: 39 additions & 38 deletions tipg/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -354,33 +353,36 @@ 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",
collectionId="{collectionId}",
),
type=MediaType.json,
rel="data",
templated=True,
),
model.Link(
title="Collection queryables",
title="Collection queryables (Template URL)",
href=self.url_for(
request,
"queryables",
collectionId="{collectionId}",
),
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",
Expand All @@ -389,6 +391,7 @@ def links(self, request: Request) -> List[model.Link]:
),
type=MediaType.geojson,
rel="data",
templated=True,
),
]

Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
)

Expand All @@ -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",
Expand All @@ -1102,19 +1107,21 @@ 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",
collectionId="{collectionId}",
),
type=MediaType.json,
rel="data",
templated=True,
),
model.Link(
title="Collection TileSet",
title="Collection TileSet (Template URL)",
href=self.url_for(
request,
"collection_tileset",
Expand All @@ -1123,6 +1130,7 @@ def links(self, request: Request) -> List[model.Link]:
),
type=MediaType.json,
rel="data",
templated=True,
),
model.Link(
title="TileMatrixSets",
Expand All @@ -1134,14 +1142,15 @@ def links(self, request: Request) -> List[model.Link]:
rel="data",
),
model.Link(
title="TileMatrixSet",
title="TileMatrixSet (Template URL)",
href=self.url_for(
request,
"tilematrixset",
tileMatrixSetId="{tileMatrixSetId}",
),
type=MediaType.json,
rel="data",
templated=True,
),
]

Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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",
)

Expand Down Expand Up @@ -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",
Expand Down

1 comment on commit 1edfab5

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'TiPg Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.30.

Benchmark suite Current: 1edfab5 Previous: 9a42606 Ratio
tests/benchmarks.py::test_benchmark_collections[html-1] 271.68107933836603 iter/sec (stddev: 0.01026253622540092) 454.3978440940236 iter/sec (stddev: 0.00013571234861770574) 1.67
tests/benchmarks.py::test_benchmark_items[html-100] 47.94325715026738 iter/sec (stddev: 0.01738688633923445) 64.76223006458177 iter/sec (stddev: 0.0003876105474827852) 1.35

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.