From 7d570e1a1647f75a32fe213f646acf19c2490c54 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Fri, 24 Jul 2020 11:03:39 +1000 Subject: [PATCH] upload: allow setting S3 endpoint by an environment variable To assist with testing, make it possible to override the default S3 endpoint URL by setting EXODUS_GW_S3_ENDPOINT_URL. It can be used to (e.g.) test against localstack. Note that, at some point, we expect to support multiple target environments and have some method of managing their configuration; most likely this env var will be dropped at that time. --- exodus_gw/s3/api.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/exodus_gw/s3/api.py b/exodus_gw/s3/api.py index fac5f8c8..babfc3b2 100644 --- a/exodus_gw/s3/api.py +++ b/exodus_gw/s3/api.py @@ -31,6 +31,7 @@ from typing import Optional import textwrap import logging +import os import aioboto3 from fastapi import Request, Response, Path, Query, HTTPException @@ -53,6 +54,15 @@ # - requests should be authenticated +def s3_client(): + # Certain aspects of the boto client can be tweaked by environment variables + # for development. + # This is expected to be replaced with a proper configuration system at some point. + return aioboto3.client( + "s3", endpoint_url=os.environ.get("EXODUS_GW_S3_ENDPOINT_URL") or None + ) + + @app.post( "/upload/{bucket}/{key}", tags=["upload"], @@ -157,7 +167,7 @@ async def object_put(bucket: str, key: str, request: Request): # Single-part upload handler: entire object is written via one PUT. reader = RequestReader.get_reader(request) - async with aioboto3.client("s3") as s3: + async with s3_client() as s3: response = await s3.put_object( Bucket=bucket, Key=key, @@ -178,7 +188,7 @@ async def complete_multipart_upload( LOG.debug("completing mpu for parts %s", parts) - async with aioboto3.client("s3") as s3: + async with s3_client() as s3: response = await s3.complete_multipart_upload( Bucket=bucket, Key=key, @@ -197,7 +207,7 @@ async def complete_multipart_upload( async def create_multipart_upload(bucket: str, key: str): - async with aioboto3.client("s3") as s3: + async with s3_client() as s3: response = await s3.create_multipart_upload(Bucket=bucket, Key=key) return xml_response( @@ -213,7 +223,7 @@ async def multipart_put( ): reader = RequestReader.get_reader(request) - async with aioboto3.client("s3") as s3: + async with s3_client() as s3: response = await s3.upload_part( Body=reader, Bucket=bucket, @@ -248,7 +258,7 @@ async def abort_multipart_upload( """ LOG.debug("Abort %s", uploadId) - async with aioboto3.client("s3") as s3: + async with s3_client() as s3: await s3.abort_multipart_upload( Bucket=bucket, Key=key, UploadId=uploadId )