Как запустить скрипт python для генерации / обновления файла JSON в корзине S3? - PullRequest
0 голосов
/ 16 февраля 2020

МОЙ ВОПРОС: Как запустить скрипт python для генерации / обновления файла JSON в корзине S3? Кроме того, должен ли я запускать этот скрипт каждый раз, когда файл добавляется в мое ведро, или когда кто-то посещает мою веб-страницу?

Читайте описание ...

У меня есть веб-сайт, размещенный на AWS, мои страницы c находятся в общедоступной корзине c S3. Цель - поделиться музыкой c, которую я написал, со студентами музыки c. У меня есть скрипт Python, который сканирует все объекты (листовые файлы c PDF) в папке в том же контейнере S3. Затем сценарий Python создает файл JSON, который содержит имена всех объектов s3 вместе с сгенерированными URL для каждого объекта.

Вот как отформатирован этот файл JSON :

{
  "bass": [{
      "bass-song1": "http://www.website.com/bass-song1.pdf"
    }, {
      "bass-song2": "http://www.website.com/bass-song2.pdf"
    }],
  "drum": [{
      "drum-song1": "http://www.website.com/drum-song1.pdf"
    }, {
      "drum-song2": "http://www.website.com/drum-song2.pdf"
    }],
  "guitar": [{
      "guitar-song1": "http://www.website.com/guitar-song1.pdf"
    }, {
      "guitar-song2": "http://www.website.com/guitar-song2.pdf"
    }]
}

Мой рабочий Python скрипт, для справки:

import boto3
import json
import pprint

# This program creates a json file
# with temporary URLs for bucket objects, organized by folder
# For use with javascript that generates links to bucket objects for website

# create a session to retrieve credentials from ~/.aws/credentials
session = boto3.Session(profile_name='<MY PROFILE>')

# use your credentials to create a low-level client with the s3 service
s3 = session.client('s3')

# Store dictionary of objects from bucket that starts with the prefix '__'
response = s3.list_objects_v2(Bucket='<MY BUCKET>', Prefix='<FOLDER IN BUCKET>')

folder_list = []
url_json = {}

# (the value of 'Contents' is a list of dictionaries)
# For all the dictionaries in the 'Contents' list,
# IF they don't end with '/' (meaning, if its not a directory)...
for i in response['Contents']:
    if i['Key'].endswith('/') != True:

        # get the directory of the current Key, save as string in 'dir'
        full_path = i['Key']
        # this retrieves the folder after '__'
        dir = full_path.split("/")[1]
        # capitalize the directory name, update variable
        dir = dir.capitalize()
        # this retrieves the file name
        filename = full_path.split("/")[2]

        # if the name of the directory ('dir') is not in folder_list:
        # add it to folder_list,
        # and add an item to dictionary 'url_json' where key is current 'dir' and value is empty list
        if dir not in folder_list:
            folder_list.append(dir)
            url_json[folder_list[-1]] = []

        # generate a temporary URL for the current bucket object
        url = s3.generate_presigned_url('get_object', Params={'Bucket':'<MY BUCKET>', 'Key':i['Key']}, ExpiresIn=3600)

        # create a dictionary for each bucket object
        # store the object's name (Key) and URL (value)
        object_dict = {filename:url}

        # Append the newly created URL to a list in the 'url_json' dictionary,
        # whose key is the last directory in 'folder_list'
        url_json[folder_list[-1]].append(object_dict)

# Dump content of 'url_json' directory to 'urls.json' file
# if it already exists, overwrite it
with open('url_list.json', mode='w') as outfile:
    json.dump(url_json, outfile)

Кроме того, в теле моей веб-страницы я написал несколько встроенных JavaScript, которые загружают / читают файл JSON и использует URL-адреса и связанный с ними текст для создания ссылок для доступа пользователей к этим файлам на моей веб-странице.

Моя рабочая JavaScript, для справки:

<script type="text/javascript">

async function getData(url) {
  const response = await fetch(url);
  return response.json()
}

async function main() {
  const data = await getData('<JSON FILE URL>');

  // 'instrument' example: 'Bass'
  for (var instrument in data) {

    var h = document.createElement("H3"); // Create the H1 element
    var t = document.createTextNode(instrument); // Create a text element
    h.appendChild(t); // Append the text node to the H1 element
    document.body.appendChild(h); // Append the H1 element to the document body

    // store the list of bass songs
    var song_list = data[instrument]
    // for each song (list element),
    for (var song_object of song_list) {
      // for every song name in the object (in python, dictionary)
      for (var song_name in song_object) {
        // create a var with the name and URL of the PDF song file
        var link_str = song_name;
        var link_url = song_object[song_name];

        // Create link to appear on website
        const a = document.createElement("a");
        var lineBreak = document.createElement("br");
        a.href = link_url;
        a.innerText = link_str;
        a.style.backgroundColor="rgba(255, 255, 255, 0.7)"
        document.body.appendChild(a);
        document.body.append(lineBreak);
      }
    }
  }
}
main();

</script>

Итак, моя конечная цель заключается в следующем: Я загружаю файл PDF в свое хранилище S3, мой скрипт Python выполняется для обновления файла JSON в моем хранилище S3, и когда кто-то посещает мою веб-страницу, JavaScript проанализирует файл JSON, чтобы создать ссылки на эти файлы PDF. Должен ли я сценарий python создать JSON при загрузке файлов в корзину или при посещении веб-сайта? Проблема заключается в том, что URL этих объектов имеют время истечения ... но я также не хочу запускать код каждый раз, когда кто-то загружает страницу (по соображениям $$).

Любая помощь будет принята с благодарностью. Дайте мне знать, если вам нужна дополнительная информация от меня. Спасибо, Себастьян.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...