我有一个使用Python/Bottle编写的REST前端来处理文件上传,通常是大文件上传.API以这样一种方式得到:
客户端将PUT作为有效负载发送给文件.除其他外,它发送日期和授权标头.这是针对重播攻击的安全措施 - 请求使用临时密钥,使用目标网址,日期和其他一些内容进行烧录
现在问题.如果提供的日期在15分钟的给定日期时间窗口中,则服务器接受请求.如果上传需要足够长的时间,则会比允许的时间增量更长.现在,使用装饰器瓶视图方法完成请求授权处理.但是,除非上传完成,否则瓶子不会启动调度过程,因此验证会在较长的上载时失败.
我的问题是:有没有办法解释瓶子或WSGI立即处理请求并流式传输上传?由于其他原因,这对我也很有用.或任何其他解决方案?在我写这篇文章时,我想到了WSGI中间件,但我仍然喜欢外部洞察力.
我愿意切换到Flask,甚至其他Python框架,因为REST前端非常轻量级.
谢谢
我知道不建议在生产中运行Bottle或Flask应用程序,python myapp.py --port=80
因为它只是一个开发服务器.
我认为也不建议运行它python myapp.py --port=5000
并将其链接到Apache:RewriteEngine On
,RewriteRule /(.*) http://localhost:5000/$1 [P,L]
(或者我错了?),因为WSGI是首选.
所以我现在正在设置Python app <-> mod_wsgi <-> Apache
(没有gunicorn或其他工具来保持简单).
问题:当使用WSGI时,我知道它是Apache,mod_wsgi
并且会myapp.py
在请求到来时自动启动/停止运行足够的进程,但是:
例:
我做了一些更改myapp.py
,并且我想重新启动运行它的所有进程,这些进程已由mod_wsgi启动(注意:我知道mod_wsgi可以观察源代码的更改,并重新启动,但这仅适用于对其进行的更改. wsgi文件,而不是.py文件.我已经读过touch myapp.wsgi
可以解决这个问题,但更一般地说我希望能够手动停止并重新启动)
我想暂时停止整个应用程序myapp.py
(它的所有实例)
我不想用service apache2 stop
它,因为我也用Apache 运行其他网站,而不仅仅是这个(我有几个VirtualHosts
).出于同样的原因(我使用Apache运行其他网站,而某些客户端可能同时下载1 GB文件),我不希望这样做service apache2 restart
会对使用Apache的所有网站产生影响.
我正在寻找比kill pid
SIGTERM等更清洁的方式(因为我读过它不建议在这种情况下使用信号).
注意:我已经阅读了如何从mod_wsgi执行优雅的应用程序关闭,它有所帮助,但这里是补充问题,而不是重复.
我一直在从瓶子转移到烧瓶。如果我需要的代码不超过 20 行,我是那种更喜欢编写自己的代码而不是从 Internet 下载软件包的人。以支持Basic
身份验证协议为例。在瓶子里我可以写:
def allow_anonymous():
"""assign a _allow_anonymous flag to functions not requiring authentication"""
def wrapper(fn):
fn._allow_anonymous = True
return fn
return wrapper
def auth_middleware(fn):
"""perform authentication (pre-req)"""
def wrapper(*a, **ka):
# if the allow_anonymous annotation is set then bypass this auth
if hasattr(fn, '_allow_anonymous') and fn._allow_anonymous:
return fn(*a, **ka)
user, password = request.auth or (None, None)
if user is None or not check(user, password):
err = HTTPError(401, text)
err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm)
return err …
Run Code Online (Sandbox Code Playgroud) 我注意到Python Web框架处理请求处理的三种主要方式:装饰器,带有单个请求方法的控制器类,以及带有GET/POST方法的请求类.
我很好奇这三种方法的优点.这些方法中有哪些主要优点或缺点?为了解决问题,这里有三个例子.
瓶子使用装饰器:
@route('/')
def index():
return 'Hello World!'
Run Code Online (Sandbox Code Playgroud)
Pylons使用控制器类:
class HelloController(BaseController):
def index(self):
return 'Hello World'
Run Code Online (Sandbox Code Playgroud)
Tornado使用请求处理程序类和类型的方法:
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
Run Code Online (Sandbox Code Playgroud)
哪种风格是最佳做法?
$ sudo pip install bottle
Downloading/unpacking bottle
Downloading bottle-0.10.7.tar.gz (55Kb): 55Kb downloaded
Running setup.py egg_info for package bottle
Installing collected packages: bottle
Found existing installation: bottle 0.10.7
Uninstalling bottle:
Successfully uninstalled bottle
Running setup.py install for bottle
changing mode of build/scripts-2.6/bottle.py from 640 to 755
changing mode of /usr/local/bin/bottle.py to 755
Successfully installed bottle
>>> help('modules')
blahblah
bottle
blahblah
$ ls /usr/local/lib/python2.6/dist-packages/
bottle-0.10.7.egg-info bottle.py bottle.pyc
Run Code Online (Sandbox Code Playgroud)
但
$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
[GCC 4.4.5] on linux2
Type …
Run Code Online (Sandbox Code Playgroud) 问: 什么是可比的解决方案的例子,在这个环节,除了使用实施GEVENT-socketio和Socket.io.js与瓶?我正在寻找最小的解决方案,它将简单地将一些流量从客户端传递到服务器并使用gevent-socketio,Socket.io.js和bottle返回客户端.
背景:我开发了一个简单的Web应用程序,它为服务器上的远程自定义shell(cli)提供基于Web的终端.浏览器(客户端)从表单输入字段收集shell命令,通过Web套接字将命令传递给gevent.pywsgi.WSGIServer
通过geventwebsocket.WebSocketHandler
处理程序处理请求,处理程序将命令提供给shell,同时通过套接字将输出异步返回到textarea字段在客户端浏览器中的表单中.这是基于瓶子团队提供的一个很好的例子:
http://bottlepy.org/docs/dev/async.html#finally-websockets
这里提供冗余:
example_server.py:
from bottle import request, Bottle, abort
app = Bottle()
@app.route('/websocket')
def handle_websocket():
wsock = request.environ.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
while True:
try:
message = wsock.receive()
wsock.send("Your message was: %r" % message)
except WebSocketError:
break
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketHandler, WebSocketError
server = WSGIServer(("0.0.0.0", 8080), app,
handler_class=WebSocketHandler)
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
client.html:
<!DOCTYPE html>
<html>
<head>
<script …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Apache和mod_wsgi运行Bottle.py.
我在Windows上运行它,使用xampp.python v2.7
我在httpd中的Apache配置:
<VirtualHost *>
ServerName example.com
WSGIScriptAlias / C:\xampp\htdocs\GetXPathsProject\app.wsgi
<Directory C:\xampp\htdocs\GetXPathsProject>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)
我的app.wsgi代码:
import os
os.chdir(os.path.dirname(__file__))
import bottle
application = bottle.default_app()
Run Code Online (Sandbox Code Playgroud)
我的hello.py:
from bottle import route
@route('/hello')
def hello():
return "Hello World!"
Run Code Online (Sandbox Code Playgroud)
当我去的时候,localhost/hello
我收到404错误.我在Apache日志文件中没有任何其他错误,可能缺少基本的东西.
我正在开发一个基于Python的应用程序(HTTP-REST或jsonrpc接口),它将用于生产自动化测试环境.这将连接到运行所有测试脚本的Java客户端.即,不需要人工访问(除了测试应用程序本身).
我们希望在Raspberry Pi上部署它,所以我希望它相对快速且占用空间小.它可能不会得到大量的请求(在最大负载,可能是每秒几个),但它应该能够运行并在很长一段时间内保持稳定.
由于其简单性(一个文件),我已经确定了Bottle作为框架.这是对Flask的折腾.任何认为Flask可能更好的人,让我知道原因.
我对Bottle的内置HTTP服务器的稳定性有点不确定,所以我正在评估这三个选项:
问题:
我有一个Python Bottle应用程序,我想在静态文件中添加Cache-Control.我是新人,所以如果我做错了,请原谅我.
这是函数以及我如何提供静态文件:
@bottle.get('/static/js/<filename:re:.*\.js>')
def javascripts(filename):
return bottle.static_file(filename, root='./static/js/')
Run Code Online (Sandbox Code Playgroud)
要添加Cache-Control,我还添加了一行(我在教程中看到了它)
@bottle.get('/static/js/<filename:re:.*\.js>')
def javascripts(filename):
bottle.response.headers['Cache-Control'] = 'public, max-age=604800'
return bottle.static_file(filename, root='./static/js/')
Run Code Online (Sandbox Code Playgroud)
但是当我在Chrome上检查开发人员工具的标题时:我有Cache-Control:max-age=0
或者Cache-Control:no-cache
我添加了一个使用python的cassandra库的瓶子服务器,但它退出时出现此错误:
Bottle FATAL Exited too quickly (process log may have details)
log显示:
File "/usr/local/lib/python2.7/dist-packages/cassandra/cluster.py", line 1765, in _reconnect_internal
raise NoHostAvailable("Unable to connect to any servers", errors)
所以我尝试使用supervisorctl start Bottle手动运行它,然后它开始没有问题.结论=瓶子服务开始得太快(在需要的cassandra监督服务之前):需要延迟!