在 Elastic Beanstalk 上使用 Python 中的 GET 请求对音频文件进行切片

Slicing audio files using GET requests in Python on Elastic Beanstalk

尝试在 Elastic Beanstalk 上启动一个简单的 Flask 应用程序以将音频分割成块。
使用 GET 请求下载音频文件的第一步:

@application.route("/<path:url>", methods=['GET'])
def converting_audio_task(url):
    import requests
    r = requests.get(url)
    file_name = 'audio.wav'
    with open(file_name,'wb') as f:
        f.write(r.content)

音频文件使用 public URL 托管在 GCP 存储上(我在 GCE 上有这个应用 运行 没有问题):
https://storage.googleapis.com/sampleaudio.appspot.com/audio.wav

GET 请求失败,出现以下错误

/var/log/httpd/error_log
-------------------------------------
File "/opt/python/run/venv/local/lib/python3.6/site-packages/requests/models.py", line 390, in prepare_url
[Sat Nov 23 17:43:49.946393 2019] [:error] [pid 28537] [remote 118.109.93.79:4] raise InvalidURL("Invalid URL %r: No host supplied" % url)
[Sat Nov 23 17:43:49.946398 2019] [:error] [pid 28537] [remote 118.109.93.79:4] requests.exceptions.InvalidURL: Invalid URL 'https:/storage.googleapis.com/sampleaudio.appspot.com/audio.wav': No host supplied

请注意,错误消息中 https: 之后的斜杠奇怪地消失了。
在请求中添加或删除斜杠可能会导致 requests.exceptions.MissingSchema: No schema supplied.

之类的错误

我不知道这段 AWS 代码可能有什么问题,但显然我在这里遗漏了一些关键的东西。
任何帮助或提示将不胜感激!

@application.route("/<path:url>", methods=['GET'])

当您在此处指定 path 时,您实际上指的是 5 个 convertor types 之一。我怀疑 path 转换器需要一个类似 UNIX 的路径,因此删除了双斜杠。

解决此问题的方法是将 'storage API URL' 作为 URL 参数传递给 flask:

所以对您的应用程序的请求 URL 将是:

http://localhost:5000/?url=https://storage.googleapis.com/sampleaudio.appspot.com/audio.wav

然后您将在 Python 中处理此问题:

@application.route("/", methods=['GET'])
def converting_audio_task():
    import requests
    url = request.args.get('url')

    if url:
        r = requests.get(url)
        file_name = 'audio.wav'
        with open(file_name,'wb') as f:
            f.write(r.content)
        # eventually
        return 'success. Ingested URL: %s' % (url,) ,200
    else:
        return 'url arg missing', 404

使用此方法 url 可以正确到达后端。

值得注意的是,这种方法存在一些问题:

  • 存储 API URL 可能会出现在服务器日志中,因为它是请求 URL 字符串的一部分。另一种方法是 POST 数据。
  • 当您写入文件时,您是在写入应用服务器的磁盘。我不确定 if/how EB 分配了这个存储空间。另一种方法是使用 boto3 python client.
  • 写入像 S3 这样的对象存储
  • 如果您处理大型音频文件,应用程序将在从 Google 下载曲目时阻塞。这意味着在阻塞函数(requests.get 和本例中的文件写入操作)完成之前,客户端不会得到响应。可以在以下位置找到对此以及如何在亚马逊环境中处理该问题的更好解释:AWS Elastic Beanstalk Worker Environments.