Registry / http-networking / greenback

greenback

JSON →
library1.3.0pypypi✓ verified 24d ago

Greenback is a Python library that enables calling asynchronous code from a synchronous context within an active `asyncio` or `Trio` event loop. It bridges the gap between synchronous and asynchronous programming, allowing for gradual migration of codebases and interoperability with async-unaware libraries. The current version is 1.3.0, and it maintains a focused release cadence as a small, specialized utility built on `greenlet`.

pip install greenback
INSTALL
IMPORT
SIG · GREENBACK
G
greenback
http-networkingpythonv1.3.0
Install
2.0s avg
Import
91ms
Disk
21MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.3.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.098s · 24.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 2.0s · import 0.084s · 22MB
21MB installed
● package 21MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

greenback
import greenback
Primary import for all functionalities.
ensure_portal
await greenback.ensure_portal()
greenback.ensure_portal() (without await)
Must be awaited as it sets up the greenlet context within an async task.
await_
greenback.await_(async_function())
await async_function() (in sync code)
Used to 'await' an async function from a synchronous context where `await` keyword is not allowed.
with_portal_run_sync
greenback.with_portal_run_sync(sync_function)
Runs a synchronous function with a portal, useful for scoping performance impact.

This quickstart demonstrates how to use `greenback` to call an `async` function (`fetch_data`) from a regular `sync` function (`process_item`, `another_sync_task`) within an `asyncio` event loop. First, `await greenback.ensure_portal()` is called in the main async task to set up the necessary `greenlet` context. Then, `greenback.await_()` is used in the synchronous functions to execute the async calls. The `with_portal_run_sync` helper is also shown for explicit portal scoping.

import asyncio import greenback # An async function we want to call from sync code async def fetch_data(item_id): print(f"[Async] Fetching data for {item_id}...") await asyncio.sleep(0.1) # Simulate I/O return f"Data for {item_id}" # A synchronous function that needs to call an async function def process_item(item_id): print(f"[Sync] Processing item {item_id}") # Call the async function from sync context using greenback.await_ data = greenback.await_(fetch_data(item_id)) print(f"[Sync] Received: {data}") return data # The main async entry point async def main(): # Ensure a greenback portal is set up for this task await greenback.ensure_portal() print("Portal ensured.") # Call the synchronous function that will use greenback result = process_item("A123") print(f"Main task received: {result}") # Example using with_portal_run_sync def another_sync_task(): print("[Sync 2] Starting another sync task.") result2 = greenback.await_(fetch_data("B456")) print(f"[Sync 2] Got: {result2}") return result2 final_result = greenback.with_portal_run_sync(another_sync_task) print(f"Main task got final result: {final_result}") if __name__ == "__main__": asyncio.run(main())
Debug
Known issues
gotchaGreenback works by manipulating the C stack via `greenlet`. Poorly-behaved C extension modules that violate Python's assumption that objects are fully heap-allocated might crash when used with `greenback`.
fix
Thoroughly test C extension modules when used in a `greenback`-enabled context. Such issues often indicate a bug in the extension module itself, which `greenback` merely exposes.
affects: All versions
gotchaCalling `greenback.await_()` inside Python finalizers (`__del__` methods), signal handlers, or weakref callbacks is explicitly unsupported and can lead to unexpected behavior or crashes.
fix
Avoid using `greenback.await_()` in these specific contexts. Refactor your code to perform async operations outside of finalizers, signal handlers, or weakref callbacks.
affects: All versions
gotchaSetting up a `greenback` portal (e.g., via `await greenback.ensure_portal()`) incurs a minor performance overhead for the task it's enabled on, as each task step passes through `greenback`.
fix
Use `greenback.with_portal_run()` or `greenback.with_portal_run_sync()` to explicitly scope the portal's lifetime to only the necessary portion of a task, minimizing performance impact.
affects: All versions
gotchaThe `greenback.with_portal_run_tree()` and other portal propagation functions designed for child tasks only work with the `Trio` event loop, not with `asyncio`, due to `asyncio`'s different task model and lack of necessary instrumentation features.
fix
When using `asyncio`, you must explicitly call `await greenback.ensure_portal()` in each task that intends to use `greenback.await_()`. Do not rely on automatic portal propagation for `asyncio`.
affects: All versions
gotchaCalling `greenback`'s asynchronous functions (e.g., `with_portal_run_sync`, `ensure_portal`) without `await`ing them will result in a `RuntimeWarning` and the function will not execute as intended, instead returning an unawaited coroutine object.
fix
Always `await` `greenback`'s asynchronous functions to ensure they execute correctly and yield their intended results.
affects: All versions
gotchaCalling coroutine functions such as `greenback.with_portal_run_sync()` without `await`ing them will result in a `RuntimeWarning: coroutine was never awaited` and the coroutine object being returned instead of its intended result.
fix
Always `await` `greenback`'s coroutine functions, such as `greenback.with_portal_run_sync()`, when you intend to execute them and obtain their result. For example, use `await greenback.with_portal_run_sync(...)`.
affects: All versions
Errors
Common errors & fixes
RuntimeError: no running event loop
Greenback requires an active asyncio or Trio event loop to re-enter asynchronous code from a synchronous context, and this error occurs when an attempt is made to use greenback.await_() or similar functions without a loop being currently active in the thread.
fix
Ensure your synchronous code using greenback.await_() is called from within an active asyncio task after a portal has been set up, typically by wrapping the entry point in `asyncio.run()` or ensuring `await greenback.ensure_portal()` has been called in the async task.
TypeError: object NoneType can't be used in 'await' expression
This error can occur when `greenback.await_()` is called with an expression that does not return an awaitable object (e.g., `None` instead of a coroutine or future), often due to a misconfigured or improperly called asynchronous function.
fix
Verify that the argument passed to `greenback.await_()` is indeed an awaitable (e.g., the result of calling an `async` function, like `asyncio.sleep(0)` instead of `asyncio.sleep`).
ModuleNotFoundError: No module named 'greenback'
This error indicates that the 'greenback' package is not installed in the Python environment being used, or the Python environment is not correctly configured.
fix
Install the greenback library using pip: `pip install greenback` or ensure your virtual environment is activated and greenback is installed within it.
Upgrade
Version history
1.3.0latest on PyPI · released Dec 23, 2025
Audit
Dependencies
greenletrequiredCore dependency for coroutine switching. Greenback is built on top of it.
Agent activity
26 hits · last 30 days
node
22
OpenAI (training)
2
Resources