diff --git a/.gitignore b/.gitignore index fae014a4..fca284e4 100644 --- a/.gitignore +++ b/.gitignore @@ -114,6 +114,6 @@ venv.bak/ .vscode cdk-deployment/lambda/stac_validator/ -cdk-deployment/lambda/libraries.zip +cdk-deployment/build-libraries/libraries.zip Pipfile* \ No newline at end of file diff --git a/Makefile b/Makefile index 48aec365..43e27f29 100644 --- a/Makefile +++ b/Makefile @@ -22,11 +22,10 @@ build: ## Build a Docker container build-libraries: # Build the libraries for layers. Used internally docker build -f "cdk-deployment/build-libraries/Dockerfile-libraries" -t lambdalayer:latest . docker run -d -it --name lambdalayer lambdalayer:latest - docker cp lambdalayer:code/libraries.zip ./cdk-deployment/lambda + docker cp lambdalayer:code/libraries.zip ./cdk-deployment/build-libraries docker stop lambdalayer docker rm lambdalayer docker rmi lambdalayer - cp -r stac_validator cdk-deployment/lambda build-cdk: ## Build the libraries in preperation for CDK deployment make build-libraries diff --git a/cdk-deployment/app.py b/cdk-deployment/app.py index c55513fa..cab11e71 100644 --- a/cdk-deployment/app.py +++ b/cdk-deployment/app.py @@ -5,9 +5,9 @@ # with examples from the CDK Developer's Guide, which are in the process of # being updated to use `cdk`. You may delete this import if you don't need it. from aws_cdk import core -from validator_cdk.validator_cdk_stack import ValidatorCdkStack +from validator_cdk.validator_cdk_stack import FastAPICdkStack app = core.App() -ValidatorCdkStack(app, "ValidatorCdkStack") +FastAPICdkStack(app, "FastAPICdkStack") app.synth() diff --git a/cdk-deployment/build-libraries/.dockerignore b/cdk-deployment/build-libraries/.dockerignore new file mode 100644 index 00000000..05b10522 --- /dev/null +++ b/cdk-deployment/build-libraries/.dockerignore @@ -0,0 +1,28 @@ +__pycache__ +*.pyc +*.pyo +*.pyd +.Python +env +pip-log.txt +pip-delete-this-directory.txt +.tox +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +*.log +.git +*.swp +package-lock.json +__pycache__ +.pytest_cache +.env +.venv +*.egg-info + +# CDK asset staging directory +.cdk.staging +cdk.out \ No newline at end of file diff --git a/cdk-deployment/build-libraries/Dockerfile-libraries b/cdk-deployment/build-libraries/Dockerfile-libraries index 91498cbd..0b1bd3dd 100644 --- a/cdk-deployment/build-libraries/Dockerfile-libraries +++ b/cdk-deployment/build-libraries/Dockerfile-libraries @@ -4,5 +4,5 @@ COPY . /code/ RUN apt-get -y update && \ apt-get -y install zip unzip && \ python -m pip install --upgrade pip && \ - pip install . requests>=2.19.1 pytest==6.2.2 pystac==0.5.6 jsonschema==3.2.0 click==7.1.2 -t ./python && \ + pip install . mangum uvicorn fastapi[all] requests>=2.19.1 pystac==0.5.6 jsonschema==3.2.0 click==7.1.2 -t ./python && \ zip -r libraries.zip ./python/ \ No newline at end of file diff --git a/cdk-deployment/lambda/lambda.py b/cdk-deployment/lambda/lambda.py index 1040b628..f1974ea8 100644 --- a/cdk-deployment/lambda/lambda.py +++ b/cdk-deployment/lambda/lambda.py @@ -1,39 +1,55 @@ import json import tempfile +from fastapi import FastAPI, Request +from fastapi.middleware.cors import CORSMiddleware +from mangum import Mangum + from stac_validator import stac_validator +app = FastAPI(title="STAC Validator", version=2.0, root_path="/prod/") + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) -def handler(event, context): - body = json.loads(event["body"]) - if body.get("stac_url"): - body = body["stac_url"] - else: - # TODO: Look at alains devops template. store in mem - temp_stac_file = tempfile.NamedTemporaryFile( - delete=False, - mode="w+", - ) - json.dump(body, temp_stac_file) - temp_stac_file.flush() - temp_stac_file.close() - body = temp_stac_file.name - stac = stac_validator.StacValidate(body) - stac.run() +def validate(stac_object): + stac = stac_validator.StacValidate(stac_object) + stac.run() output = stac.message[0] + return output + + +@app.get("/url") +async def validate_url_get_request(stac_url): + output = validate(str(stac_url)) + return {"body": output} + + +@app.post("/url") +async def validate_url_post_request(stac_url): + output = validate(str(stac_url)) + return {"body": output} + + +@app.post("/json") +async def validate_json(request: Request): + stac_file = await request.json() + temp_stac_file = tempfile.NamedTemporaryFile( + delete=False, + mode="w+", + ) + json.dump(stac_file, temp_stac_file) + temp_stac_file.flush() + temp_stac_file.close() + body = temp_stac_file.name + output = validate(body) + return {"body": output} + - if "validation_method" in output: - output.pop("validation_method") - - return { - "statusCode": 200, - "isBase64Encoded": False, - "headers": { - "Content-Type": "application/json", - "Access-Control-Allow-Headers": "Content-Type", - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "OPTIONS,POST,GET", - }, - "body": json.dumps(output), - } +handler = Mangum(app) diff --git a/cdk-deployment/validator_cdk/validator_cdk_stack.py b/cdk-deployment/validator_cdk/validator_cdk_stack.py index dc7b7747..e4fa9380 100644 --- a/cdk-deployment/validator_cdk/validator_cdk_stack.py +++ b/cdk-deployment/validator_cdk/validator_cdk_stack.py @@ -11,22 +11,22 @@ class ValidatorCdkStack(cdk.Stack): def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) - stac_lib = _lambda.LayerVersion( + val_lib = _lambda.LayerVersion( self, - "stac-lib-layer", - code=_lambda.AssetCode("lambda/libraries.zip"), + "validator-library-layer", + code=_lambda.AssetCode("build-libraries/libraries.zip"), compatible_runtimes=[_lambda.Runtime.PYTHON_3_8], ) # Defines an AWS Lambda resource validator_lambda = _lambda.Function( self, - "STACHandler", + "STACValidator", runtime=_lambda.Runtime.PYTHON_3_8, code=_lambda.Code.asset("lambda"), handler="lambda.handler", timeout=cdk.Duration.seconds(30), - layers=[stac_lib], + layers=[val_lib], ) cors = apigw.CorsOptions(allow_origins=["*"]) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..2f77e63b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,8 @@ +[build-system] +requires = [ + "requests", + "jsonschema", + "pystac", + "click", +] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..a9662a59 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,3 @@ +"pytest" +"pytest-mypy" +"pre-commit" \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 224a7795..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py index 2cd1c8a3..de3fabd2 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,6 @@ #!/usr/bin/env python -try: - from setuptools import setup -except ImportError: - from distutils.core import setup +from setuptools import setup __version__ = "2.0.0" @@ -17,7 +14,7 @@ setup( name="stac_validator", version=__version__, - author="James Banting, Darren Wiens, Jonathan Healy", + author="James Banting, Jonathan Healy", author_email="jhealy@sparkgeo.com", description="A package to validate STAC files", license="MIT", @@ -38,13 +35,11 @@ "jsonschema==3.2.0", "pystac==0.5.6", "click==7.1.2", - "pytest", - "pytest-mypy", - "pre-commit", ], packages=["stac_validator"], entry_points={ "console_scripts": ["stac_validator = stac_validator.stac_validator:main"] }, + python_requires=">=3.6", tests_require=["pytest"], )