Использование лямбда (python) для чтения csv из s3 и возврата csv клиенту через шлюз API

У меня есть шлюз 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
          }

Для загрузки вы можете отправить ответ в формате json с URL-адресом файла, который можно загрузить. Загружаемый файл может храниться в S3, и пользователь может щелкнуть по нему или вставить в браузере для загрузки. В идеале, небольшой пользовательский интерфейс может быть расширен, чтобы иметь возможность щелкнуть, чтобы загрузить файл в случае необходимости.

coldy 16.04.2023 21:20

проблема в том, что эта лямбда запрашивает несколько файлов, и в конечном итоге у меня будут другие параметры строки запроса для фильтрации множества файлов на основе диапазонов дат и т. д. Таким образом, csv необходимо «построить» как таковой, а затем предоставить клиенту.

bob 17.04.2023 01:07
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
113
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Укажите ведро в качестве параметра пути

Чтобы указать ведро в качестве параметра пути, проще всего определить переменную пути формы /base-url-of-your-api/{bucket} в маршруте шлюза API. До вашей лямбды, чтобы проверить правильность данного параметра и вернуть ошибку HTTP или нет.

Вы получите что-то вроде этого:

  • Ресурс шлюза API: {bucket}
  • В вашем коде: bucket_name = event['requestContext']['path'].split('/')[-1]

Однако я бы предпочел использовать функциональное имя вместо физического имени корзины. Это делается для того, чтобы не раскрывать конечному пользователю имя ваших корзин S3 и сохранить гибкость для организации ваших корзин по-разному в будущем без изменения контракта API:

  • Вызов 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"

Примечание

Я поддерживаю библиотеку с открытым исходным кодом, которая призвана упростить все это, предоставляя способы (среди прочего):

  • определить формат возврата для выбора,
  • автоматически возвращать 406, если Accept не перечисляет какой-либо приемлемый формат
  • настроить преобразователи содержимого ответа для преобразования вашего внутреннего формата в формат, ожидаемый вызывающим абонентом

Он называется awsmate и доступен здесь: https://github.com/shlublu/awsmate Я постараюсь найти время, чтобы отредактировать этот ответ и опубликовать здесь код, если вам это интересно (дайте мне знать в комментариях). А пока он поставляется с примером приложения, которое может показать, как быстро сделать то, что вы хотите, я надеюсь.

Спасибо. Я уже использую переменную пути в шлюзе для перечисления ведра. Однако у меня не было типа контента, text/csv. Я думаю, мне это нужно, чтобы вернуть csv клиенту. Я добавлю это и поиграю.

bob 17.04.2023 22:01

Другие вопросы по теме