Skip to content

Commit caa1168

Browse files
authored
Merge pull request #46 from spectriclabs/feat-pydantic-params
Update dependancies and clear CVE's
2 parents becfc4f + e8957eb commit caa1168

File tree

6 files changed

+65
-18
lines changed

6 files changed

+65
-18
lines changed

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ COPY elastic_datashader /build/elastic_datashader
1111
WORKDIR /build/elastic_datashader
1212
RUN poetry build
1313

14-
FROM python:3.11 AS deployment
14+
FROM python:3.11-slim AS deployment
1515
LABEL maintainer="foss@spectric.com"
1616
RUN useradd -d /home/datashader datashader && \
1717
mkdir -p /home/datashader /opt/elastic_datashader/tms-cache && \
@@ -23,8 +23,8 @@ COPY --from=builder /build/dist/*.whl /home/datashader/tmp/
2323
ENV PATH="$PATH:/home/datashader/.local/bin"
2424
RUN pip install --upgrade pip && \
2525
pip install --no-cache-dir /home/datashader/tmp/*.whl && \
26-
pip install gunicorn==20.1.0 && \
27-
pip install uvicorn==0.22.0
26+
pip install gunicorn==21.2.0 && \
27+
pip install uvicorn==0.24.0
2828

2929
COPY deployment/logging_config.yml /opt/elastic_datashader/
3030
COPY deployment/gunicorn_config.py /opt/elastic_datashader/

elastic_datashader/main.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from asyncio import create_task
22

33
from fastapi import FastAPI
4-
4+
from fastapi.middleware.cors import CORSMiddleware
55
import urllib3
66

77
from .cache import background_cache_cleanup
@@ -30,6 +30,19 @@
3030
app.include_router(legend.router)
3131
app.include_router(tms.router)
3232

33+
34+
35+
36+
origins = ["*"]
37+
38+
app.add_middleware(
39+
CORSMiddleware,
40+
allow_origins=origins,
41+
allow_credentials=True,
42+
allow_methods=["*"],
43+
allow_headers=["*"],
44+
)
45+
3346
@app.on_event("startup")
3447
async def app_startup():
3548
create_task(background_cache_cleanup())

elastic_datashader/parameters.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@
1818
from .logger import logger
1919
from .timeutil import quantize_time_range, convert_kibana_time
2020

21+
from pydantic import BaseModel, Field
22+
23+
class SearchParams(BaseModel):
24+
geopoint_field: str
25+
params: dict
26+
cmap: str = Field(default="bym")
27+
resolution:str = Field(default="finest")
28+
span_range:str = Field(default="auto", alias='span')
29+
spread:str = Field(default="auto") # Point Size
30+
timeOverlap:bool = Field(default=False)
31+
timeOverlapSize:str = Field(default="auto")
32+
timestamp_field:str = Field(default="@timestamp")
33+
search_nautical_miles: int = Field(default=50)
34+
geofield_type: str = Field(default='geo_point')
35+
bucket_max: float = Field(default=100, ge=0, le=100)
36+
bucket_min: float = Field(default=0, ge=0, le=1)
2137

2238
def create_default_params() -> Dict[str, Any]:
2339
return {
@@ -287,7 +303,7 @@ def extract_parameters(headers: Dict[Any, Any], query_params: Dict[Any, Any]) ->
287303
params["highlight"] = query_params.get("highlight")
288304
params["spread"] = normalize_spread(query_params.get("spread"))
289305
params["resolution"] = query_params.get("resolution", params["resolution"])
290-
params["use_centroid"] = query_params.get("use_centroid", default=params["use_centroid"])
306+
params["use_centroid"] = query_params.get("use_centroid", params["use_centroid"])
291307
params["cmap"] = get_cmap(query_params.get("cmap", None), category_field)
292308
params["span_range"] = query_params.get("span", "auto")
293309
params["geopoint_field"] = query_params.get("geopoint_field", params["geopoint_field"])

elastic_datashader/routers/tms.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
from typing import Optional
44
import time
55
import uuid
6+
import json
67
from elasticsearch import Elasticsearch
78
from elasticsearch.exceptions import NotFoundError
89
from elasticsearch_dsl import Document
910
from fastapi import APIRouter, BackgroundTasks, HTTPException, Request, Response
10-
from fastapi.responses import RedirectResponse
11+
from fastapi.responses import RedirectResponse, JSONResponse
1112
from starlette.datastructures import URL
1213

1314
from ..cache import (
@@ -26,7 +27,7 @@
2627
from ..drawing import generate_x_tile
2728
from ..elastic import get_es_headers, get_search_base
2829
from ..logger import logger
29-
from ..parameters import extract_parameters, merge_generated_parameters
30+
from ..parameters import extract_parameters, merge_generated_parameters, SearchParams
3031
from ..tilegen import (
3132
TILE_HEIGHT_PX,
3233
TILE_WIDTH_PX,
@@ -148,8 +149,8 @@ def cached_response(es, idx, x, y, z, params, parameter_hash) -> Optional[Respon
148149

149150
try:
150151
es.update( # pylint: disable=E1123
151-
".datashader_tiles",
152-
tile_id(idx, x, y, z, parameter_hash),
152+
index=".datashader_tiles",
153+
id=tile_id(idx, x, y, z, parameter_hash),
153154
body={"script" : {"source": "ctx._source.cache_hits++"}},
154155
retry_on_conflict=5,
155156
)
@@ -281,7 +282,7 @@ def generate_tile_to_cache(idx: str, x: int, y: int, z: int, params, parameter_h
281282
logger.debug("Releasing cache placeholder %s", rendering_tile_name(idx, x, y, z, parameter_hash))
282283
release_cache_placeholder(config.cache_path, rendering_tile_name(idx, x, y, z, parameter_hash))
283284

284-
async def fetch_or_render_tile(already_waited: int, idx: str, x: int, y: int, z: int, request: Request, background_tasks: BackgroundTasks):
285+
async def fetch_or_render_tile(already_waited: int, idx: str, x: int, y: int, z: int, request: Request, background_tasks: BackgroundTasks,post_params={}):
285286
check_proxy_key(request.headers.get('tms-proxy-key'))
286287

287288
es = Elasticsearch(
@@ -292,7 +293,9 @@ async def fetch_or_render_tile(already_waited: int, idx: str, x: int, y: int, z:
292293

293294
# Get hash and parameters
294295
try:
295-
parameter_hash, params = extract_parameters(request.headers, request.query_params)
296+
print(request.query_params)
297+
print(post_params)
298+
parameter_hash, params = extract_parameters(request.headers, {**request.query_params,**post_params})
296299
# try to build the dsl object bad filters cause exceptions that are then retried.
297300
# underlying elasticsearch_dsl doesn't support the elasticsearch 8 api yet so this causes requests to thrash
298301
# If the filters are bad or elasticsearch_dsl cannot build the request will never be completed so serve X tile
@@ -344,3 +347,18 @@ async def get_tms(idx: str, x: int, y: int, z: int, request: Request, background
344347
@router.get("/{already_waited}/{idx}/{z}/{x}/{y}.png")
345348
async def get_tms_after_wait(already_waited: int, idx: str, x: int, y: int, z: int, request: Request, background_tasks: BackgroundTasks):
346349
return await fetch_or_render_tile(already_waited, idx, x, y, z, request, background_tasks)
350+
351+
352+
@router.post("/{idx}/{z}/{x}/{y}.png")
353+
async def post_tile(already_waited: int,idx: str, x: int, y: int, z: int, request: Request,params: SearchParams, background_tasks: BackgroundTasks):
354+
params = params.dict()
355+
params["params"] = json.dumps(params["params"])
356+
response = await fetch_or_render_tile(0, idx, x, y, z, request, background_tasks,post_params=params)
357+
if isinstance(response,RedirectResponse):
358+
print(response.headers)
359+
return JSONResponse(status_code=200, content={"retry-after":response.headers['retry-after']})
360+
return response
361+
362+
363+
364+

elastic_datashader/tilegen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ def generate_tile(idx, x, y, z, headers, params, tile_width_px=256, tile_height_
969969

970970
# Create base search
971971
base_s = get_search_base(config.elastic_hosts, headers, params, idx)
972-
base_s = base_s[0:0]
972+
#base_s = base_s[0:0]
973973
# Now find out how many documents
974974
count_s = copy.copy(base_s)[0:0] # slice of array sets from/size since we are aggregating the data we don't need the hits
975975
count_s = count_s.filter("geo_bounding_box", **{geopoint_field: bb_dict})
@@ -1023,7 +1023,7 @@ def generate_tile(idx, x, y, z, headers, params, tile_width_px=256, tile_height_
10231023
geotile_precision = min(max(current_zoom, current_zoom + agg_zooms), MAXIMUM_PERCISION)
10241024

10251025
tile_s = copy.copy(base_s)
1026-
tile_s = tile_s.params(size=0, track_total_hits=False)
1026+
tile_s = tile_s.params(track_total_hits=False)
10271027
tile_s = tile_s.filter(
10281028
"geo_bounding_box", **{geopoint_field: bb_dict}
10291029
)

pyproject.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ elastic_datashader = "elastic_datashader.cli:main"
2121

2222
[tool.poetry.dependencies]
2323
python = ">=3.10,<4"
24-
elasticsearch = "7.17.4"
25-
elasticsearch-dsl = "7.4.0"
26-
datashader = "0.15.2"
24+
elasticsearch = "8.11.1"
25+
elasticsearch-dsl = "8.11.0"
26+
datashader = "0.16.0"
2727
pandas = "^1.5.3"
2828
colorcet = "^3.0.1"
2929
mercantile = "1.2.1"
@@ -32,11 +32,11 @@ Pillow = "*"
3232
pynumeral = "*"
3333
arrow = "*"
3434
python-datemath = "*"
35-
numba = "0.57.0"
35+
numba = "0.57.1"
3636
numpy = "^1.23"
3737
PyYAML = "*"
3838
humanize = "*"
39-
uvicorn = {extras = ["standard"], version = "^0.18.2", optional = true}
39+
uvicorn = {extras = ["standard"], version = "0.24.0", optional = true}
4040
fastapi = "^0.96"
4141
georgio = "2023.156.924"
4242
jinja2 = "3.1.2"

0 commit comments

Comments
 (0)