2727log = logging .getLogger ()
2828log .setLevel (logging .INFO )
2929
30+ images_table = dynamodb_r .Table (os .environ ['IMAGES_TABLE' ])
3031info_images_table = dynamodb_r .Table (os .getenv ('INFO_IMAGES_TABLE' ))
3132recent_uploads_table = dynamodb_r .Table (os .getenv ('UPLOADS_LOG_TABLE_NAME' ))
3233s3 = boto3 .client ('s3' , REGION , config = Config (signature_version = 's3v4' ))
@@ -45,116 +46,115 @@ def default(event, context):
4546 log .info (json .dumps (event , indent = 2 ))
4647 return http_response (HTTPStatus .OK , "New photon ranch API" )
4748
48-
49- def upload (event , context ):
50- """Generates a presigned URL to upload files at AWS.
51-
52- A request for a presigned post URL requires the name of the object.
53- This is sent in a single string under the key 'object_name' in the
54- json-string body of the request.
55-
56- Args:
57- event.body.s3_directory (str): Name of the s3 bucket to use.
58- event.body.filename (str): Name of the file to upload.
59-
60- Returns:
61- 204 status code with presigned upload URL string if successful.
62- 403 status code if incorrect s3 bucket or info channel supplied.
63-
64- Example request body:
65- '{"object_name":"a_file.txt", "s3_directory": "data"}'
66- This request will save an image into the main s3 bucket as:
67- MAIN_BUCKET_NAME/data/a_file.txt
68-
69- * * *
70-
71- Another example Python program using the presigned URL to upload a file:
72-
73- with open(object_name, 'rb') as f:
74- files = {'file': (object_name, f)}
75- http_response = requests.post(
76- response['url'], data=response['fields'], files=files)
77- # If successful, returns HTTP status code 204
78- log.info(f'File upload HTTP status code: {http_response.status_code}')
79-
80- * * *
81-
82- If the upload URL is to be used with an info image, then
83- the request must include 'info_channel' with a value of 1, 2, or 3.
84- This will prompt an update to the info-images table, where it will
85- store the provided base_filename in the row with pk=={site}#metadata,
86- under the attribute channel{n}.
87-
88- For example, the request body:
89- {
90- "object_name": "tst-inst-20211231-00000001-EX10.jpg",
91- "s3_directory": "info-images",
92- "info_channel": 2
93- }
94- will result in the info-images table being updated with:
95- {
96- "pk": "tst#metadata",
97- "channel2": "tst-inst-20211231-00000001",
98- ...
99- }
100- The URL returned by this endpoint will allow a POST request
101- to s3 with the actual file. The code that processes new s3 objects
102- will see that it is an info image, then query the info-images table
103- to find which channel to use, and finally update the info-images
104- table with an entry like:
105- {
106- "pk": "tst#2",
107- "jpg_10_exists": true,
108- ...
109- }
110- This is the object that is queried to find the info image at
111- site 'tst', channel 2.
112- """
113-
114- log .info (json .dumps (event , indent = 2 ))
115- body = _get_body (event )
116-
117- # Retrieve and validate the s3_directory
118- s3_directory = body .get ('s3_directory' , 'data' )
119- filename = body .get ('object_name' )
120- if s3_directory not in ['data' , 'info-images' , 'allsky' , 'test' ]:
121- error_msg = "s3_directory must be either 'data', 'info-images', or 'allsky'."
122- log .warning (error_msg )
123- return http_response (HTTPStatus .FORBIDDEN , error_msg )
124-
125- # If info image: get the channel number to use
126- if s3_directory == 'info-images' :
127-
128- site = filename .split ('-' )[0 ]
129- base_filename = get_base_filename_from_full_filename (filename )
130- channel = int (body .get ('info_channel' , 1 ))
131- if channel not in [1 ,2 ,3 ]:
132- error_msg = f"Value for info_channel must be either 1, 2, or 3. Received { channel } instead."
133- log .warning (error_msg )
134- return http_response (HTTPStatus .FORBIDDEN , error_msg )
135-
136- # Create an entry to track metadata for the next info image that will be uploaded
137- info_images_table .update_item (
138- Key = { 'pk' : f'{ site } #metadata' },
139- UpdateExpression = f"set channel{ channel } =:basefilename" ,
140- ExpressionAttributeValues = {':basefilename' : base_filename }
141- )
142-
143- # Get upload metadata
144- metadata = body .get ('metadata' , None )
145- if metadata is not None :
146- metadata = json .dumps (json .loads (metadata ), cls = DecimalEncoder )
147-
148- # TODO: if applicable, add metadata to database
149-
150- key = f"{ s3_directory } /{ body ['object_name' ]} "
151- url = s3 .generate_presigned_post (
152- Bucket = BUCKET_NAME ,
153- Key = key ,
154- ExpiresIn = S3_PUT_TTL
155- )
156- log .info (f"Presigned upload url: { url } " )
157- return http_response (HTTPStatus .OK , url )
49+ # def upload(event, context):
50+ # """Generates a presigned URL to upload files at AWS.
51+
52+ # A request for a presigned post URL requires the name of the object.
53+ # This is sent in a single string under the key 'object_name' in the
54+ # json-string body of the request.
55+
56+ # Args:
57+ # event.body.s3_directory (str): Name of the s3 bucket to use.
58+ # event.body.filename (str): Name of the file to upload.
59+
60+ # Returns:
61+ # 204 status code with presigned upload URL string if successful.
62+ # 403 status code if incorrect s3 bucket or info channel supplied.
63+
64+ # Example request body:
65+ # '{"object_name":"a_file.txt", "s3_directory": "data"}'
66+ # This request will save an image into the main s3 bucket as:
67+ # MAIN_BUCKET_NAME/data/a_file.txt
68+
69+ # * * *
70+
71+ # Another example Python program using the presigned URL to upload a file:
72+
73+ # with open(object_name, 'rb') as f:
74+ # files = {'file': (object_name, f)}
75+ # http_response = requests.post(
76+ # response['url'], data=response['fields'], files=files)
77+ # # If successful, returns HTTP status code 204
78+ # log.info(f'File upload HTTP status code: {http_response.status_code}')
79+
80+ # * * *
81+
82+ # If the upload URL is to be used with an info image, then
83+ # the request must include 'info_channel' with a value of 1, 2, or 3.
84+ # This will prompt an update to the info-images table, where it will
85+ # store the provided base_filename in the row with pk=={site}#metadata,
86+ # under the attribute channel{n}.
87+
88+ # For example, the request body:
89+ # {
90+ # "object_name": "tst-inst-20211231-00000001-EX10.jpg",
91+ # "s3_directory": "info-images",
92+ # "info_channel": 2
93+ # }
94+ # will result in the info-images table being updated with:
95+ # {
96+ # "pk": "tst#metadata",
97+ # "channel2": "tst-inst-20211231-00000001",
98+ # ...
99+ # }
100+ # The URL returned by this endpoint will allow a POST request
101+ # to s3 with the actual file. The code that processes new s3 objects
102+ # will see that it is an info image, then query the info-images table
103+ # to find which channel to use, and finally update the info-images
104+ # table with an entry like:
105+ # {
106+ # "pk": "tst#2",
107+ # "jpg_10_exists": true,
108+ # ...
109+ # }
110+ # This is the object that is queried to find the info image at
111+ # site 'tst', channel 2.
112+ # """
113+
114+ # log.info(json.dumps(event, indent=2))
115+ # body = _get_body(event)
116+
117+ # # Retrieve and validate the s3_directory
118+ # s3_directory = body.get('s3_directory', 'data')
119+ # filename = body.get('object_name')
120+ # if s3_directory not in ['data', 'info-images', 'allsky', 'test']:
121+ # error_msg = "s3_directory must be either 'data', 'info-images', or 'allsky'."
122+ # log.warning(error_msg)
123+ # return http_response(HTTPStatus.FORBIDDEN, error_msg)
124+
125+ # # If info image: get the channel number to use
126+ # if s3_directory == 'info-images':
127+
128+ # site = filename.split('-')[0]
129+ # base_filename = get_base_filename_from_full_filename(filename)
130+ # channel = int(body.get('info_channel', 1))
131+ # if channel not in [1,2,3]:
132+ # error_msg = f"Value for info_channel must be either 1, 2, or 3. Received {channel} instead."
133+ # log.warning(error_msg)
134+ # return http_response(HTTPStatus.FORBIDDEN, error_msg)
135+
136+ # # Create an entry to track metadata for the next info image that will be uploaded
137+ # info_images_table.update_item(
138+ # Key={ 'pk': f'{site}#metadata' },
139+ # UpdateExpression=f"set channel{channel}=:basefilename",
140+ # ExpressionAttributeValues={':basefilename': base_filename}
141+ # )
142+
143+ # # Get upload metadata
144+ # metadata = body.get('metadata', None)
145+ # if metadata is not None:
146+ # metadata = json.dumps(json.loads(metadata), cls=DecimalEncoder)
147+
148+ # # TODO: if applicable, add metadata to database
149+
150+ # key = f"{s3_directory}/{body['object_name']}"
151+ # url = s3.generate_presigned_post(
152+ # Bucket = BUCKET_NAME,
153+ # Key = key,
154+ # ExpiresIn = S3_PUT_TTL
155+ # )
156+ # log.info(f"Presigned upload url: {url}")
157+ # return http_response(HTTPStatus.OK, url)
158158
159159
160160def download (event , context ):
0 commit comments