Arkitekt Gateway
A Python library for managing a Tailscale-based sidecar proxy. Arkitekt Gateway bundles a Go binary that handles secure networking via Tailscale, with full Python control over the process lifecycle, signal handling, and log streaming.
Features
- 🚀 Multi-platform support - Pre-built binaries for Linux, macOS, and Windows (x86_64 and ARM64)
- 🔄 Async-first API - Full asyncio support with context managers
- 📡 Signal handling - Send SIGINT, SIGTERM, or any signal to the sidecar
- 📝 Log streaming - Async iterator and callback-based log access
- 🖥️ CLI included - Typer-based command-line interface
- 🔒 Lifecycle management - Python controls when the sidecar starts and stops
Installation
pip install arkitekt-gateway
Or with uv:
uv add arkitekt-gateway
Quick Start
Command Line
# Run the sidecar proxy
arkitekt-gateway run \
--authkey tskey-auth-xxxxx \
--coordserver https://your-coordination-server.com \
--hostname my-proxy \
--port 8080
# Check binary info
arkitekt-gateway info
Environment variables are also supported:
export TS_AUTHKEY="tskey-auth-xxxxx"
export TS_COORDSERVER="https://your-coordination-server.com"
arkitekt-gateway run
Python API
Basic Usage
import asyncio
from arkitekt_gateway import Sidecar, SidecarConfig
async def main():
config = SidecarConfig(
authkey="tskey-auth-xxxxx",
coordserver="https://your-coordination-server.com",
hostname="my-proxy",
port="8080",
)
async with Sidecar(config) as sidecar:
# Wait for the proxy to be ready
proxy_url = await sidecar.wait_ready()
print(f"Proxy ready at: {proxy_url}")
# Get status and peer info
status = await sidecar.get_status()
print(f"Connected peers: {len(status.peers)}")
# Keep running...
await asyncio.sleep(60)
# Sidecar is automatically stopped when exiting the context
asyncio.run(main())
Streaming Logs
async def main():
config = SidecarConfig(
authkey="tskey-auth-xxxxx",
coordserver="https://your-coordination-server.com",
)
async with Sidecar(config) as sidecar:
async for log in sidecar.logs():
print(f"[{log.stream}] {log.line}")
asyncio.run(main())
Using Log Callbacks
from arkitekt_gateway import Sidecar, SidecarConfig, LogLine
async def log_handler(log: LogLine):
if "error" in log.line.lower():
print(f"ERROR: {log.line}")
async def main():
config = SidecarConfig(
authkey="tskey-auth-xxxxx",
coordserver="https://your-coordination-server.com",
)
sidecar = Sidecar(config)
sidecar.on_log(log_handler)
await sidecar.start()
try:
await sidecar.wait()
finally:
if sidecar.is_running:
await sidecar.stop()
asyncio.run(main())
Sending Signals
import signal
async def main():
config = SidecarConfig(
authkey="tskey-auth-xxxxx",
coordserver="https://your-coordination-server.com",
)
async with Sidecar(config) as sidecar:
# Do some work...
await asyncio.sleep(5)
# Send interrupt signal
await sidecar.interrupt()
# Or send any signal
await sidecar.send_signal(signal.SIGTERM)
asyncio.run(main())
API Reference
SidecarConfig
Configuration dataclass for the sidecar process.
| Parameter | Type | Default | Description |
|---|---|---|---|
authkey |
str |
required | Tailscale authentication key |
coordserver |
str |
required | Coordination server URL |
hostname |
str |
"ts-proxy" |
Hostname in the Tailnet |
port |
str |
"8080" |
Port to listen on |
statedir |
str |
"" |
State directory for Tailscale data |
mode |
ProxyMode |
ProxyMode.HTTP |
Proxy mode (HTTP or SOCKS5) |
statusport |
str |
"9090" |
Port for the status API |
verbose |
bool |
False |
Enable verbose logging |
Sidecar
Async wrapper for the Go sidecar binary.
Properties
| Property | Type | Description |
|---|---|---|
is_running |
bool |
Whether the sidecar process is running |
pid |
int | None |
Process ID of the sidecar |
exit_code |
int | None |
Exit code if the process has terminated |
Methods
| Method | Description |
|---|---|
await start() |
Start the sidecar process |
await stop(timeout=5.0) |
Stop the sidecar gracefully (SIGTERM, then SIGKILL) |
await wait() |
Wait for the sidecar to exit |
await wait_ready(timeout=30.0) |
Wait for the sidecar to emit READY signal, returns proxy URL |
await wait_for_signal(signal, timeout) |
Wait for a specific IPC signal |
await get_status() |
Get status from the status API (peers, connection info) |
await health_check() |
Check if the status API is healthy |
await interrupt() |
Send SIGINT to the sidecar |
await send_signal(sig) |
Send any signal to the sidecar |
async for log in logs() |
Async iterator for log lines |
on_log(callback) |
Register an async callback for log lines |
LogLine
Represents a log line from the sidecar.
| Field | Type | Description |
|---|---|---|
stream |
str |
Either "stdout" or "stderr" |
line |
str |
The log message |
event |
SidecarEvent | None |
Parsed IPC signal if present |
SidecarSignal
IPC signals emitted by the sidecar.
| Signal | Description |
|---|---|
STARTING |
Sidecar is initializing |
CONNECTING |
Connecting to Tailnet |
CONNECTED |
Successfully connected (includes IPs) |
LISTENING |
Proxy is listening |
READY |
Fully ready to accept connections |
ERROR |
An error occurred |
SHUTDOWN |
Graceful shutdown |
AUTH_REQUIRED |
Authentication required |
SidecarStatus
Status information from the status API.
| Field | Type | Description |
|---|---|---|
self_info |
SelfInfo |
Information about this node |
peers |
list[PeerInfo] |
List of peers in the Tailnet |
backend_state |
str |
Backend state (e.g., "Running") |
Development
Local Setup
# Clone the repository
git clone https://github.com/jhnnsrs/arkitekt-gateway.git
cd arkitekt-gateway
# Install dependencies
uv sync --all-extras --dev
# Download the sidecar binary for local development
python dev.py
# Run tests
uv run pytest tests -v
Building
The package uses hatchling with a custom build hook that downloads the appropriate platform-specific binary during wheel building.
uv build
License
License
MIT
Metadata
Release files for arkitekt-gateway 1.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| arkitekt_gateway-1.2.2.tar.gz | 33.7 MB | Without provenance | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| arkitekt_gateway-1.2.2-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| arkitekt_gateway-1.2.2-py3-none-manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| arkitekt_gateway-1.2.2-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
Total release size: 83.2 MB
Release files / arkitekt_gateway-1.2.2.tar.gz
| Download URL | arkitekt_gateway-1.2.2.tar.gz |
|---|---|
| Size | 33.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8db33c4c89e854e1b7ee346ac43960ecb01aa2fc7b290fedb447df0a32373ea5
|
|
BLAKE2b-256 checksum How to use checksums |
ddcea69b908cda2938297f637c15efdc802840c021f14317b8301ebc5987f740
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / arkitekt_gateway-1.2.2-py3-none-win_amd64.whl
| Download URL | arkitekt_gateway-1.2.2-py3-none-win_amd64.whl |
|---|---|
| Size | 16.7 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c750991b93c330a3ccf43daad8505c627510cfa336d4a15b28472ae32c44021e
|
|
BLAKE2b-256 checksum How to use checksums |
0ca609c50ace151ab8a49ade72353180dfc9466f2ecef121434ec9b45467620f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / arkitekt_gateway-1.2.2-py3-none-manylinux2014_x86_64.whl
| Download URL | arkitekt_gateway-1.2.2-py3-none-manylinux2014_x86_64.whl |
|---|---|
| Size | 16.9 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
45a5f40aa91c7fee50535e19b4c25e43b672bcdaf56cffede2260483e0f4db95
|
|
BLAKE2b-256 checksum How to use checksums |
68fe5bc0ab58fedd685d2eb057235a80a226d6382f392a1d5ccf2022d69a9df6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / arkitekt_gateway-1.2.2-py3-none-macosx_11_0_arm64.whl
| Download URL | arkitekt_gateway-1.2.2-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 16.0 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f6066e890012d121a90b42c16619d3e3f3d453f4d5792df569b1fa649f1f76c1
|
|
BLAKE2b-256 checksum How to use checksums |
6b59c386ef2aa65b03c2224fcfa9b5c8451198eca24d8375bd39cfc4f2381c27
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for arkitekt-gateway 1.2.2
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.