Skip to main content

Provide sync compatibility for your async functions

Project description

Easy Sync

codecov

Provide sync compatibility for your async functions

Motivation

Everytime I provide a Python package to my user, I'm expected to provide both sync version and async version API at the same time.

But I don't want to always duplicate implementations for both synchronous and asynchronous versions of the same thing, and think out two name for each of them, as it is a waste of time, and far from DRY.

I hope there is some magic which can turn my asynchronous function implementations into synchronous versions, so I can write once and get both of them.

I call this magic @sync_compatible here, your decorated function f can be called via both await f(x) (in a asynchronous context) or f(x).wait() (in a synchronous context).

Features

  1. Expose a single function name for both async and sync version
  2. Automatic provide a sync version from your async function definition (via Metaprogramming)
  3. Lightweight, pure python, and no dependencies
  4. Complex cases such as list comprehensions, nested function definitions are also supported, feel free to write your pythonic code.
  5. Strict type annotation are contained, and validated by pylance the strict mode. all type information is kept here
  6. Unit tests contained, and test coverage ratio is monitored

Usage

Install via pip install easy-sync or poetry add easy-sync from (pypi)

The Magic Style

from easy_sync import sync_compatible

@sync_compatible
async def async_add(a: int, b: int) -> int:
    await asyncio.sleep(1)
    return a + b

print(async_add(1, 2).wait())

NOTE: There are some requirements

This will generate a sync version code of your async function, the logic is:

  1. Replaces all await f(...) statements into f(...).wait()
  2. Replaces all await asyncio.sleep(...) statements into time.sleep(...).

For other case, you might need to define a wrapper for yourself, via The Name Reusing Style of @sync_compatible

Tips about extra decorators

  1. Extra decorators is ignored in the generated sync function, since they are written for async functions and probably not works on sync functions, keep them might cause unexpected error. If you really need them, please use The Name Reusing Style and add decorators manually.
  2. When used with extra decorators, lift this outer can solve .wait() method not found issues.

The Name Reusing Style

Instead of use the magic, you are allowed to provide the sync function yourself, and expose a single name to users.

This is useful to define your own wrapper, or cover some special cases the magic style cannot handle.

from easy_sync import sync_compatible

@sync_compatible(sync_fn = _sync_fetch_url)
async def fetch_url(url: str) -> str:
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

def _sync_fetch_url(url: str) -> str:
    return requests.get(url).text

@sync_compatible
async def get_data() -> str:
    return await fetch_url("https://site.name/path")

print(get_data().wait())

Run tests and Contribute

You can use nix develop . or poetry shell under the project root to enter the develop environment.

Run unit tests via pytest, or run pytest --cov=src for coverage report.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

easy_sync-0.2.2.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

easy_sync-0.2.2-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file easy_sync-0.2.2.tar.gz.

File metadata

  • Download URL: easy_sync-0.2.2.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.11.9 Linux/6.9.7-zen1

File hashes

Hashes for easy_sync-0.2.2.tar.gz
Algorithm Hash digest
SHA256 aa4a0a765f723d76220049d9cda65700da6274a9dd27983116c641585839d236
MD5 80f8c8c131f3ad14eafea7f4d5871e16
BLAKE2b-256 d0f10f4ff5868e7e661abde67fc5b99b1efd84dacef95adb0e9380ede589470a

See more details on using hashes here.

File details

Details for the file easy_sync-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: easy_sync-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.11.9 Linux/6.9.7-zen1

File hashes

Hashes for easy_sync-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4e5f44bfd764b42b9d985b1321c8b36fa26ababd19e389c6e749c047aeca1e10
MD5 9122e6955f808cf194e4b0bb6d76487e
BLAKE2b-256 2ccff90b4f7920cf8dd377958c1cff4fd57a933b0654763fd02a23aec6f393f7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page