Python 来自SQL的AWS签名URL

Python 来自SQL的AWS签名URL,python,sql,django,amazon-s3,boto3,Python,Sql,Django,Amazon S3,Boto3,我在S3存储桶中有很多静态内容,没有公共读取权限。我想通过生成签名URL来提供对此内容的访问 我在大多数用例中使用python和boto3库。我有一些原始的SQL查询,它们直接从数据库中提取URL并将其直接转储到浏览器。我不希望在服务器上循环所有结果,使用python将URL转换为签名URL,然后将其发送到浏览器。我更希望有一个类似于这种魔力的SQL 而不是 从照片中选择imageFileUrl 我希望能做一些类似的事情 从照片中选择签名的URL图像文件URL 用于此的python boto类/

我在S3存储桶中有很多静态内容,没有公共读取权限。我想通过生成签名URL来提供对此内容的访问

我在大多数用例中使用python和boto3库。我有一些原始的SQL查询,它们直接从数据库中提取URL并将其直接转储到浏览器。我不希望在服务器上循环所有结果,使用python将URL转换为签名URL,然后将其发送到浏览器。我更希望有一个类似于这种魔力的SQL

而不是

从照片中选择imageFileUrl

我希望能做一些类似的事情

从照片中选择签名的URL图像文件URL

用于此的python boto类/函数似乎是botocore.signers.RequestSigner.sign

在深入研究我的用例时,它的真正内容至少看起来是botocore.auth.HmacV1QueryAuth及其get\u签名、canonical\u字符串、sign\u字符串和_inject\u签名函数

以前有人解决过这个问题吗?我走对了吗

我正在使用python 3、django 2和postgresql 10

编辑: 我可以考虑使用这里讨论的CursRoWorkPrasePARAM来制作自己的游标。
也许可以找到一种方法来传递函数映射,这样任何需要特别注意的列都可以在原点处获得正确的结果,而不是再次循环结果集。我们拭目以待

我认为这是不可能的,我想不出任何其他方法来避免循环并生成签名。s3也不支持一次生成多个文件的签名。

以下是一些Python,它可以使用Python2.7生成预签名URL,Python2.7是Redshift使用的版本:

导入base64 进口hmac 进口沙 导入URL库 导入时间 密钥='abc123' OBJECT='/my bucket/foo' 持续时间=120 有效期 到期时间=inttime.time+持续时间 生成签名 h=hmac.newSECRET\u KEY,GET\n\n\n+strexpiry\u epoch+\n+OBJECT,sha signature=urllib.quote_plusbase64.encodestringh.digest.strip 把这个放在URL后面 打印?AWSAccessKeyId=AKIAxxx&Expires=+strexpiry\u epoch+&Signature=+Signature 它将输出要附加到URL的参数,以允许通过预签名的URL进行访问

您需要将您的密钥放入代码中


希望您可以将此代码转换为红移中的用户定义函数。

最后我只是循环了一下结果。我仍然认为可以用自定义光标来代替。我最终可能会这么做

下面是我创建的原始sql帮助程序的要点。它允许像这样的干净代码:

from Acme.db import AcmeQuery

sql = 'select id, "pdf_url" from books where status=%(status)s limit 10'
params = {'status': 'A'}

s3signer = AcmeQuery.S3Signer(cols=['pdf_url'])

rows = AcmeQuery(sql, params=params, row_modifier=s3signer).run()
这是它的主要部分。完整代码的要点是什么

class AcmeQuery(object):
  def run(self):
    with connection.cursor() as cursor:
          cursor.execute(sql, params)

          # covert list of tuples to list of dictionaries
          rows = dictfetchall(cursor)

          # post process each row with a custom function
          # function must accept the as a dictionary as its first argument
          # other arguments may be accepted as well via kwargs
          if self.row_modifier:
              for row in rows:
                  self.row_modifier.func(row, **self.row_modifier.params)

   return rows

class RowModifier(object):
    def __init__(self, func, params=None):
        self.func = func
        self.params = params or {}

谢谢我们使用的是一个内置的postgresql服务器,但postgresql也允许python中的用户定义函数。所以这肯定是一个选择。哎呀!抱歉,我错误地假设为红移,但我看到您正在使用PostgreSQL。同样的一般方法仍然适用。