with open(path_file, "rb") as f: res = requests.post(url, data=f, timeout=600)
我在 server 端,从 tornado_request 中该如何接收这个文件流并保存下来呢。
谢谢各位的不吝赐教。
就比如例子中的我假设有个长耗时的任务, 怎么写才会简单点?
import tornado.ioloop import tornado.web import time import _thread # 模拟耗时任务 def long_work(arg): time.sleep(5) yield arg * 1024 def mycoroutine(func): def wrapper(self): gen = func(self) work_gen = next(gen) def fun(): result = next(work_gen) try: gen.send(result) except StopIteration: pass _thread.start_new_thread(fun, ()) return wrapper class IndexHandler(tornado.web.RequestHandler): @tornado.web.asynchronous @mycoroutine def get(self): arg = 10 # 假设请求的参数 result = yield long_work(arg) self.finish(f'<h1>Index {result}</h1>') class SyncHandler(tornado.web.RequestHandler): def get(self): self.write('<h1>SyncHandler</h1>') def make_app(): return tornado.web.Application([ (r'/', IndexHandler), (r'/sync', SyncHandler) ]) if __name__ == '__main__': app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start()
]]>网上看了半天例子, 照着做了做, 貌似行不通
class AsyncTaskHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous @tornado.gen.coroutine def get(self, *args, **kwargs): resp = yield tornado.gen.Task(self.do_something) self.finish(resp) @tornado.gen.coroutine def do_something(self, *args, **kwargs): time.sleep(10) return {'message': 'OKOK'}
]]>python version : >=3.4
]]>@gen.coroutine def get(self): http_client = AsyncHTTPClient() response1, response2 = yield [http_client.fetch(url1), http_client.fetch(url2)]
这个时候, 1,2 是同时发送出去的,也就是说使用这种方式,可以让 n 个请求,同时发出去,等他们都返回了再统一返回。
那么我要如何保证,其中一个请求坏了,其余的结果依旧可用?
]]>nginx
反向代理tornado
实例,怎么重定向到首页url
]]>写了一个测试用的小脚本,期望遇到 404 的时候能够触发我自己声明的 write_error 函数,然而 write_error 并没有生效,输出的是 tornado 默认的 404 页面。
代码如下:
#!/bin/env python3.5 #coding:utf-8 import os import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options define("port", default=8000, help="端口", type=int) class BaseHandler(tornado.web.RequestHandler): def write_error(self, stat, **kw): self.write('Func write_error !') class IndexHandler(BaseHandler): def get(self): self.write('hello') handlers = [ (r'/index', IndexHandler), ] settings = { 'template_path': os.path.join(os.path.dirname(__file__), "templates"), 'static_path': os.path.join(os.path.dirname(__file__), 'static'), } if __name__ == '__main__': tornado.options.parse_command_line() app = tornado.web.Application(handlers=handlers, **settings) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) print(options.port) tornado.ioloop.IOLoop.instance().start()
然后去 google 了一下,把 BaseHandler 成了这样,但是 404 的时候还是返回了默认的 404 页面:
class BaseHandler(tornado.web.RequestHandler): def _handle_request_exception(self, e): self.write_error(404) def send_error(self, stat, **kw): self.write_error(404) def write_error(self, stat, **kw): self.write('Func write_error !')
]]>tornado.httpclient.AsyncHTTPClient
类的 fetch()
方法的源代码。我没有在里面找到任何"fetch"的动作,它是怎么实现 “ Executes a request, asynchronously returning an HTTPResponse
”的? 完整代码在: https://github.com/tornadoweb/tornado/blob/master/tornado/httpclient.py
def fetch(self, request, callback=None, raise_error=True, **kwargs): """Executes a request, asynchronously returning an `HTTPResponse`. The request may be either a string URL or an `HTTPRequest` object. If it is a string, we construct an `HTTPRequest` using any additional kwargs: ``HTTPRequest(request, **kwargs)`` This method returns a `.Future` whose result is an `HTTPResponse`. By default, the ``Future`` will raise an `HTTPError` if the request returned a non-200 response code (other errors may also be raised if the server could not be contacted). Instead, if ``raise_error`` is set to False, the response will always be returned regardless of the response code. If a ``callback`` is given, it will be invoked with the `HTTPResponse`. In the callback interface, `HTTPError` is not automatically raised. Instead, you must check the response's ``error`` attribute or call its `~HTTPResponse.rethrow` method. """ if self._closed: raise RuntimeError("fetch() called on closed AsyncHTTPClient") if not isinstance(request, HTTPRequest): request = HTTPRequest(url=request, **kwargs) else: if kwargs: raise ValueError("kwargs can't be used if request is an HTTPRequest object") # We may modify this (to add Host, Accept-Encoding, etc), # so make sure we don't modify the caller's object. This is also # where normal dicts get converted to HTTPHeaders objects. request.headers = httputil.HTTPHeaders(request.headers) request = _RequestProxy(request, self.defaults) future = TracebackFuture() if callback is not None: callback = stack_context.wrap(callback) def handle_future(future): exc = future.exception() if isinstance(exc, HTTPError) and exc.response is not None: response = exc.response elif exc is not None: response = HTTPResponse( request, 599, error=exc, request_time=time.time() - request.start_time) else: response = future.result() self.io_loop.add_callback(callback, response) future.add_done_callback(handle_future) def handle_response(response): if raise_error and response.error: future.set_exception(response.error) else: future.set_result(response) self.fetch_impl(request, handle_response) return future def fetch_impl(self, request, callback): raise NotImplementedError()
更多详细信息可访问: https://github.com/alex8224/gtornado
]]>def get(self): time.sleep(100) self.write('hello test')
如果程序执行的时候中间处理一个需要很多时间,这个时候有一个新的请求
那么第二个请求需要等待第一个请求执行完才开始执行第二个操作
接着用 nginx 做了一个负载均衡,开了 3 个 tornado
upstream to.com{ server 127.0.0.1:8887; server 127.0.0.1:8888; server 127.0.0.1:8889; }
可是中间还是有机率切到同一个端口上面,然后又要等待处理,有什么其他处理方面吗?
]]>在用户认证时,我覆写了 BaseHandler,以便使用内置的 current_user() 方法与 is_authenticated 修饰器。
class BaseHandler(tornado.web.RequestHandler): def get_current_user(self): return self.get_secure_cookie('user')
在某步中,我加了判断 if self.current_user then xxx,此时即便登录了也无法执行 xxx,如果我把判断写成 if self.get_current_user then xxx,便能成功确认登录,xxx 就执行了。
请问这可能是什么问题?
]]>网上搜索无果,问题和这大哥一样:
http://stackoverflow.com/questions/20290020/tornado-next-query-string-url-parameter
不过该答案并未解决问题, 所以继续来v站求解
from tornado.concurrent import Future
def async_fetch_future(url):
http_client = AsyncHTTPClient()
my_future = Future()
fetch_future = http_client.fetch(url)
fetch_future.add_done_callback(
lambda f: my_future.set_result(f.result()))
return my_future
什么协程,异步迷迷糊糊的!
完全不懂 my_future = Future() 为什么要生成个 Future 对象,最后又返回它!!已经痛苦了几天了!!大神来解救下我吧
]]>1、多个进程同时读取SQLite,会有锁定么? 网上说多个进程可以同时读写,但说写的时候有锁定,那读的时候,是不是都能立马返回?如果可以立马返回, 那应该可以开多个 Tornado 了吧?
2、多个线程之间,不能共享句柄么?网上说,多线程之间共享句柄可能存在问题,那多线程查询的话,每次要connect,然后在close么? 怎么样能在 Tornado 里保持SQLite的长连接呢?
目前的需求是: SQLite 只读,没有写的需求。
]]>求教如何在 {% %} 里面调用 jQuery获得的data
]]>请问有什么要注意的?
]]>Torngas 是基于Tornado的应用开发框架,tornado是一个异步非阻塞的web框架,但是由于其小巧灵活,并没有一个统一,通用的 应用层框架解决方案。Torngas 大量参考和借鉴了Django的设计模式,形成一套基于tornado的Django like应用层开发框架。
这个框架已经应用在千万级PV的项目里,现在开源出来,希望对大家有用。^ _^
RequestHandler 貌似没有传进来端口号?
]]>