A Traefik-like provider framework for dynamic proxy configuration in Python.
This project is not a full reverse proxy by itself. It is a provider engine that watches multiple sources (files, HTTP APIs, Docker, Consul, etc.) and produces a normalized routing configuration.
- Build a Python Traefik-like router
- Build an edge gateway that reloads routes dynamically
- Implement Kubernetes/Docker providers in Python
- Provide unified routing config for multiple systems
- Provider plugin interface (
ProviderBase) withstart()/stop()/current_config() - Provider manager — loads providers, merges configs, tracks background tasks
- File provider — watches YAML files for live changes via
watchfiles - HTTP provider — polls JSON routes from a remote endpoint with connection pooling
- Event bus — async pub/sub for config update notifications
- Graceful shutdown — signal handlers (SIGINT/SIGTERM) stop all providers cleanly
- Configurable logging —
--log-levelCLI option (DEBUG, INFO, WARNING, ERROR) - Merge conflict detection — logs warnings when multiple providers define the same router or service
pip install python-proxy-providerproxy-provider run --file examples/routes.ymlThen edit examples/routes.yml and see live reload output.
Combine multiple providers:
proxy-provider run --file examples/routes.yml --http http://localhost:8000/routes --log-level DEBUG ┌─────────────────┐
│ EventBus │
│ (async Queue) │
└──────┬──────────┘
┌────────────────┼────────────────┐
▼ ▼ ▼
FileProvider HttpProvider (future providers)
(watch YAML) (poll JSON) Docker, Consul, K8s
│ │ │
└────────────────┼────────────────┘
▼
ProviderManager
┌──────────┐
│ merge() │
└────┬─────┘
▼
DynamicConfig
(routers + services)
Implement a custom provider by subclassing ProviderBase:
from python_proxy_provider.providers.base import ProviderBase
from python_proxy_provider.models import DynamicConfig
from python_proxy_provider.events import ConfigEvent
class MyProvider(ProviderBase):
name = "my"
async def start(self):
cfg = DynamicConfig(...)
await self.bus.publish(ConfigEvent(provider=self.name, config=cfg))
async def current_config(self) -> DynamicConfig:
return self._config- Docker provider (watch containers)
- Consul provider
- Kubernetes provider
- Plugin discovery via
entry_points - Conflict resolution policies
- Distributed config cache
- Graceful shutdown: Signal handlers (SIGINT/SIGTERM) stop all providers cleanly.
- Connection pooling: Shared
httpx.AsyncClientsingleton (was creating a client per request). - Logging: Replaced
print()with structuredloggingthroughout; added--log-levelCLI option. - Merge conflict detection: Warns when multiple providers define the same router/service key.
- EventBus close:
EventBus.close()prevents publishing after shutdown; subscribe loop exits cleanly. - Task tracking:
ProviderBasetracks background task for proper cancellation viastop(). - Bare except fixes: All
except Exceptionblocks re-raiseasyncio.CancelledError. - Build system: Migrated from
setuptoolstohatchling. Added classifiers, keywords, optional dev/test deps, ruff/pytest config. - Tests: Expanded from 1 test to 20 tests covering models, events, manager, file provider, and HTTP provider.
- Initial release: Provider plugin interface, file provider, HTTP provider, event bus, CLI demo.
MIT