import praisonaiagents spawns no background thread, leaves host environment variables alone, preserves host logging handlers, and never replaces warnings.warn — so it is safe to import inside an existing app or at the parent of a pre-fork server before workers fork.
multiprocessing parent; nothing starts a daemon thread or corrupts the environment before workers fork.
Reference: PraisonAI PR #5219 (fixes #5162) and PR #6135 (fixes #6134). This is the Python companion to JS Import Safety & Runtimes.
What’s safe on import (after PR #5219)
Three import-time side effects that used to corrupt the host process are gone.1
Host environment variables are preserved
praisonaiagents._logging._configure_environment() uses os.environ.setdefault(key, value). A value the host exported before launch (LITELLM_LOG, LITELLM_TELEMETRY, PYDANTIC_WARNINGS_ENABLED, and the rest) is kept — and no longer leaks a different value into subprocesses spawned afterwards.2
The asyncio logger is left alone
"asyncio" was removed from the SDK’s noisy-logger list. Import no longer forces logging.getLogger("asyncio") to CRITICAL, so host asyncio errors (Task exception was never retrieved, scheduling failures) continue to surface.3
No cleanup thread is spawned at import
The See Runtime Resolution → Background cleanup thread.
runtime/resolve.py cleanup daemon starts lazily on the first cache write — inside resolve_runtime under _runtime_cache_lock — not at module import. A bare import praisonaiagents or a touch of runtime.SessionContext spawns nothing, which is exactly the guarantee pre-fork server deployments need.Host logging, warnings, and env on import (PR #6135)
PR #6135 removed the last import-time changes to host process state.1
Root logger is left alone if the host configured it
logging.basicConfig(..., force=True) is gone. If the root logger already has a handler, import leaves the root handler list and level unchanged. See Logging Configuration → When the host has already configured logging.2
Host httpx / openai / pydantic loggers are kept
When the host has configured logging, import no longer clears handlers or
propagate on httpx, httpcore, openai.*, pydantic, or markdown_it loggers.3
warnings.warn is never replaced
warnings.warn and warnings.warn_explicit are no longer monkey-patched. Noisy third-party warnings are silenced with scoped warnings.filterwarnings(...) entries only, so warnings.warn is the same object before and after import.4
Env defaults wait for the LLM layer
LITELLM_*, HTTPX_*, and PYDANTIC_* defaults are applied when praisonaiagents.llm is imported — not on import praisonaiagents. Subprocesses the host spawns before using the LLM path inherit an unchanged environment. Values are still applied with setdefault.tests/unit/test_import_side_effects.py.
Fork-safety guide
Import at the parent, then fork — as long as noresolve_runtime call happens before the fork, no daemon thread is cloned into a child in an undefined state.
- gunicorn (pre-fork)
- multiprocessing.Process
- ProcessPoolExecutor
Before PR #5219 the import-time cleanup thread was cloned into every child at
fork() in an undefined state — a known cause of hangs and duplicate cache eviction under gunicorn pre-fork workers, multiprocessing.Process, and Celery prefork. After PR #5219, importing at the parent is safe as long as no resolve_runtime call happens before fork.Best Practices
Import at the parent, resolve in the child
Import at the parent, resolve in the child
Under a pre-fork server, keep
import praisonaiagents in the master and let the first agent.start() / resolve_runtime happen inside each worker. The lazy cleanup daemon then starts per-worker, never in the master.Configure host logging before or after — both work
Configure host logging before or after — both work
If your app installs root handlers before importing PraisonAI, the SDK leaves them alone. If it imports PraisonAI first, attach your handlers afterwards as usual.
Set env vars before launch to keep them
Set env vars before launch to keep them
Export
LITELLM_LOG, LITELLM_TELEMETRY, and friends in your shell / systemd / Docker before the process starts. setdefault preserves them and never leaks a different value into subprocesses.Re-suppress asyncio yourself if you need it
Re-suppress asyncio yourself if you need it
Import no longer silences the asyncio logger. If you want the old quiet behaviour, call
logging.getLogger("asyncio").setLevel(logging.CRITICAL) in your own code.Related
Import Safety (JS)
JavaScript companion — no dotenv side effects on import
Logging Configuration
Host-configured logging is preserved on import
Runtime Resolution
Lazy cleanup-thread start and fork safety
Thread Safety
Output-singleton locks and concurrent agent guarantees

