improvements to lambda wrapper [#13]

This commit is contained in:
Brandon Liu
2022-07-05 21:26:13 +08:00
parent f442e403c5
commit fbc7b02123
5 changed files with 95 additions and 21 deletions
+21 -1
View File
@@ -7,4 +7,24 @@
2. Create a ZIP archive with the `tippecanoe` binary at `bin/tippecanoe` and upload as a Lambda layer
3. Copy [lambda_function.py](lambda_function.py) (python 3.9 runtime)
4. set the environment variable `OUTPUT_BUCKET` to your output bucket; give lambda IAM role access to input/output buckets
4. set the environment variable `OUTPUT_BUCKET` to your output bucket; give lambda IAM role access to input/output buckets
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowGet",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::tippecanoe-lambda-input/*"
},
{
"Sid": "AllowPut",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::tippecanoe-lambda-output/*"
}
]
}
```
-20
View File
@@ -1,20 +0,0 @@
import os
import json
import subprocess
import boto3
# if the input bucket is publicly readable
# from botocore import UNSIGNED
# from botocore.config import Config
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
#s3 = boto3.client('s3',config=Config(signature_version=UNSIGNED))
s3 = boto3.client('s3')
s3.download_file(bucket,key,'/tmp/input.geojsonseq')
p = subprocess.check_call(['tippecanoe','-o','/tmp/output.mbtiles','/tmp/input.geojsonseq','--force'])
s3.upload_file('/tmp/output.mbtiles',os.environ['OUTPUT_BUCKET'],key + ".mbtiles")
return {
'statusCode': 200,
'body': json.dumps('Done!')
}
+48
View File
@@ -0,0 +1,48 @@
import os
import json
import subprocess
import sys
import boto3
# if the input bucket is publicly readable
# from botocore import UNSIGNED
# from botocore.config import Config
#s3 = boto3.client('s3',config=Config(signature_version=UNSIGNED))
def lambda_handler(event, context):
bucket_name = event['Records'][0]['s3']['bucket']['name']
input_key = event['Records'][0]['s3']['object']['key']
tmpdir = '/tmp'
run_tippecanoe('tippecanoe',tmpdir,bucket_name, input_key)
return {
'statusCode': 200,
'body': json.dumps('Done!')
}
# input formats: "geojsonseq", "fgb", "geobuf", "geojson", "csv"
def split_key(key):
if key.endswith(".gz"):
root, ext = os.path.splitext(key[0:-3])
return root, ext + ".gz"
else:
return os.path.splitext(key)
def run_tippecanoe(executable, tmpdir, bucket_name, input_key):
s3 = boto3.client('s3')
root, ext = split_key(input_key)
input_path = os.path.join(tmpdir,'input' + ext)
output_path = os.path.join(tmpdir,'output.mbtiles')
s3.download_file(bucket_name,input_key,input_path)
p = subprocess.Popen([executable,'-o',output_path,input_path,'--force','-u','-U','5'],stderr=subprocess.PIPE)
for line in p.stderr:
try:
j = json.loads(line)
s3.put_object(Body=json.dumps(j),Bucket=os.environ['OUTPUT_BUCKET'],Key=root + ".progress")
except json.decoder.JSONDecodeError:
pass
s3.upload_file(output_path,os.environ['OUTPUT_BUCKET'],root + ".mbtiles")
if __name__ == "__main__":
tmpdir = 'tmp'
bucket_name = sys.argv[1]
input_key = sys.argv[2]
run_tippecanoe('../tippecanoe', tmpdir, bucket_name, input_key)
+26
View File
@@ -0,0 +1,26 @@
from tippecanoe import split_key
import unittest
class TestTippecanoe(unittest.TestCase):
def test_basic(self):
root, ext = split_key("file.json")
self.assertEqual(root,"file")
self.assertEqual(ext,".json")
def test_basic_gz(self):
root, ext = split_key("file.csv.gz")
self.assertEqual(root,"file")
self.assertEqual(ext,".csv.gz")
def test_nested_key(self):
root, ext = split_key("dir/file.fgb")
self.assertEqual(root,"dir/file")
self.assertEqual(ext,".fgb")
def test_nested_key_gz(self):
root, ext = split_key("dir/file.geojsonseq.gz")
self.assertEqual(root,"dir/file")
self.assertEqual(ext,".geojsonseq.gz")
if __name__ == '__main__':
unittest.main()
View File