Load environment variables from Argus over local IPC, with .env fallback — similar to python-dotenv, but secrets come from your Argus bucket when the desktop app is running.
v0.2 — returns Argus proxy connection details so you wire any HTTP library yourself.
- Python 3.10+
- Argus desktop signed in (IPC socket active)
- Project
.envwithARGUS_BUCKET_IDandARGUS_BUCKET_TOKEN(not the secret values themselves)
pip install useargusWhen proxy is disabled on the bucket, load_env() injects real secret values into os.environ. Use any HTTP client normally:
import os
import httpx
from useargus import load_env
load_env()
with httpx.Client() as client:
client.get("https://api.example.com", headers={"Authorization": f"Bearer {os.environ['API_KEY']}"})When proxy is enabled, proxy mappings receive argus-proxy-* placeholders — not real keys. Call load_env(), then wire your HTTP client with SDK helpers:
import httpx
from useargus import load_env, argus_httpx_config
load_env()
client = httpx.Client(**argus_httpx_config(), timeout=60)See docs/usage for per-library guides (requests, httpx, aiohttp, Anthropic SDK, LangChain, …).
Call load_env() before other modules read os.environ:
from useargus import load_env
load_env()When the bucket has Argus Proxy enabled, wire your HTTP client after load_env() using the proxy helpers (see docs/usage).
# Before
from dotenv import load_dotenv
load_dotenv()
# After
from useargus import load_env
load_env()ARGUS_BUCKET_ID=550e8400-e29b-41d4-a716-446655440000
ARGUS_BUCKET_TOKEN=tok_...
# Optional local overrides (override bucket values for the same key)
# DATABASE_URL=postgresql://localhost/devCopy .env.example to get started.
- Parse
.env(no side effects yet). - If
ARGUS_BUCKET_IDandARGUS_BUCKET_TOKENare set (OS env or.env), connect to Argus over IPC and fetch mapped secrets. - Apply bucket values to
os.environ. - Apply
.env— duplicate keys use the.envvalue (overrides bucket). - If bucket credentials are missing, load
.envonly (standard dotenv behavior).
| State | IPC |
|---|---|
| Signed in, idle app lock | Works — approval popup may appear for new clients |
| Signed out | Returns locked — use fallback_on_locked=True to load .env only |
Idle app lock does not block IPC. Only sign-out returns IPC locked.
The first time a process connects, Argus shows an access approval dialog (up to ~120s). Later requests use the grant TTL from bucket settings.
from useargus import load_env
result = load_env(
path=".env", # default: .env in cwd
override=False, # dotenv-only mode: don't override existing OS env
timeout_ms=130_000, # IPC timeout
fallback_on_locked=False, # if signed out, load .env instead of raising
)
# result.source == "bucket" | "dotenv"
# result.keys — names set (never values)After load_env(), use per-library config helpers and builders where needed:
from useargus import argus_httpx_config, create_argus_requests_proxy_adapter
client = httpx.Client(**argus_httpx_config(), timeout=60)| Kind | Functions |
|---|---|
| Config | argus_requests_config(), argus_httpx_config(), argus_aiohttp_config(), argus_urllib_config() |
| Builders | create_argus_requests_proxy_adapter() / create_argus_requests_proxy_adapter_class() |
Per-library copy-paste examples: docs/usage/
Low-level IPC fields remain on require_proxy_config() / get_proxy_config().
Lower-level IPC call if you only need the bucket map:
import os
from useargus import fetch_bucket_env
env = fetch_bucket_env(
bucket_id=os.environ["ARGUS_BUCKET_ID"],
client_token=os.environ["ARGUS_BUCKET_TOKEN"],
)All errors extend ArgusError with .code and optional .request_id. Catch specific types for programmatic handling:
| Error | Argus IPC | When |
|---|---|---|
ArgusConnectionError |
— | Socket/pipe missing, timeout, connection closed |
ArgusLockedError |
status: locked |
Argus signed out |
ArgusApprovalDeniedError |
denied + APPROVAL_DENIED |
User rejected client access |
ArgusApprovalTimeoutError |
denied + APPROVAL_TIMEOUT |
Approval dialog timed out (120s) |
ArgusBucketNotFoundError |
BUCKET_NOT_FOUND |
Wrong ARGUS_BUCKET_ID |
ArgusInvalidTokenError |
INVALID_TOKEN |
Wrong or rotated ARGUS_BUCKET_TOKEN |
ArgusBucketInactiveError |
BUCKET_INACTIVE |
Bucket paused in Argus |
ArgusPeerResolveError |
PEER_RESOLVE |
Argus could not identify this process |
ArgusProxyError |
PROXY_ERROR |
Proxy enabled but misconfigured |
ArgusInvalidRequestError |
INVALID_REQUEST |
Malformed IPC request |
ArgusInvalidResponseError |
— | Unexpected Argus response |
ArgusConfigureError |
— | Proxy unavailable or disabled for bucket |
ArgusError |
other error codes |
DB_ERROR, INTERNAL_ERROR, etc. |
Call load_env() first in every example. Full guides: docs/usage/
import requests
from useargus import load_env, argus_requests_config, create_argus_requests_proxy_adapter
load_env()
cfg = argus_requests_config()
session = requests.Session()
session.proxies.update(cfg["proxies"])
session.verify = cfg["verify"]
session.trust_env = cfg["trust_env"]
adapter = create_argus_requests_proxy_adapter()
session.mount("https://", adapter)
session.mount("http://", adapter)import httpx
from useargus import load_env, argus_httpx_config
load_env()
client = httpx.Client(**argus_httpx_config(), timeout=30)See docs/usage/ for aiohttp, urllib, Anthropic SDK, and LangChain.
useargus/env/load.py—load_envuseargus/proxy/config.py—get_proxy_config,require_proxy_config,proxy_urluseargus/proxy/wiring.py— per-library proxy config and buildersuseargus/ipc/client.py— IPC client,ProxyConfiguseargus/errors.py— error types
python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"
ruff check .
mypy useargus
pytest
python -m buildPublishing is manual via GitHub Actions (adding PYPI_TOKEN alone does not publish).
- Add repository secret
PYPI_TOKEN(PyPI API token with publish rights). - Go to Actions → Publish to PyPI → Run workflow.
- Enter the version (e.g.
0.2.0orv0.2.0).
The workflow runs CI, sets pyproject.toml version, publishes to PyPI, tags v<version>, and creates a GitHub release.
MIT