-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: tipg-api * update readme * load pgstac vars into env directly in utils, fix an import bug * add CDN for tipg api --------- Co-authored-by: emileten <[email protected]>
- Loading branch information
1 parent
daec1e0
commit 24faa85
Showing
8 changed files
with
229 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { | ||
Stack, | ||
aws_ec2 as ec2, | ||
aws_rds as rds, | ||
aws_lambda as lambda, | ||
aws_secretsmanager as secretsmanager, | ||
CfnOutput, | ||
Duration, | ||
} 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"; | ||
|
||
export class TiPgApiLambda extends Construct { | ||
readonly url: string; | ||
public tiPgLambdaFunction: PythonFunction; | ||
|
||
constructor(scope: Construct, id: string, props: TiPgApiLambdaProps) { | ||
super(scope, id); | ||
|
||
const apiCode = props.apiCode || { | ||
entry: `${__dirname}/runtime`, | ||
index: "src/handler.py", | ||
handler: "handler", | ||
}; | ||
|
||
this.tiPgLambdaFunction = new PythonFunction(this, "tipg-api", { | ||
...apiCode, | ||
runtime: lambda.Runtime.PYTHON_3_10, | ||
architecture: lambda.Architecture.X86_64, | ||
environment: { | ||
PGSTAC_SECRET_ARN: props.dbSecret.secretArn, | ||
DB_MIN_CONN_SIZE: "1", | ||
DB_MAX_CONN_SIZE: "1", | ||
...props.apiEnv, | ||
}, | ||
vpc: props.vpc, | ||
vpcSubnets: props.subnetSelection, | ||
allowPublicSubnet: true, | ||
memorySize: 1024, | ||
timeout: Duration.seconds(30), | ||
}); | ||
|
||
props.dbSecret.grantRead(this.tiPgLambdaFunction); | ||
this.tiPgLambdaFunction.connections.allowTo(props.db, ec2.Port.tcp(5432), "allow connections from tipg"); | ||
|
||
const tipgApi = new HttpApi(this, `${Stack.of(this).stackName}-tipg-api`, { | ||
defaultDomainMapping: props.tipgApiDomainName ? { | ||
domainName: props.tipgApiDomainName | ||
} : undefined, | ||
defaultIntegration: new HttpLambdaIntegration("integration", this.tiPgLambdaFunction), | ||
}); | ||
|
||
this.url = tipgApi.url!; | ||
|
||
new CfnOutput(this, "tipg-api-output", { | ||
exportName: `${Stack.of(this).stackName}-tip-url`, | ||
value: this.url, | ||
}); | ||
} | ||
} | ||
|
||
export interface TiPgApiLambdaProps { | ||
|
||
/** | ||
* VPC into which the lambda should be deployed. | ||
*/ | ||
readonly vpc: ec2.IVpc; | ||
|
||
/** | ||
* RDS Instance with installed pgSTAC. | ||
*/ | ||
readonly db: rds.IDatabaseInstance; | ||
|
||
/** | ||
* Subnet into which the lambda should be deployed. | ||
*/ | ||
readonly subnetSelection: ec2.SubnetSelection; | ||
|
||
/** | ||
* Secret containing connection information for pgSTAC database. | ||
*/ | ||
readonly dbSecret: secretsmanager.ISecret; | ||
|
||
/** | ||
* Custom code to run for fastapi-pgstac. | ||
* | ||
* @default - simplified version of fastapi-pgstac | ||
*/ | ||
readonly apiCode?: TiPgApiEntrypoint; | ||
|
||
/** | ||
* Customized environment variables to send to titiler-pgstac runtime. | ||
*/ | ||
readonly apiEnv?: Record<string, string>; | ||
|
||
/** | ||
* Custom Domain Name for tipg API. If defined, will create the | ||
* domain name and integrate it with the tipg API. | ||
* | ||
* @default - undefined | ||
*/ | ||
readonly tipgApiDomainName?: IDomainName; | ||
} | ||
|
||
export interface TiPgApiEntrypoint { | ||
/** | ||
* 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"]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
tipg==0.3.1 | ||
mangum==0.15.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
"""tipg lambda.""" | ||
|
||
__version__ = "0.1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
""" | ||
Handler for AWS Lambda. | ||
""" | ||
|
||
import asyncio | ||
import os | ||
from mangum import Mangum | ||
from src.utils import load_pgstac_secret | ||
|
||
load_pgstac_secret(os.environ["PGSTAC_SECRET_ARN"]) # required for the below imports | ||
|
||
# skipping linting rule that wants all imports at the top | ||
from tipg.main import app # noqa: E402 | ||
from tipg.collections import register_collection_catalog # noqa: E402 | ||
from tipg.database import connect_to_db # noqa: E402 | ||
from tipg.settings import ( # noqa: E402 | ||
CustomSQLSettings, # noqa: E402 | ||
DatabaseSettings, # noqa: E402 | ||
PostgresSettings, # noqa: E402 | ||
) # noqa: E402 | ||
|
||
|
||
postgres_settings = PostgresSettings() | ||
db_settings = DatabaseSettings() | ||
custom_sql_settings = CustomSQLSettings() | ||
|
||
|
||
@app.on_event("startup") | ||
async def startup_event() -> None: | ||
"""Connect to database on startup.""" | ||
await connect_to_db( | ||
app, | ||
settings=postgres_settings, | ||
schemas=db_settings.schemas, | ||
user_sql_files=custom_sql_settings.sql_files, | ||
) | ||
await register_collection_catalog( | ||
app, | ||
schemas=db_settings.schemas, | ||
tables=db_settings.tables, | ||
exclude_tables=db_settings.exclude_tables, | ||
exclude_table_schemas=db_settings.exclude_table_schemas, | ||
functions=db_settings.functions, | ||
exclude_functions=db_settings.exclude_functions, | ||
exclude_function_schemas=db_settings.exclude_function_schemas, | ||
spatial=db_settings.only_spatial_tables, | ||
) | ||
|
||
|
||
handler = Mangum(app, lifespan="off") | ||
|
||
if "AWS_EXECUTION_ENV" in os.environ: | ||
loop = asyncio.get_event_loop() | ||
loop.run_until_complete(app.router.startup()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import base64 | ||
import json | ||
import boto3 | ||
import os | ||
|
||
|
||
def load_pgstac_secret(secret_name: str): | ||
"""Retrieve secrets from AWS Secrets Manager | ||
Args: | ||
secret_name (str): name of aws secrets manager secret containing database connection secrets | ||
profile_name (str, optional): optional name of aws profile for use in debugger only | ||
Returns: | ||
secrets (dict): decrypted secrets in dict | ||
""" | ||
|
||
# Create a Secrets Manager client | ||
session = boto3.session.Session() | ||
client = session.client(service_name="secretsmanager") | ||
|
||
get_secret_value_response = client.get_secret_value(SecretId=secret_name) | ||
|
||
if "SecretString" in get_secret_value_response: | ||
secret = json.loads(get_secret_value_response["SecretString"]) | ||
else: | ||
secret = json.loads(base64.b64decode(get_secret_value_response["SecretBinary"])) | ||
|
||
try: | ||
os.environ.update( | ||
{ | ||
"postgres_host": secret["host"], | ||
"postgres_dbname": secret["dbname"], | ||
"postgres_user": secret["username"], | ||
"postgres_pass": secret["password"], | ||
"postgres_port": str(secret["port"]), | ||
} | ||
) | ||
except Exception as ex: | ||
print("Could not load the pgstac environment variables from the secret") | ||
raise ex |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters