Skip to main content

proxyvars
skeleton Supported Python versions Package version

Tests Coverage Documentation Status Lifted?

Callback-based object proxies in Python.

Example Usage

The library might have many use cases.

Asynchronous Apps

Imagine a web app that processes many requests asynchronously. A fun design we can learn from contextvars is that we can run request handlers in proper contexts with all the request-related data held in context variables instead of requiring endpoint functions to accept parameters like request. This approach heavily used in Flask, where one can access request data using a global proxy flask.request. With bare contextvars, we could achieve this:

from contextvars import ContextVar
from proxyvars import proxy
from asgi_framework import App  # some random ASGI web framework

class Request:
    args: dict[str, str]
    headers: dict[str, str]
    data: str
    # etc...

request_context: ContextVar[Request] = ContextVar("request_context")
app = App()

# the app will manage to set the appropriate Request object in the context
# before actually triggering the index() coroutine
@app.get("/")
async def echo():
    request: Request = request_context.get()
    # do something with request...
    return request.data

With proxyvars, we can skip the assignment and simply create a dynamic-lookup proxy:

# below the Request class
request = lookup_proxy(request_context)

@app.get("/")
async def echo():
    return request.data  # request delegated attribute access to request_context.get()

Flexible "Global" State

One of the crucial caveats of using global variables is reduction of modularity and flexibility. Typically we want to test our code in an easily-parametrizable environment, which becomes unobvious in case of some global state that other parts of your program might depend on. Problems arise in multi-threaded or asynchronous applications, where some global data typically should be thread- or task-local. Python offers threading.local and contextvars (respectively) for achieving these goals.

But sometimes global state is just the most convenient solution. Imagine running an app with a core App class with a config read from a file. We don't want to populate the configuration into attributes of the App instance and rather store configuration data properly in a class named Config.

We can store Config instance as an attribute config of our main class App that manages the whole application life cycle and then, everytime we need a config value, we can request the app's config attribute. With a lot of codebase, you can find this solution more and more tedious.

Creating a global app_config variable, not bound to an app, is not a good direction either though. What if you want to 2 apps with distinct configurations? Will you modify the global app_config to the proper Config object everytime?

Get That "Global" Experience With Proxyvars!

Simply create a global context variable.

app_config_var: ContextVar[Config] = ContextVar("app_config_var")
app_config: Config = lookup_proxy(app_config_var)

Now just run your tests in properly set-up contexts with app_config_var holding objects local to every thread, task or just a custom copy of the current context.

Mutable Immutables

Ever dreamt of thread-safe, mutable integers in Python? I don't think anybody did, but it's possible with lookup proxies & beloved contextvars just in case.

from contextvars import ContextVar
from proxyvars import proxy

my_iq_var = ContextVar("my_iq_var", 100)
my_iq = lookup_proxy(my_iq_var)

print(my_iq)  # 100

# Users of proxyvars typically have 200 IQ. Patch our current variable.
my_iq_var.set(200)

print(my_iq)  # 200

# Alright, let's be real. Assuming we have 200 IQ is a non-200 IQ behavior.
# Subtract 60 IQ points. We are entitled to 140 as programmers.
my_iq -= 60

print(my_iq_var.get())  # 140
print(my_iq)  # 60

This way, we got a mutable immutable. Or, more correctly, we got a proxy object that can change its state which is represented by an immutable object.

Have fun with proxyvars!

For Enterprise

Tidelift Available as part of the Tidelift Subscription.
This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. Learn more here.

To report a security vulnerability, please use the Tidelift security contact.
Tidelift will coordinate the fix and disclosure.

Installation

You might simply install it with pip:

pip install proxyvars

If you use Poetry, then you might want to run:

poetry add proxyvars

For Contributors

Poetry Ruff Pre-commit

  1. Fork the proxyvars repository on GitHub.

  2. Install Poetry.
    Poetry is an amazing tool for managing dependencies & virtual environments, building packages and publishing them. You might use pipx to install it globally (recommended):

    pipx install poetry
    

    If you encounter any problems, refer to the official documentation for the most up-to-date installation instructions.

    Be sure to have Python 3.8 installed—if you use pyenv, simply run:

    pyenv install 3.8
    
  3. Clone your fork locally and install dependencies.

    git clone https://github.com/your-username/proxyvars path/to/proxyvars
    cd path/to/proxyvars
    poetry env use $(cat .python-version)
    poetry install
    

    Next up, simply activate the virtual environment and install pre-commit hooks:

    poetry shell
    pre-commit install
    

For more information on how to contribute, check out CONTRIBUTING.md.
Always happy to accept contributions! ❤️

Legal Info

© Copyright by Bartosz Sławecki (@bswck).
This software is licensed under the terms of MIT License.

Metadata

Release files for proxyvars 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for proxyvars 0.10.0
File Size Uploaded Provenance Actions
proxyvars-0.10.0.tar.gz 14.1 kB Without provenance Details for proxyvars-0.10.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for proxyvars 0.10.0
File Interpreter ABI Platform Actions
proxyvars-0.10.0-py3-none-any.whl Python 3 none any Details for proxyvars-0.10.0-py3-none-any.whl

Total release size: 24.4 kB

Release files / proxyvars-0.10.0.tar.gz

Download URL proxyvars-0.10.0.tar.gz
Size 14.1 kB
Tags Source
SHA-256 checksum
How to use checksums
19a0edf3513e4f0d43262346063ff75b301ff828f659ffba5021eaa1903f3f96
BLAKE2b-256 checksum
How to use checksums
eb50ec329bf276e94465f72ef522e63f7d310a6b61649c244147254bcc1f0d97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.0.0 CPython/3.12.3

Release files / proxyvars-0.10.0-py3-none-any.whl

Download URL proxyvars-0.10.0-py3-none-any.whl
Size 10.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1224945422901b6b271bdae1b50a5d58e16baa1eb90017c9b79b5ba2aff17282
BLAKE2b-256 checksum
How to use checksums
96bd792db932e09bd2ec12562ae809571f7109c44522aab2c77f5ca31b59424f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.0.0 CPython/3.12.3

Security for proxyvars 0.10.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page