Add your description here
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file arkitekt_gateway-1.2.1.tar.gz.
File metadata
- Download URL: arkitekt_gateway-1.2.1.tar.gz
- Upload date:
- Size: 33.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f681211a9141529d886a08c3884cb7dcdce14ba5a5229224671bccde06bba5d5
|
|
| MD5 |
2037fe7a17968e98639cd5efcb63798c
|
|
| BLAKE2b-256 |
7d3254156e3f7225a2a04128f460b28eee6c1c2839db1bfb709a1d555fc485f1
|
File details
Details for the file arkitekt_gateway-1.2.1-py3-none-win_amd64.whl.
File metadata
- Download URL: arkitekt_gateway-1.2.1-py3-none-win_amd64.whl
- Upload date:
- Size: 16.7 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08219e51c034ff0c2eb669a4fb2c10b9d44eaf9bc920eb2baa742469ad2390ed
|
|
| MD5 |
99d954a1217243c00b4a3c1cb1e2df43
|
|
| BLAKE2b-256 |
5f555c789e4b4c581d62fa92abe469e1d2655a7cddbed539314a496e6d1bb4c6
|
File details
Details for the file arkitekt_gateway-1.2.1-py3-none-manylinux2014_x86_64.whl.
File metadata
- Download URL: arkitekt_gateway-1.2.1-py3-none-manylinux2014_x86_64.whl
- Upload date:
- Size: 16.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50b78ec3edb4efe50d2cfeff4173fbaf64653761df96b84700eedb85d6ea71d6
|
|
| MD5 |
8138d598cf37e58db59701b141276cb4
|
|
| BLAKE2b-256 |
47f25ee792cba7cd0babe8c5b77c7352b008adbd0a8410b779f25a252ab73018
|
File details
Details for the file arkitekt_gateway-1.2.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: arkitekt_gateway-1.2.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 16.0 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9886d0722517deeca41385bb9ebba3d718cbeb5d9c9a0a1e448f33056a5bf40
|
|
| MD5 |
14cb8bf2d45e448485fdd2a00c4654f2
|
|
| BLAKE2b-256 |
c5438d8ba4373935a2688cb7e20a1be5702df4d8063c3a02f39e9447f0253220
|