【问题标题】:How to upload a file to s3 from a file upload form after modifying it with PIL?使用PIL修改文件后如何从文件上传表单将文件上传到s3?
【发布时间】:2015-01-28 07:36:05
【问题描述】:

代码如下:

app.config['DEBUG']= True


if request.method == 'POST' and request.form['file_submit']:
        print request.form
        print request.files['image']
        if request.files['image']:
            print 'foshhh'
            image_file = request.files['image']
            img = PIL.Image.open(image_file.stream)
            print img
            if request.form['make_transparent']:
                threshold=100
                print 'changin sizesd'
                dist=5
                # np.asarray(img) is read only. Wrap it in np.array to make it modifiable.
                arr=np.array(np.asarray(img))
                r,g,b,a=np.rollaxis(arr,axis=-1)
                mask=((r>threshold)
                    & (g>threshold)
                    & (b>threshold)
                    & (np.abs(r-g)<dist)
                    & (np.abs(r-b)<dist)
                    & (np.abs(g-b)<dist)
                    )
                arr[mask,3]=0
                img=Image.fromarray(arr,mode='RGBA')
            if request.form['change_size']:
                img = Image.open('out.png')
                img.thumbnail(size,Image.ANTIALIAS)
                img.save('out.png',"PNG")

            img.save('out.png',"PNG")
            print os.path.getsize("out.png")   #from answer
            assert os.path.isfile("out.png")   #from answer
            conn = S3Connection(AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY)
            b = conn.get_bucket('snappie.watermarks')
            k = Key(b)
            k.key = "test.png"
            k.set_metadata('Content-Type', 'image/png')
            k.set_contents_from_filename("out.png")
            print "got file"
            return redirect("https://s3.amazonaws.com/snappie.watermarks/"+filename)
        else:
            print 'please upload a file to submit the form!'

这里是html表单:

   <form method="POST" enctype="multipart/form-data" name="file_submit">
            <label>Choose png here.<input type="file" name="image"></label>
            <input type="hidden" name="file_submit" value="yes">
            Change size?<input type="checkbox" name="change_size" value="yes"/>
            Make Background Transparent?<input type="checkbox" name="make_transparent" value="yes"\><br><br>
            <input type="submit" value="submit">
    </form>

问题的一部分是它并没有真正给我一个错误日志。您可以看到这个想法是有 2 个复选框可以修改图像文件。如果第一个被选中,它“变得透明”,如果第二个被选中,它会改变大小。

我认为图像对象在转换和修改时的类型存在问题,尤其是当它被传递到此对象时:k.set_contents_from_filename("out.png")

这里有什么帮助吗?这是服务器日志给我的唯一输出:

GET
127.0.0.1 - - [18/Jan/2015 15:42:26] "GET / HTTP/1.1" 200 -
POST
ImmutableMultiDict([('file_submit', u'yes')])
<FileStorage: u'birnam_wood.jpg' ('image/jpeg')>
foshhh
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=100x100 at 0x7FDDF4CA6C68>
127.0.0.1 - - [18/Jan/2015 15:42:32] "POST / HTTP/1.1" 400 -

【问题讨论】:

  • 我是否错过了您问题中清楚说明问题所在的部分?也就是说,您想要实现什么、预期的行为以及您观察到什么?
  • 现在提交照片时,出现服务器错误。很明显,某处存在错误。最重要的是,我不相信我正确地传递了文件。在 if 语句中以及在完成更改后将其保存为“out.png”是正确的方法吗?这个“out.png”会与所有图像信息一起临时存储在服务器上吗?我觉得我可以将其保存为“文件”而不是文件名。无论如何,显然目前有问题,因此错误
  • 您是否将您的 Web 应用程序(Flask)置于开发模式?也就是说,当您的代码引发未处理的异常时,您是否看到回溯?
  • 你的意思是 app.config['DEBUG'] = True?我没有设置它,因为我被告知不要在我的 Web 服务器主机 (pythonanywhere.com) 上设置,还是您的意思是不同的开发模式选项?
  • 在生产中,你永远不应该这样做,对吧(这主要是一种安全措施)。出于开发目的,您必须能够查看回溯。否则应该如何调试?所以,是的,出于调查目的,您必须将 app.config['DEBUG'] 设置为 True

标签: python amazon-s3 flask boto


【解决方案1】:

为了正确的调试目的,您确实需要查看回溯。它会告诉你出了什么问题:-)!!

否则:我猜你的一般方法(首先在文件系统中创建一个图像文件,然后使用 boto 上传它)很好。但是,出于调试目的,您可以检查 img.save('out.png',"PNG") 留下的内容。出于调查目的,您可以测试文件是否存在,否则会引发异常:assert os.path.isfile("out.png")。此外,您可能希望使用os.path.getsize("out.png") 打印文件大小。据我记得使用 boto,k.set_contents_from_filename("out.png") 是正确的做法。

也就是说,你做事的顺序是对的。正如 Dmitry 已经指出的那样,S3 很可能存在身份验证/连接问题。通过查看 Traceback,您将找到此问题的详细信息。 boto 回溯将包含错误 AWS 错误响应。

【讨论】:

  • hmm 将 debug 设置为 true 似乎并没有提供回溯。我已经用我添加的代码更新了这个问题,正如你从输出中看到的那样,在此之前它没有提供关于 assert 行或 print 行的任何信息。事实上,在这 2 个 if 语句之后打印任何内容都不会被打印出来。这没有任何意义。就像那些 2 if 语句正在停止一切?但是根本不应该调用它们,因为我没有选中这些框。还有其他方法可以强制它给我回溯吗?
  • 是的,如果我删除这两个 if 语句,它实际上会起作用。显然我想找到一种方法来保留它们:)
  • “就像那 2 个 if 语句正在停止所有事情一样?” 当然,代码中的某些内容是错误,我们知道前!请把这视为理所当然:您需要该回溯才能查看问题所在。回溯会立即告诉您出了什么问题。努力得到这个。如果不能访问 Python 中最重要的调试实例,就无法开发应用程序:异常导致的回溯。
  • 您知道,如果没有看到适当的回溯,这里的人不会想要调试您的代码。我现在有,因为你似乎很合作,看了你的代码 30 秒,也许if request.form['make_transparent']: 引发了 KeyError。你在某个时候打印request.form,我猜相应的输出是ImmutableMultiDict([('file_submit', u'yes')])。因此,'make_transparent' 不是该字典中的有效键。通过查看回溯,您会立即看到这一点。 'change_size' 也不是。
  • 'make_transparent' 是一个有效的密钥,我认为? “change_size”也是如此。它们都是输入类型=隐藏在表单上。我认为您对关键错误的看法可能是正确的。但我不确定为什么?我真的需要那个追溯!我会继续努力想办法做到这一点
【解决方案2】:

请使用以下技巧查看 boto 发送到 S3 的所有原始 http 请求:

import httplib
httplib.HTTPConnection.debuglevel = 1

您也可以使用此提示:

import logging
logging.basicConfig(filename="boto.log", level=logging.DEBUG)

在使用 web 服务器测试功能之前,请尝试从默认的 python 控制台执行一些测试代码:

import httplib
httplib.HTTPConnection.debuglevel = 1

conn = boto.connect_s3(aws_access_key_id='some', aws_secret_access_key='some')
b = conn.get_bucket('snappie.watermarks')
k = Key(b)
k.key = "test.txt"
k.set_contents_from_string('12345')

之后请检查文件是否存在。在任何情况下,您都应该执行所有操作:

key.make_public()

因为默认情况下所有新的存储桶对象都不公开。

【讨论】:

  • 我不明白字符串 '12345' 是从哪里来的?如果我从问题代码中的 url 打开文件,我将如何将其设置为字符串?
  • 在您的示例中,您将一些图像保存在磁盘上,然后尝试使用该图像中的内容创建 S3 密钥。我建议您使用一些抽象代码(以及字符串 12345 作为内容)在存储桶上创建一些 测试密钥,以确保您对存储桶的访问没有任何问题,或者可能存在其他一些访问限制。
  • 当我尝试这样做时,它似乎确实创建了一些东西,但是当我查看它时,它给了我一个 XML 文件似乎没有任何与之关联的样式信息,“test.png”错误“我创建的密钥。我不确定这是否意味着它已被创建?
  • 请使用一些特定的工具来检查 S3 上的文件是否存在。例如,您可以使用 dragondisk.com 。也不要忘记 key.make_public() 。如果没有此命令,您的新存储桶对象将无法从互联网上看到。
  • hmm 实际上,它根本没有被创建。我正在该存储桶中直接检查我的 amazon s3 帐户,并且在我设置的密钥名称下不存在任何文件。我真的认为它只是出错了,因为在文件到达亚马逊 s3 之前我没有正确转换文件。
【解决方案3】:

基本上,我认为当 request.files 字典中没有“图像”对象但请求已发送时,就会形成服务器错误。因此,服务器不知道该怎么做。我通过使用 request.files.get('image') 而不是 request.files['image'] 来修复它。因此,如果没有图像,它会返回 None 而不是给出关键错误。

仍然没有 trackback,虽然我知道每个人都想要一个,因为烧瓶中的这种服务器错误似乎没有返回 traceback。只是浏览器中的“错误请求”错误消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    相关资源
    最近更新 更多