def _data_and_files(self, data=True, files=True, future=None): result = {}, None chunk = None if future is None: stream = self.environ.get('wsgi.input') if self.method not in ENCODE_URL_METHODS and stream: chunk = stream.read() if isinstance(chunk, Future): return chain_future( chunk, partial(self._data_and_files, data, files)) else: chunk = future if chunk is not None: content_type, options = self.content_type_options charset = options.get('charset', 'utf-8') if content_type in JSON_CONTENT_TYPES: result = json.loads(chunk.decode(charset)), None elif content_type: self.environ['wsgi.input'] = BytesIO(chunk) result = parse_form_data(self.environ, charset) else: result = chunk, None self.environ['wsgi.input'] = BytesIO(chunk) self.cache.data_and_files = result return self.data_and_files(data, files)
def test_chain(self): loop = get_event_loop() future = Future() next = chain_future(future, callback=lambda r: r+2) loop.call_later(0.2, future.set_result, 1) result = yield next self.assertEqual(result, 3)
def execute_task(self, jobname, **kwargs): '''Execute a task immediately ''' kwargs['queue'] = False task = self._create_task(jobname, **kwargs) if task: future = TaskFuture(task.id, loop=self._loop) coro = self._execute_task(None, task) return chain_future(coro, next=future)
def get(self, *args, **kw): '''Get a single model ''' if len(args) == 1: return self._read_store.get_model(self, args[0]) elif args: raise QueryError("'get' expected at most 1 argument, %s given" % len(args)) else: return chain_future(self.filter(**kw).all(), self._get)
def queue(self, message, callback=True): '''Queue the ``message``. If callback is True (default) returns a Future called back once the message is delivered, otherwise return a future called back once the messaged is queued ''' future_done = MessageFuture(message.id, self.backend, loop=self._loop) if message.queue: self.queued_messages[message.id] = future_done else: # the task is not queued instead it is executed immediately coro = self.backend.execute(message) return chain_future(coro, next=future_done) # queue the message coro = self._queue_message(message, future_done) if callback: ensure_future(coro, loop=self._loop) return future_done else: future = MessageFuture(message.id, self.backend, loop=self._loop) return chain_future(coro, next=future)
def _data_and_files(self, data=True, files=True, stream=None, future=None): if future is None: data_files = parse_form_data(self.environ, stream=stream) if isawaitable(data_files): return chain_future( data_files, partial(self._data_and_files, data, files, stream)) else: data_files = future self.cache.data_and_files = data_files return self.data_and_files(data, files, stream)
def wait(self, callback=None): '''Waits for the transaction have finished. :param callback: optional function called back once the transaction has finished. The function receives one parameter only, the transaction. :return: a :class:`~asyncio.Future` ''' executed = self._executed if executed is None: executed = self.commit() return chain_future(executed, callback) if callback else executed
def queue(self, message, callback=True): """Queue the ``message``. If callback is True (default) returns a Future called back once the message is delivered, otherwise return a future called back once the messaged is queued """ future_done = MessageFuture(message.id, self.backend, loop=self._loop) if message.queue: self.queued_messages[message.id] = future_done else: # the task is not queued instead it is executed immediately coro = self.backend.execute(message) return chain_future(coro, next=future_done) # queue the message coro = self._queue_message(message, future_done) if callback: ensure_future(coro, loop=self._loop) return future_done else: future = MessageFuture(message.id, self.backend, loop=self._loop) return chain_future(coro, next=future)
def read(self, maxbuf=None): """Return bytes in the buffer. If the stream is not yet ready, return a :class:`asyncio.Future` which results in the bytes read. """ if not self._waiting: body = self.recv() if self.done(): return self._getvalue(body, maxbuf) else: self._waiting = chain_future(self.on_message_complete, lambda r: self._getvalue(body, maxbuf)) return self._waiting else: return self._waiting
def read(self, maxbuf=None): '''Return bytes in the buffer. If the stream is not yet ready, return a :class:`asyncio.Future` which results in the bytes read. ''' if not self._waiting: body = self.recv() if self.done(): return self._getvalue(body, maxbuf) else: self._waiting = chain_future( self.on_message_complete, lambda r: self._getvalue(body, maxbuf)) return self._waiting else: return self._waiting
def wait_for_body_middleware(environ, start_response=None): '''Use this middleware to wait for the full body. This middleware wait for the full body to be received before letting other middleware to be processed. Useful when using synchronous web-frameworks such as :django:`django <>`. ''' def _wsgi_input(value): environ['wsgi.input'] = BytesIO(value) if environ['wsgi.input']: stream = environ['wsgi.input'] chunk = stream.read() if isfuture(chunk): return chain_future(chunk, callback=_wsgi_input) else: _wsgi_input(chunk)
def render(self, request=None, callback=None): '''Render this string. This method returns a string or a :class:`~asyncio.Future` which results in a string. On the other hand, the callable method of a :class:`.String` **always** returns a :class:`~asyncio.Future`. ''' stream = [] async = False for data in self.stream(request): if is_async(data): async = True stream.append(data) if not callback: callback = self.to_string if async: return chain_future(multi_async(stream), callback=callback) else: return callback(stream)
def render(self, request=None, callback=None): '''Render this string. This method returns a string or a :class:`~asyncio.Future` which results in a string. On the other hand, the callable method of a :class:`.String` **always** returns a :class:`~asyncio.Future`. ''' stream = [] async = False for data in self.stream(request): if isawaitable(data): async = True stream.append(data) if not callback: callback = self.to_string if async: return chain_future(multi_async(stream), callback=callback) else: return callback(stream)
def __call__(self, request): stream = multi_async(self.stream(request)) return chain_future(stream, callback=self.to_string)