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: custom runtimes option for titiler and ingestor #66

Merged
merged 6 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
75 changes: 72 additions & 3 deletions lib/ingestor-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
RemovalPolicy,
Stack,
} from "aws-cdk-lib";
import { PythonFunction } from "@aws-cdk/aws-lambda-python-alpha";
import { PythonFunction, PythonFunctionProps } from "@aws-cdk/aws-lambda-python-alpha";
import { Construct } from "constructs";

export class StacIngestor extends Construct {
Expand Down Expand Up @@ -55,6 +55,7 @@ export class StacIngestor extends Construct {
dbVpc: props.vpc,
dbSecurityGroup: props.stacDbSecurityGroup,
subnetSelection: props.subnetSelection,
apiCode: props.apiCode,
});

this.buildApiEndpoint({
Expand All @@ -72,6 +73,7 @@ export class StacIngestor extends Construct {
dbVpc: props.vpc,
dbSecurityGroup: props.stacDbSecurityGroup,
subnetSelection: props.subnetSelection,
ingestorCode: props.ingestorCode,
});

this.registerSsmParameter({
Expand Down Expand Up @@ -108,11 +110,17 @@ export class StacIngestor extends Construct {
dbVpc: ec2.IVpc;
dbSecurityGroup: ec2.ISecurityGroup;
subnetSelection: ec2.SubnetSelection
apiCode?: ApiCode;
}): PythonFunction {

const handler = new PythonFunction(this, "api-handler", {
const apiCode = props.apiCode || {
entry: `${__dirname}/runtime`,
index: "src/handler.py",
handler: "handler",
};

const handler = new PythonFunction(this, "api-handler", {
...apiCode,
runtime: lambda.Runtime.PYTHON_3_9,
timeout: Duration.seconds(30),
environment: { DB_SECRET_ARN: props.dbSecret.secretArn, ...props.env },
Expand Down Expand Up @@ -145,10 +153,19 @@ export class StacIngestor extends Construct {
dbVpc: ec2.IVpc;
dbSecurityGroup: ec2.ISecurityGroup;
subnetSelection: ec2.SubnetSelection;
ingestorCode?: IngestorCode;
}): PythonFunction {
const handler = new PythonFunction(this, "stac-ingestor", {



const ingestorCode = props.ingestorCode || {
entry: `${__dirname}/runtime`,
index: "src/ingestor.py",
handler: "handler",
};

const handler = new PythonFunction(this, "stac-ingestor", {
...ingestorCode,
runtime: lambda.Runtime.PYTHON_3_9,
timeout: Duration.seconds(180),
environment: { DB_SECRET_ARN: props.dbSecret.secretArn, ...props.env },
Expand Down Expand Up @@ -290,4 +307,56 @@ export interface StacIngestorProps {
* Custom Domain Name Options for Ingestor API
*/
readonly ingestorDomainNameOptions?: apigateway.DomainNameOptions;

/**
* Custom code for the ingestor api.
*
* @default - default in the runtime folder.
*/
readonly apiCode?: ApiCode;

/**
* Custom code for the ingestor.
*
* @default - default in the runtime folder.
*/
readonly ingestorCode?: IngestorCode;
}

export interface ApiCode {

/**
* Path to the source of the function or the location for dependencies, for the api lambda.
*/
readonly entry: PythonFunctionProps["entry"];

/**
* Path to the index file containing the exported handler, relative to `api_lambda_entry`.
*/
readonly index: PythonFunctionProps["index"];

/**
* The name of the exported handler in the `api_lambda_index` file.
*/
readonly handler: PythonFunctionProps["handler"];

}

export interface IngestorCode {

/**
* Path to the source of the function or the location for dependencies, for the ingestor lambda.
*/
readonly entry: PythonFunctionProps["entry"];

/**
* Path to the index file containing the exported handler, relative to `ingestor_lambda_entry`.
*/
readonly index: PythonFunctionProps["index"];

/**
* The name of the exported handler in the `ingestor_lambda_index` file.
*/
readonly handler: PythonFunctionProps["handler"];

}
4 changes: 2 additions & 2 deletions lib/tipg-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ import {
readonly dbSecret: secretsmanager.ISecret;

/**
* Custom code to run for fastapi-pgstac.
* Custom code to run for the application.
*
* @default - simplified version of fastapi-pgstac
* @default - simplified version of tipg.
*/
readonly apiCode?: TiPgApiEntrypoint;

Expand Down
117 changes: 86 additions & 31 deletions lib/titiler-pgstac-api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,77 @@
aws_lambda as lambda,
aws_secretsmanager as secretsmanager,
CfnOutput,
Duration,

Check failure on line 9 in lib/titiler-pgstac-api/index.ts

View workflow job for this annotation

GitHub Actions / package / Build and package

'Duration' is declared but its value is never read.
aws_logs,
} from "aws-cdk-lib";
import {PythonFunction, PythonFunctionProps} from "@aws-cdk/aws-lambda-python-alpha";
import { IDomainName, HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha";
import { HttpLambdaIntegration } from "@aws-cdk/aws-apigatewayv2-integrations-alpha";
import { Construct } from "constructs";


// default settings that can be overridden by the user-provided environment.
let defaultTitilerPgstacEnv :{ [key: string]: any } = {
"CPL_VSIL_CURL_ALLOWED_EXTENSIONS": ".tif,.TIF,.tiff",
"GDAL_CACHEMAX": "200",
"GDAL_DISABLE_READDIR_ON_OPEN": "EMPTY_DIR",
"GDAL_INGESTED_BYTES_AT_OPEN": "32768",
"GDAL_HTTP_MERGE_CONSECUTIVE_RANGES": "YES",
"GDAL_HTTP_MULTIPLEX": "YES",
"GDAL_HTTP_VERSION": "2",
"PYTHONWARNINGS": "ignore",
"VSI_CACHE": "TRUE",
"VSI_CACHE_SIZE": "5000000",
"DB_MIN_CONN_SIZE": "1",
"DB_MAX_CONN_SIZE": "1"
}

const defaultMemorySize = 3008;

export class TitilerPgstacApiLambda extends Construct {
readonly url: string;
public titilerPgstacLambdaFunction: lambda.Function;

constructor(scope: Construct, id: string, props: TitilerPgStacApiLambdaProps) {
super(scope, id);

const titilerPgstacEnv = {
"CPL_VSIL_CURL_ALLOWED_EXTENSIONS": ".tif,.TIF,.tiff",
"GDAL_CACHEMAX": "200",
"GDAL_DISABLE_READDIR_ON_OPEN": "EMPTY_DIR",
"GDAL_INGESTED_BYTES_AT_OPEN": "32768",
"GDAL_HTTP_MERGE_CONSECUTIVE_RANGES": "YES",
"GDAL_HTTP_MULTIPLEX": "YES",
"GDAL_HTTP_VERSION": "2",
"PYTHONWARNINGS": "ignore",
"VSI_CACHE": "TRUE",
"VSI_CACHE_SIZE": "5000000",
"DB_MIN_CONN_SIZE": "1",
"DB_MAX_CONN_SIZE": "1",
"PGSTAC_SECRET_ARN": props.dbSecret.secretArn,
}


this.titilerPgstacLambdaFunction = new lambda.Function(this, "lambda", {
handler: "handler.handler",


// if user provided environment variables, merge them with the defaults.
const apiEnv = props.apiEnv ? { ...defaultTitilerPgstacEnv, ...props.apiEnv, "PGSTAC_SECRET_ARN": props.dbSecret.secretArn } : defaultTitilerPgstacEnv;

const apiCode = props.apiCode || {
entry: `${__dirname}/runtime`,
index: "src/handler.py",
handler: "handler",
};

this.titilerPgstacLambdaFunction = new PythonFunction(this, "titiler-pgstac-api", {
...apiCode,
runtime: lambda.Runtime.PYTHON_3_10,
code: lambda.Code.fromDockerBuild(__dirname, {
file: "runtime/Dockerfile",
buildArgs: { PYTHON_VERSION: '3.10' },
}),
timeout: Duration.seconds(30),
architecture: lambda.Architecture.X86_64,
environment: apiEnv,
vpc: props.vpc,
vpcSubnets: props.subnetSelection,
allowPublicSubnet: true,
memorySize: 3008,
logRetention: aws_logs.RetentionDays.ONE_WEEK,
environment: titilerPgstacEnv,
});
memorySize: props.titilerLambdaMemorySize ?? defaultMemorySize,
logRetention: aws_logs.RetentionDays.ONE_WEEK
})

// this.titilerPgstacLambdaFunction = new lambda.Function(this, "lambda", {
// handler: "handler.handler",
// runtime: lambda.Runtime.PYTHON_3_10,
// code: props.titilerApiAsset ?? lambda.Code.fromDockerBuild(__dirname, {
// file: "runtime/Dockerfile",
// buildArgs: { PYTHON_VERSION: '3.10' },
// }),
// timeout: Duration.seconds(30),
// vpc: props.vpc,
// vpcSubnets: props.subnetSelection,
// allowPublicSubnet: true,
// memorySize: props.titilerLambdaMemorySize ?? 3008,
// logRetention: aws_logs.RetentionDays.ONE_WEEK,
// environment: titilerPgstacEnv,
// });

// grant access to buckets using addToRolePolicy
if (props.buckets) {
Expand Down Expand Up @@ -105,8 +130,9 @@
readonly dbSecret: secretsmanager.ISecret;

/**
* Customized environment variables to send to titiler-pgstac runtime.
*/
* Customized environment variables to send to titiler-pgstac runtime. These will be merged with `defaultTitilerPgstacEnv`.
* The database secret arn is automatically added to the environment variables at deployment.
/*/
readonly apiEnv?: Record<string, string>;

/**
Expand All @@ -118,4 +144,33 @@
* Custom Domain Name Options for Titiler Pgstac API,
*/
readonly titilerPgstacApiDomainName?: IDomainName;

/**
* Custom code to run for titiler-pgstac.
*
* @default - the app code in the `runtime` folder.
*/
readonly apiCode?: TitilerPgstacEntrypoint;
/**

* amount of memory to allocate to the lambda function.
*/
readonly titilerLambdaMemorySize?: number;
}



export interface TitilerPgstacEntrypoint {
/**
* Path to the source of the function or the location for dependencies.
*/
readonly entry: PythonFunctionProps["entry"];
/**
* The path (relative to entry) to the index file containing the exported handler.
*/
readonly index: PythonFunctionProps["index"];
/**
* The name of the exported handler in the index file.
*/
readonly handler: PythonFunctionProps["handler"];
}
20 changes: 0 additions & 20 deletions lib/titiler-pgstac-api/runtime/Dockerfile

This file was deleted.

3 changes: 2 additions & 1 deletion lib/titiler-pgstac-api/runtime/dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
uvicorn
uvicorn
boto3>=1.26.139
2 changes: 1 addition & 1 deletion lib/titiler-pgstac-api/runtime/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
titiler.pgstac==0.5.1
boto3>=1.26.139
psycopg[binary, pool]
mangum>=0.14,<0.15
2 changes: 1 addition & 1 deletion lib/titiler-pgstac-api/runtime/src/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import asyncio
import os
from mangum import Mangum
from utils import get_secret_dict
from src.utils import get_secret_dict

pgstac_secret_arn = os.environ["PGSTAC_SECRET_ARN"]

Expand Down
Loading