| .onedev-buildspec.yml | Loading last commit info... | |
| tests | ||
| .gitignore | ||
| README.md | ||
| cfcontext.py | ||
| setup.py |
cfcontext
cfcontext is a lightweight library for managing shared contexts within a Python application. It allows you to create, replace, and handle dynamic contextual objects that are inherited across the call stack frames, ensuring consistency throughout nested function calls and asynchronous tasks.
Installation
pip install cfcontext
Features
- Shared Context Management: A global context can be created and accessed anywhere in your application.
- Context Inheritance: Contexts are inherited across the call stack, so child functions and tasks can automatically access the parent context.
- Unlinked Contexts: Create separate contexts to avoid conflicts or temporarily replace the current context.
- Asynchronous Support: Manage context within async tasks, ensuring consistent shared data.
Usage
1. Creating and Using a Context
The context can be initialized with specific attributes:
from cfcontext import Context
ctx = Context(abc=123)
print(ctx.abc) # 123
Once created, the context can be accessed anywhere in your code, even in nested functions:
def some_function():
print(Context().abc) # 123
some_function()
2. Creating a Separate Context
You can create a distinct, unlinked context using the create() static method:
ctx1 = Context(oi='io')
ctx2 = Context.create()
print(ctx1.oi) # 'io'
print(ctx2.oi) # None
3. Replacing the Current Context
To replace the current context with another one:
ctx = Context.create()
ctx.abc = 123456
replace_context(ctx)
print(Context().abc) # 123456
4. Using with context manager syntax (with)
You can use a context inside a with bloc :
Context(abc = 123)
with Context.create(abc=456):
print("Inside `with` bloc: ", Context().abc) # Inside `with` bloc: 456
print("Outside `with` bloc: ", Context().abc) # Outside `with` bloc: 123
5. Using with Asynchronous Tasks
cfcontext manages context within async tasks, inheriting context values even in concurrent environments. Contextual data is shared and can be modified across different tasks:
import asyncio
from cfcontext import Context
async def async_task(a, b, n):
Context(n=n)
assert Context().a == a
assert Context().b == b
Context().b = 'Ok!'
async def async_main(a):
Context(a=2, b='Ok')
await async_task(2, 'Ok', 0)
t1 = asyncio.create_task(async_task(a, None, 1))
t2 = asyncio.create_task(async_task(2, 'Ok', 2), context=Context())
await asyncio.sleep(1)
Context(a=1)
asyncio.run(async_main(1))
print(Context().a) # 1
Tests
The library is tested with scenarios covering linked, unlinked, and asynchronous context management. To run the tests:
pytest