У меня есть шлюз API с настройкой параметров пути и строки запроса и интеграцией лямбда с использованием лямбда со слоем панд (awswrangler). Я хочу, чтобы пользователь мог указать ведро как параметр пути и параметр строки запроса, который будет определять, возвращаются ли им данные в виде json или csv (загружаемый) По сути, я хочу, чтобы он загружал CSV автоматически, если они укажут fmt=csv в URL-адресе. Вот шлюз с двумя форматами:
https://m0fhdyq5.execute-api.us-east-1.amazonaws.com/v1/br-candles?fmt=json
https://m0fhddyq5.execute-api.us-east-1.amazonaws.com/v1/br-candles?fmt=csv
бр-свечи это ведро
Вот мой лямбда-код. В настоящее время у меня есть только «код состояния: 200 для формата csv, так как я не знаю, как делать то, что я хочу.
import json
import awswrangler as wr
def lambda_handler(event, context):
print(event)
bucket_name = event['params']['path']['bucket']
format = event['params']['querystring']['fmt']
full_path = f"s3://{bucket_name}"
print(bucket_name, format)
raw_df = wr.s3.read_csv(path=full_path, path_suffix=['.csv'], use_threads=True)
for df in raw_df:
if format == 'json':
df = raw_df.to_json(orient = "records")
parsed = json.loads(df)
return {
'body': (parsed)
}
elif format == 'csv':
for df in raw_df:
#df = df.to_string(index=False)
#print (df)
return {
"statusCode": 200
}
else:
return {
"statusCode": 300
}
проблема в том, что эта лямбда запрашивает несколько файлов, и в конечном итоге у меня будут другие параметры строки запроса для фильтрации множества файлов на основе диапазонов дат и т. д. Таким образом, csv необходимо «построить» как таковой, а затем предоставить клиенту.
Укажите ведро в качестве параметра пути
Чтобы указать ведро в качестве параметра пути, проще всего определить переменную пути формы /base-url-of-your-api/{bucket}
в маршруте шлюза API. До вашей лямбды, чтобы проверить правильность данного параметра и вернуть ошибку HTTP или нет.
Вы получите что-то вроде этого:
{bucket}
bucket_name = event['requestContext']['path'].split('/')[-1]
Однако я бы предпочел использовать функциональное имя вместо физического имени корзины. Это делается для того, чтобы не раскрывать конечному пользователю имя ваших корзин S3 и сохранить гибкость для организации ваших корзин по-разному в будущем без изменения контракта API:
/your-api-base-url/{functionalName}
''' с добавлением правильной обработки ошибок '''
buckets_mapping = {
'functionalNameAlpha' : 'bucket-name-for-alpha',
'functionalNameBeta' : 'bucket-name-for-beta',
'functionalNameGamma' : 'bucket-name-for-gamma'
}
functional_name = event['requestContext']['path'].split('/')[-1]
bucket = buckets_mapping[functional_name ]
Формат возврата
Что касается формата возврата, более чистый способ — полагаться на стандартный HTTP-заголовок Accept . Этот заголовок устанавливается вызывающей стороной и определяет список допустимых форматов. Например: Accept: application/json,application/xml,text/csv
означает, что эти json, xml и csv являются тремя форматами, которые понимает вызывающий, в этом порядке предпочтения.
Заголовки доступны в event
, переданном вашему lambda_handler
, смонтированному в режиме прокси. Как и выше, до вашей лямбды, чтобы проверить, совместимы ли принятые форматы с вашим приложением, и вернуть HTTP 406 «Неприемлемо», если нет:
accepted_formats = event['headers']['Accept'] # for example: "application/xml,text/csv;q=0.9,application/json,text/*;q=0.2"
Примечание
Я поддерживаю библиотеку с открытым исходным кодом, которая призвана упростить все это, предоставляя способы (среди прочего):
Он называется awsmate
и доступен здесь: https://github.com/shlublu/awsmate
Я постараюсь найти время, чтобы отредактировать этот ответ и опубликовать здесь код, если вам это интересно (дайте мне знать в комментариях). А пока он поставляется с примером приложения, которое может показать, как быстро сделать то, что вы хотите, я надеюсь.
Спасибо. Я уже использую переменную пути в шлюзе для перечисления ведра. Однако у меня не было типа контента, text/csv. Я думаю, мне это нужно, чтобы вернуть csv клиенту. Я добавлю это и поиграю.
Для загрузки вы можете отправить ответ в формате json с URL-адресом файла, который можно загрузить. Загружаемый файл может храниться в S3, и пользователь может щелкнуть по нему или вставить в браузере для загрузки. В идеале, небольшой пользовательский интерфейс может быть расширен, чтобы иметь возможность щелкнуть, чтобы загрузить файл в случае необходимости.