Hello, Manuel. The answer to your problem is to refactor the libraries in the "sans I/O" style.
Take a look here: http://sans-io.readthedocs.io/ On Thu, 8 Jun 2017 at 19:32 manuel miranda <manu.miran...@gmail.com> wrote: > Hello everyone, > > After using asyncio for a while, I'm struggling to find information about > how to support both synchronous and asynchronous use cases for the same > library. > > I.e. imagine you have a package for http requests and you want to give the > user the choice to use a synchronous or an asynchronous interface. Right > now the approach the community is following is creating separate libraries > one for each version. This is far from ideal for several reasons, some I > can think of: > > - Code duplication, most of the functionality is the same in both > libraries, only difference is the sync/async behaviors > - Some new async libraries lack functionality compared to their sync > siblings. Others will introduce bugs that the sync version already solved > long ago, etc. > - Different interfaces for the user for the same exact functionality. > > In summary, in some cases it looks like reinventing the wheel. So now > comes the question, is there any documentation, guide on what would be best > practice supporting this kind of duality? I've been playing a bit with that > on my own but I really don't know if I'm doing something stupid or not. > Simple example: > > """ > import asyncio > > > class MyConnector: > > @classmethod > async def get(cls, key): > return key > > > class AsyncClient: > > async def get(self, key): > return await MyConnector.get(key) > > > class SyncClient: > > def __init__(self): > self.loop = asyncio.get_event_loop() > > def get(self, key): > return self.loop.run_until_complete(MyConnector.get(key)) > > > def sync_call(): > client = SyncClient() > print(client.get("sync_key")) > > > async def async_call(): > client = AsyncClient() > print(await client.get("async_key")) > > > if __name__ == "__main__": > loop = asyncio.get_event_loop() > loop.run_until_complete(async_call()) > sync_call() > """ > > This is in case the underlying connector is asynchronous already. If its > synchronous and you want to support both modes, you have to rewrite the IO > interactions of MyConnector into a new AsyncMyConnector to support asyncio > and then use one or the other accordingly in the upper classes. > > Am I doing it right or there is another better/alternative way? > > Thanks for your time, > > Manuel > _______________________________________________ > Async-sig mailing list > Async-sig@python.org > https://mail.python.org/mailman/listinfo/async-sig > Code of Conduct: https://www.python.org/psf/codeofconduct/ > -- Luciano Ramalho | Author of Fluent Python (O'Reilly, 2015) | http://shop.oreilly.com/product/0636920032519.do | Technical Principal at ThoughtWorks | Twitter: @ramalhoorg
_______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/