Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

WIP: Sync with titiler #7

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,4 @@ ENV/
.mypy_cache/

cdk.out/
cdk.context.json
20 changes: 10 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
repos:
- repo: https://github.com/psf/black
rev: 19.10b0
rev: 23.11.0
hooks:
- id: black
language_version: python3.7
language_version: python
args: ["--safe"]

- repo: https://github.com/PyCQA/isort
rev: 5.4.2
rev: 5.12.0
hooks:
- id: isort
language_version: python3.7
language_version: python

- repo: https://github.com/PyCQA/flake8
rev: 3.8.3
rev: 6.1.0
hooks:
- id: flake8
language_version: python3.7
language_version: python
args: [
# E501 let black handle all line length decisions
# W503 black conflicts with "line break before operator" rule
Expand All @@ -25,10 +25,10 @@ repos:
]

- repo: https://github.com/PyCQA/pydocstyle
rev: 5.1.1
rev: 6.3.0
hooks:
- id: pydocstyle
language_version: python3.7
language_version: python
args: [
# Check for docstring presence only
"--select=D1",
Expand All @@ -37,8 +37,8 @@ repos:
]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.770
rev: v1.7.0
hooks:
- id: mypy
language_version: python3.7
language_version: python
args: ["--no-strict-optional", "--ignore-missing-imports"]
30 changes: 16 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
FROM lambci/lambda:build-python3.8
FROM public.ecr.aws/lambda/python:3.9

WORKDIR /tmp

COPY setup.py setup.py
COPY titiler_pds/ titiler_pds/
COPY setup.py ${LAMBDA_TASK_ROOT}
COPY titiler_pds/ ${LAMBDA_TASK_ROOT}/titiler_pds/

# Install dependencies
RUN pip install . rasterio==1.1.8 -t /var/task --no-binary numpy,pydantic

# Leave module precompiles for faster Lambda startup
RUN cd /var/task && find . -type f -name '*.pyc' | while read f; do n=$(echo $f | sed 's/__pycache__\///' | sed 's/.cpython-[2-3][0-9]//'); cp $f $n; done;
RUN cd /var/task && find . -type d -a -name '__pycache__' -print0 | xargs -0 rm -rf
RUN cd /var/task && find . -type f -a -name '*.py' -print0 | xargs -0 rm -f
RUN cd /var/task && find . -type d -a -name 'tests' -print0 | xargs -0 rm -rf
RUN rm -rdf /var/task/numpy/doc/
RUN rm -rdf /var/task/stack
RUN pip3 install titiler_pds/rio_tiler_pds-0.7.0-py3-none-any.whl -t ${LAMBDA_TASK_ROOT} && \
pip3 install . rasterio==1.3a2 -t ${LAMBDA_TASK_ROOT} && \
\
echo "Leave module precompiles for faster Lambda startup" && \
cd ${LAMBDA_TASK_ROOT} && find . -type f -name '*.pyc' | \
while read f; do n=$(echo $f | sed 's/__pycache__\///' | sed 's/.cpython-[2-3][0-9]//'); cp $f $n; done && \
\
cd ${LAMBDA_TASK_ROOT} && find . -type d -a -name '__pycache__' -print0 | xargs -0 rm -rf && \
cd ${LAMBDA_TASK_ROOT} && find . -type f -a -name '*.py' -print0 | grep -v handler.py | xargs -0 rm -f && \
cd ${LAMBDA_TASK_ROOT} && find . -type d -a -name 'tests' -print0 | xargs -0 rm -rf && \
rm -rdf ${LAMBDA_TASK_ROOT}/numpy/doc/ && \
rm -rdf ${LAMBDA_TASK_ROOT}/stack

CMD [ "titiler_pds.handler.handler" ]
19 changes: 11 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@
from setuptools import find_packages, setup

inst_reqs = [
"titiler>=0.1.0,<0.2",
"brotli-asgi>=1.1.0",
"titiler.core>=0.7.0",
"titiler.mosaic>=0.7.0",
"titiler.application>=0.7.0",
"tilebench",
"rio-tiler-pds>=0.5.0,<1.0",
"rio-tiler-pds>=0.7.0,<1.0",
"mangum>=0.10",
]

extra_reqs = {
"deploy": [
"aws-cdk.core==1.76.0",
"aws-cdk.aws_lambda==1.76.0",
"aws-cdk.aws_apigatewayv2==1.76.0",
"aws-cdk.aws_apigatewayv2_integrations==1.76.0",
"aws-cdk.core==1.160.0",
"aws-cdk.aws_lambda==1.160.0",
"aws-cdk.aws_apigatewayv2==1.160.0",
"aws-cdk.aws_apigatewayv2_integrations==1.160.0",
],
"test": ["pytest", "pytest-cov", "pytest-asyncio", "requests"],
}


setup(
name="titiler_pds",
version="0.0.1",
description=u"TiTiler for AWS Public Dataset",
version="0.1.0",
description="TiTiler for AWS Public Dataset",
python_requires=">=3",
classifiers=[
"Intended Audience :: Information Technology",
Expand Down
20 changes: 7 additions & 13 deletions stack/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(
id: str,
memory: int = 1024,
timeout: int = 30,
runtime: aws_lambda.Runtime = aws_lambda.Runtime.PYTHON_3_8,
runtime: aws_lambda.Runtime = aws_lambda.Runtime.FROM_IMAGE,
concurrent: Optional[int] = None,
permissions: Optional[List[iam.PolicyStatement]] = None,
env: dict = {},
Expand All @@ -59,16 +59,10 @@ def __init__(
self,
f"{id}-lambda",
runtime=runtime,
code=aws_lambda.Code.from_asset(
path=os.path.abspath(code_dir),
bundling=core.BundlingOptions(
image=core.BundlingDockerImage.from_asset(
os.path.abspath(code_dir), file="Dockerfile",
),
command=["bash", "-c", "cp -R /var/task/. /asset-output/."],
),
code=aws_lambda.Code.from_asset_image(
directory=os.path.abspath(code_dir),
),
handler="titiler_pds.handler.handler",
handler=aws_lambda.Handler.FROM_IMAGE,
memory_size=memory,
reserved_concurrent_executions=concurrent,
timeout=core.Duration.seconds(timeout),
Expand All @@ -81,8 +75,8 @@ def __init__(
api = apigw.HttpApi(
self,
f"{id}-endpoint",
default_integration=apigw_integrations.LambdaProxyIntegration(
handler=lambda_function
default_integration=apigw_integrations.HttpLambdaIntegration(
id=f"{id}-endpoint-lambda", handler=lambda_function
),
)
core.CfnOutput(self, "Endpoint", value=api.url)
Expand Down Expand Up @@ -124,7 +118,7 @@ def __init__(
"Client": settings.client,
}.items():
if value:
core.Tag.add(app, key, value)
core.Tag(key, value, apply_to_launched_instances=False)


LambdaStack(
Expand Down
21 changes: 15 additions & 6 deletions titiler_pds/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from rio_tiler_pds.landsat.utils import sceneid_parser as l8_sceneid_parser
from rio_tiler_pds.sentinel.utils import s2_sceneid_parser

from titiler.dependencies import DefaultDependency
from titiler.core.dependencies import DefaultDependency

from .settings import mosaic_config

Expand All @@ -21,7 +21,7 @@ class CustomPathParams:
sceneid: str = Query(..., description="Sceneid.")
scene_metadata: Dict = field(init=False)

def __post_init__(self,):
def __post_init__(self):
"""Define dataset URL."""
self.url = self.sceneid
if re.match(
Expand All @@ -46,10 +46,16 @@ def __post_init__(self,):
):
self.scene_metadata = l8_sceneid_parser(self.sceneid)

def __str__(self):
"""to string"""
return self.sceneid


def BandsParams(
bands: str = Query(
..., title="bands names", description="comma (',') delimited bands names.",
...,
title="bands names",
description="comma (',') delimited bands names.",
)
) -> Sequence[str]:
"""Bands."""
Expand All @@ -61,7 +67,9 @@ class BandsExprParams(DefaultDependency):
"""Band names and Expression parameters."""

bands: Optional[str] = Query(
None, title="bands names", description="comma (',') delimited bands names.",
None,
title="bands names",
description="comma (',') delimited bands names.",
)
expression: Optional[str] = Query(
None,
Expand All @@ -83,14 +91,15 @@ class MosaicParams:

layer: str = Query(..., description="Mosaic Layer name ('{username}.{layer}')")

def __post_init__(self,):
def __post_init__(self):
"""Define mosaic URL."""
pattern = (
r"^(?P<username>[a-zA-Z0-9-_]{1,32})\.(?P<layername>[a-zA-Z0-9-_]{1,32})$"
)
if not re.match(pattern, self.layer):
raise HTTPException(
status_code=400, detail=f"Invalid layer name: `{self.layer}`",
status_code=400,
detail=f"Invalid layer name: `{self.layer}`",
)
if mosaic_config.backend == "dynamodb://":
self.url = f"{mosaic_config.backend}{mosaic_config.host}:{self.layer}"
Expand Down
2 changes: 1 addition & 1 deletion titiler_pds/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
logging.getLogger("mangum.lifespan").setLevel(logging.ERROR)
logging.getLogger("mangum.http").setLevel(logging.ERROR)

handler = Mangum(app, lifespan="auto", log_level="error")
handler = Mangum(app, lifespan="auto")
4 changes: 2 additions & 2 deletions titiler_pds/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from brotli_asgi import BrotliMiddleware
from tilebench.middleware import VSIStatsMiddleware

from titiler.errors import DEFAULT_STATUS_CODES, add_exception_handlers
from titiler.middleware import CacheControlMiddleware, TotalTimeMiddleware
from titiler.application.middleware import CacheControlMiddleware, TotalTimeMiddleware
from titiler.core.errors import DEFAULT_STATUS_CODES, add_exception_handlers

from .routes import landsat_collection2, naip, sentinel
from .settings import api_config
Expand Down
Binary file added titiler_pds/rio_tiler_pds-0.7.0-py3-none-any.whl
Binary file not shown.
9 changes: 5 additions & 4 deletions titiler_pds/routes/landsat.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""Landsat endpoint."""

from rio_tiler_pds.landsat.aws import L8Reader
from rio_tiler_pds.landsat.aws.landsat8 import L8Reader

from titiler.custom.routing import apiroute_factory
from titiler.dependencies import BandsExprParams
from titiler.endpoints.factory import MosaicTilerFactory, MultiBandTilerFactory
from titiler.core.dependencies import BandsExprParams
from titiler.core.factory import MultiBandTilerFactory
from titiler.core.routing import apiroute_factory
from titiler.mosaic.factory import MosaicTilerFactory

from ..dependencies import CustomPathParams, MosaicParams

Expand Down
9 changes: 5 additions & 4 deletions titiler_pds/routes/landsat_collection2.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""Landsat endpoint."""

from rio_tiler_pds.landsat.aws import LandsatC2Reader
from rio_tiler_pds.landsat.aws.landsat_collection2 import LandsatC2Reader

from titiler.custom.routing import apiroute_factory
from titiler.dependencies import BandsExprParams
from titiler.endpoints.factory import MosaicTilerFactory, MultiBandTilerFactory
from titiler.core.dependencies import BandsExprParams
from titiler.core.factory import MultiBandTilerFactory
from titiler.core.routing import apiroute_factory
from titiler.mosaic.factory import MosaicTilerFactory

from ..dependencies import CustomPathParams, MosaicParams

Expand Down
8 changes: 4 additions & 4 deletions titiler_pds/routes/naip.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""NAIP endpoint."""

from titiler.custom.routing import apiroute_factory
from titiler.endpoints.factory import MosaicTilerFactory
from titiler.resources.enums import OptionalHeaders
from titiler.core.resources.enums import OptionalHeader
from titiler.core.routing import apiroute_factory
from titiler.mosaic.factory import MosaicTilerFactory

from ..dependencies import MosaicParams

Expand All @@ -20,5 +20,5 @@
path_dependency=MosaicParams,
router_prefix="mosaicjson/naip",
router=APIRouter(route_class=route_class),
optional_headers=[OptionalHeaders.server_timing, OptionalHeaders.x_assets],
optional_headers=[OptionalHeader.server_timing, OptionalHeader.x_assets],
)
8 changes: 4 additions & 4 deletions titiler_pds/routes/sentinel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

from rio_tiler_pds.sentinel.aws import S2COGReader

from titiler.custom.routing import apiroute_factory
from titiler.dependencies import BandsExprParams
from titiler.endpoints.factory import MosaicTilerFactory, MultiBandTilerFactory
from titiler.core.dependencies import BandsExprParams
from titiler.core.factory import MultiBandTilerFactory
from titiler.core.routing import apiroute_factory
from titiler.mosaic.factory import MosaicTilerFactory

from ..dependencies import CustomPathParams, MosaicParams

from fastapi import APIRouter

route_class = apiroute_factory({"AWS_NO_SIGN_REQUEST": "YES"})


scenes = MultiBandTilerFactory(
reader=S2COGReader,
path_dependency=CustomPathParams,
Expand Down