Python 如何在使用PIL修改文件上传表单后将其上传到s3?
下面是代码:Python 如何在使用PIL修改文件上传表单后将其上传到s3?,python,amazon-s3,flask,boto,Python,Amazon S3,Flask,Boto,下面是代码: 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 = req
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!'
请使用以下技巧查看boto发送到S3的所有原始http请求:
导入httplib
httplib.HTTPConnection.debuglevel=1
同样,您也可以使用此提示:
导入日志
logging.basicConfig(filename=“boto.log”,level=logging.DEBUG)
在使用web服务器测试功能之前,请尝试从默认python控制台执行一些测试代码:
导入httplib
httplib.HTTPConnection.debuglevel=1
conn=boto.connect\u s3(aws\u访问\u密钥\u id='some',aws\u机密\u访问\u密钥='some')
b=conn.get_bucket('snapie.watermarks'))
k=键(b)
k、 key=“test.txt”
k、 从字符串('12345')设置内容
在此之后,请检查文件是否存在。在任何情况下,在所有操作之后,您都应该执行:
key.make_public()
因为默认情况下,所有新的bucket对象都不是公共的。为了进行适当的调试,您确实需要查看回溯。它会告诉你出了什么问题:-)强> 否则:我想您的一般方法(首先在文件系统中创建一个图像文件,然后使用boto上传)是可以的。但是,出于调试目的,您可以检查
img.save('out.png',“png”)
留下的内容。出于调查目的,您可以测试文件是否存在,或者引发异常:assert os.path.isfile(“out.png”)
。此外,您可能希望使用os.path.getsize(“out.png”)
打印文件大小。就我记得使用boto时,k.set\u contents\u from\u filename(“out.png”)
是正确的做法
也就是说,你做事的顺序是正确的。正如Dmitry已经指出的那样,S3很可能存在身份验证/连接问题。通过查看回溯,您将发现此问题的详细信息。boto回溯将包含错误AWS错误响应。基本上,我认为服务器错误是在request.files字典中没有“image”对象但请求已发送时形成的。因此服务器不知道该做什么。我通过使用request.files.get('image')而不是request.files['image']修复了它。因此,如果没有图像,它将返回None,而不是给出一个键错误
仍然没有trackback,尽管我知道每个人都想要一个,因为flask中的这种服务器错误似乎不会返回回溯。只需在浏览器中显示一条“错误请求”错误消息 我不明白“12345”这个字符串是从哪里来的?如果我是从url打开文件的,就像我的问题代码中一样,我将如何将其设置为字符串?在您的示例中,您将一些图像保存在磁盘上,然后尝试使用此图像中的内容创建S3密钥。我建议您使用一些抽象代码(以及字符串12345作为内容)在bucket上创建一些测试键,以确保您在访问bucket方面没有任何问题,或者可能存在一些其他访问限制。当我尝试这样做时,它似乎确实创建了一些内容,但当我查看它时,它给了我一个XML文件,该文件似乎没有任何与之相关联的样式信息。我创建的“test.png”键出现错误。我不确定这是否意味着它是创建的?请使用一些特定的工具来检查S3上是否存在文件。例如,您可以使用。另外,不要忘记密钥。将_公开()。如果没有这个命令,你的新bucket对象就无法从互联网上看到。嗯,实际上,它根本就没有被创建。我正在直接检查我的AmazonS3帐户,在我设置的密钥名下没有文件存在。我真的认为它只是出错了,因为在它进入AmazonS3之前,我没有正确地转换文件。我是否错过了你问题中明确说明问题所在的部分?也就是说,你想要实现什么,预期的行为是什么,你观察到了什么?好吧,现在当一张照片被提交时,有一个服务器错误。很明显,在某个地方有一个错误。除此之外,我认为我传递的文件不正确。在if语句中以及修改后都将其保存为“out.png”是正确的方法吗?这个“out.png”是否会与所有图像信息一起临时存储在服务器上?我觉得我可以将它保存为“文件”而不是文件名。在任何情况下,显然当前有问题,因此出现了错误您是否将web应用程序(Flask)置于开发模式?也就是说,当代码引发未处理的异常时,您是否看到回溯?您的意思是像app.config['DEBUG']=True?我没有设置它,因为有人告诉我不要在我的web服务器主机(pythonanywhere.com)上运行,或者你是说使用不同的开发模式选项吗?在生产环境中,你不应该这样做,对吧(这主要是一种安全措施)。出于开发目的,您必须能够看到回溯。否则,您应该如何调试?因此,是的,出于调查目的,您必须将
app.config['DEBUG']
设置为True
。嗯,将DEBUG设置为True似乎不会提供回溯。我已经用我添加的代码更新了这个问题,正如您从输出中看到的,它没有给出任何关于断言行或打印行的信息。事实上,在这两条if语句之后打印任何内容都不会被打印出来。这没有任何意义。它就像那两条如果语句停止了一切?但是他们根本不应该被叫来,因为我没有检查这些框。有没有其他方法可以强迫它给我一个回溯?是的,事实上,如果我删除那两个if语句,它会起作用。显然,我想找到一种方法来保存它们:)“就像那两条if语句阻止了所有事情的发展?”当然,代码中有些地方出错了,我们以前就知道了!请想当然地认为这是理所当然的:你需要回溯,以便看到什么是错误的。追踪会告诉你imm
<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>
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 -