使用 zipfile zlib python 和 mailgun 时,Mailgun 仅在 Python 脚本中发送部分 zip 文件

Mailgun only sends partial zip file in Python script when using zipfile zlib python and mailgun

编辑:我试图实现 gzip 但无法让它与 zipfile 库一起工作。文档似乎表明 zlib 是唯一兼容的库。 我还尝试重新安装 zlib。

我 运行 遇到了一个我创建的 Python 脚本的奇怪问题。该脚本的要点是从 SQL 服务器提取一些数据,将其转储到 CSV 中,将其压缩(压缩)并通过 Mailgun API.

通过电子邮件发送

如果我在没有使用 zlib 压缩的情况下压缩文件,mailgun 会获取整个压缩文件(14mb 包含测试数据)并成功通过电子邮件发送。我可以从电子邮件和我的本地文件系统下载 zip 文件,并在其中打开 csv 文件而不会出现问题。

但是一旦我添加了zipfile.ZIP_DEFLATED压缩方法,我就遇到了问题。生成的 zip 在我的本地文件系统上下降到 365kb,并且打开得很好。但是当我查看生成的电子邮件时,zip 文件的大小严重 t运行cated,约为 865 字节。如果我尝试下载并打开它,我会收到来自 Windows.

的 "this is not a valid zip file" 错误

为什么 Mailgun 发送完整的未压缩的 zip,而不是压缩的 zip,即使它在我的文件系统上可以正常打开?即使代码显然是同步的,我也尝试过一件疯狂的事情,就是在函数调用之间添加暂停,以防压缩需要更多时间。这没有帮助。

代码在下面,为简洁起见被剪掉了。

import pyodbc
import unicodecsv
import time
import requests
import zipfile
import zlib

now = time.localtime(time.time())
today = time.strftime("%Y-%m-%d %H%M%p", now)

filename_sql1 = "SCORM Courses " + today
filename_sql2 = "Non-SCORM Courses " + today

print "ready...."

class ODBCtoCSV(object):

    def __init__(self):

    def getEncodedData (self, doubleList):
        data=struct.pack(len(doubleList) * 'd', *doubleList)
        return base64.b64encode(data)

    def dump(self, sql, filename, include_headers=True):
        f = unicodecsv.writer(file(filename + ".csv", 'wb'))

        cnxn = pyodbc.connect(self.connect_string)
        c = cnxn.cursor()
        c.execute(sql)

        if include_headers:
            f.writerow([d[0] for d in c.description])


            f.writerows(c.fetchall())
            cnxn.close()

def generatereport(s, filename):

    print "Processing %s" % (filename)
    if __name__ == '__main__':

        query = ODBCtoCSV()
        query.dump(s, filename)
        f = open(filename + ".csv", 'rb')


def zippy(filename):
    zf = zipfile.ZipFile(filename + ".zip", "w", zipfile.ZIP_DEFLATED)
    zf.write(filename + ".csv")
    zf.close()


def send_notification_message(filename):
    return requests.post(
        "xxxxxxx",
        auth=("api", "xxxx"),
        files=[("attachment", open(filename + ".zip"))],
        data={"from": "xxxxxxx",
              "to": ["xxxxxx"],
              "subject": " Reports are Available",
              "text": "This is an automated message. The reports have run successfully and are available via attachment.",
              "html": "<p><b>This is an automated message.</b></p><p>The reports have run successfully and are available via attachment.</p>",
              "o:tag": "xxxxxx"})        

generatereport(sql1, filename_sql1)
zippy(filename_sql1)
print filename_sql1 + "Succesfully generated"
generatereport(sql2, filename_sql2)
zippy(filename_sql2)
print filename_sql2 + "Succesfully generated"
send_notification_message(filename_sql1)
send_notification_message(filename_sql2)

exit

我通过在 Mailgun 调用中将模式文件 IO 模式更改为“rb”解决了这个问题。

我不确定为什么它适用于未压缩的 zip 文件,而不是压缩的 zip 文件。修改后的代码如下。

files=[("attachment", open(filename + ".zip", "rb"))],