You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
1.7 KiB

4 years ago
  1. """ Payload implemenation for coroutines as data provider.
  2. As a simple case, you can upload data from file::
  3. @aiohttp.streamer
  4. async def file_sender(writer, file_name=None):
  5. with open(file_name, 'rb') as f:
  6. chunk = f.read(2**16)
  7. while chunk:
  8. await writer.write(chunk)
  9. chunk = f.read(2**16)
  10. Then you can use `file_sender` like this:
  11. async with session.post('http://httpbin.org/post',
  12. data=file_sender(file_name='huge_file')) as resp:
  13. print(await resp.text())
  14. ..note:: Coroutine must accept `writer` as first argument
  15. """
  16. import asyncio
  17. import warnings
  18. from .payload import Payload, payload_type
  19. __all__ = ('streamer',)
  20. class _stream_wrapper:
  21. def __init__(self, coro, args, kwargs):
  22. self.coro = asyncio.coroutine(coro)
  23. self.args = args
  24. self.kwargs = kwargs
  25. async def __call__(self, writer):
  26. await self.coro(writer, *self.args, **self.kwargs)
  27. class streamer:
  28. def __init__(self, coro):
  29. warnings.warn("@streamer is deprecated, use async generators instead",
  30. DeprecationWarning,
  31. stacklevel=2)
  32. self.coro = coro
  33. def __call__(self, *args, **kwargs):
  34. return _stream_wrapper(self.coro, args, kwargs)
  35. @payload_type(_stream_wrapper)
  36. class StreamWrapperPayload(Payload):
  37. async def write(self, writer):
  38. await self._value(writer)
  39. @payload_type(streamer)
  40. class StreamPayload(StreamWrapperPayload):
  41. def __init__(self, value, *args, **kwargs):
  42. super().__init__(value(), *args, **kwargs)
  43. async def write(self, writer):
  44. await self._value(writer)