Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: server-mode parallel requests #741

Merged
merged 11 commits into from
Jun 21, 2023
66 changes: 35 additions & 31 deletions eodag/rest/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from contextlib import asynccontextmanager
from distutils import dist
from json.decoder import JSONDecodeError
from typing import List, Union

import pkg_resources
from fastapi import APIRouter as FastAPIRouter
Expand All @@ -31,6 +32,7 @@
from fastapi.openapi.utils import get_openapi
from fastapi.responses import FileResponse, ORJSONResponse
from fastapi.types import Any, Callable, DecoratedCallable
from pydantic import BaseModel
from starlette.exceptions import HTTPException as StarletteHTTPException

from eodag.config import load_stac_api_config
Expand Down Expand Up @@ -271,42 +273,54 @@ def stac_extension_oseo(request: Request):
return jsonable_encoder(response)


class SearchBody(BaseModel):
"""
class which describes the body of a search request
"""

provider: Union[str, None] = None
collections: Union[List[str], str]
datetime: Union[str, None] = None
bbox: Union[list, str, None] = None
limit: Union[int, None] = 20
page: Union[int, None] = 1
query: Union[dict, None] = None


@router.get("/search", tags=["STAC"])
@router.post("/search", tags=["STAC"])
async def stac_search(request: Request):
def stac_search(request: Request, search_body: SearchBody = None):
"""STAC collections items"""
url = request.state.url
url_root = request.state.url_root
try:
body = await request.json()
except JSONDecodeError:

if search_body is None:
body = {}
else:
body = vars(search_body)

arguments = dict(request.query_params, **body)
provider = arguments.pop("provider", None)

response = search_stac_items(
url=url, arguments=arguments, root=url_root, provider=provider
)

resp = ORJSONResponse(
content=response, status_code=200, media_type="application/json"
)
return resp


@router.get("/collections", tags=["Capabilities"])
async def collections(request: Request):
def collections(request: Request):
"""STAC collections

Can be filtered using parameters: instrument, platform, platformSerialIdentifier, sensorType, processingLevel
"""
url = request.state.url
url_root = request.state.url_root
try:
body = await request.json()
except JSONDecodeError:
body = {}

body = {}
arguments = dict(request.query_params, **body)
provider = arguments.pop("provider", None)

Expand All @@ -316,19 +330,16 @@ async def collections(request: Request):
arguments=arguments,
provider=provider,
)

return jsonable_encoder(response)


@router.get("/collections/{collection_id}/items", tags=["Data"])
async def stac_collections_items(collection_id, request: Request):
def stac_collections_items(collection_id, request: Request):
"""STAC collections items"""
url = request.state.url
url_root = request.state.url_root
try:
body = await request.json()
except JSONDecodeError:
body = {}

body = {}
arguments = dict(request.query_params, **body)
provider = arguments.pop("provider", None)

Expand All @@ -339,19 +350,16 @@ async def stac_collections_items(collection_id, request: Request):
provider=provider,
catalogs=[collection_id],
)

return jsonable_encoder(response)


@router.get("/collections/{collection_id}", tags=["Capabilities"])
async def collection_by_id(collection_id, request: Request):
def collection_by_id(collection_id, request: Request):
"""STAC collection by id"""
url = request.state.url
url_root = request.state.url_root
try:
body = await request.json()
except JSONDecodeError:
body = {}

body = {}
arguments = dict(request.query_params, **body)
provider = arguments.pop("provider", None)

Expand All @@ -370,10 +378,8 @@ async def stac_collections_item(collection_id, item_id, request: Request):
"""STAC collection item by id"""
url = request.state.url
url_root = request.state.url_root
try:
body = await request.json()
except JSONDecodeError:
body = {}

body = {}
arguments = dict(request.query_params, **body)
provider = arguments.pop("provider", None)

Expand All @@ -397,12 +403,10 @@ async def stac_collections_item(collection_id, item_id, request: Request):


@router.get("/collections/{collection_id}/items/{item_id}/download", tags=["Data"])
async def stac_collections_item_download(collection_id, item_id, request: Request):
def stac_collections_item_download(collection_id, item_id, request: Request):
"""STAC collection item local download"""
try:
body = await request.json()
except JSONDecodeError:
body = {}

body = {}
arguments = dict(request.query_params, **body)
provider = arguments.pop("provider", None)

Expand Down
6 changes: 4 additions & 2 deletions eodag/rest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@ def get_geometry(arguments):

geom = None

if "bbox" in arguments or "box" in arguments:
if ("bbox" in arguments and arguments["bbox"] is not None) or (
"box" in arguments and arguments["box"] is not None
):
# get bbox
request_bbox = arguments.pop("bbox", None) or arguments.pop("box", None)
if request_bbox and isinstance(request_bbox, str):
Expand Down Expand Up @@ -688,7 +690,7 @@ def search_stac_items(url, arguments, root="/", catalogs=[], provider=None):
arguments.pop("ids")

# get datetime
if "datetime" in arguments.keys():
if "datetime" in arguments.keys() and arguments["datetime"] is not None:
dtime_split = arguments.get("datetime", "").split("/")
if len(dtime_split) > 1:
arguments["dtstart"] = (
Expand Down