LangHook Python SDK and Server - Make any event from anywhere instantly understandable and actionable by anyone
Project description
LangHook
Make any event from anywhere instantly understandable and actionable by anyone.
LangHook transforms chaotic webhook payloads into standardized CloudEvents with a canonical format that both humans and machines can understand. Create smart event routing with natural language - no JSON wrangling required.
🎭 Demo
Visit our interactive demo to see LangHook in action: https://demo.langhook.dev (placeholder URL)
Try sending sample webhooks and see real-time event transformation, schema discovery, and natural language subscriptions.
⚡ Quickstart: Using LangHook SDK
Install the LangHook Python SDK to integrate event processing into your applications:
pip install langhook
For SDK-specific dependencies, see the SDK documentation.
Python SDK Usage
import asyncio
from sdk.python import LangHookClient, LangHookClientConfig, AuthConfig
async def main():
# Configure client to connect to your LangHook server
config = LangHookClientConfig(
endpoint="http://localhost:8000",
auth=AuthConfig(type="token", value="your-auth-token") # Optional
)
# Use client as context manager
async with LangHookClient(config) as client:
# Create a subscription using natural language
subscription = await client.create_subscription(
"Notify me when any pull request is merged"
)
# Set up event listener
def event_handler(event):
print(f"Got event: {event.publisher}/{event.action}")
# Start listening for events
stop_listening = client.listen(
str(subscription.id),
event_handler,
{"intervalSeconds": 15}
)
# ... do other work ...
# Stop listening and clean up
stop_listening()
await client.delete_subscription(str(subscription.id))
asyncio.run(main())
TypeScript/JavaScript SDK
npm install langhook-sdk
import { LangHookClient, LangHookClientConfig } from 'langhook-sdk';
async function main() {
// Configure client to connect to your LangHook server
const config: LangHookClientConfig = {
endpoint: 'http://localhost:8000',
auth: {
type: 'token',
value: 'your-auth-token' // Optional
}
};
// Create client
const client = new LangHookClient(config);
// Initialize connection
await client.init();
// Create a subscription using natural language
const subscription = await client.createSubscription(
'Notify me when any pull request is merged'
);
// Set up event listener
const eventHandler = (event) => {
console.log(`Got event: ${event.publisher}/${event.action}`);
};
// Start listening for events
const stopListening = client.listen(
subscription.id.toString(),
eventHandler,
{ intervalSeconds: 15 }
);
// ... do other work ...
// Stop listening and clean up
stopListening();
await client.deleteSubscription(subscription.id.toString());
}
main().catch(console.error);
🚀 Running LangHook Server
Option 1: Using Docker Compose (Recommended)
The easiest way to run LangHook with all dependencies:
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/touchaponk/langhook/main/docker-compose.yml
# Start PostgreSQL + NATS + Redis + LangHook
docker-compose --profile docker up -d
# Check status
docker-compose ps
The server will be available at http://localhost:8000.
Option 2: Running LangHook Server Only
If you already have PostgreSQL, NATS, and Redis running:
# Install the server package
pip install langhook[server]
# Configure environment (copy and edit .env.example)
curl -O https://raw.githubusercontent.com/touchaponk/langhook/main/.env.example
cp .env.example .env
# Edit .env with your database and message broker URLs
# Start the server
langhook
Required services:
- NATS JetStream (message broker) -
nats://localhost:4222 - Redis (rate limiting) -
redis://localhost:6379 - PostgreSQL (optional, for subscriptions) -
postgresql://user:pass@localhost:5432/langhook
Option 3: Running from Source Code
For development or customization:
# Clone the repository
git clone https://github.com/touchaponk/langhook.git
cd langhook
# Start dependencies only
docker-compose up -d nats redis postgres
# Install in development mode
pip install -e .
# Copy environment configuration
cp .env.example .env
# Edit .env as needed
# Run the server
langhook
Using LangHook CLI to Start the Server
The langhook command starts the full server with all services:
# Basic usage
langhook
# View help
langhook --help
# With custom configuration
DEBUG=true LOG_LEVEL=debug langhook
Other CLI tools:
langhook-streams- Manage NATS JetStream streamslanghook-dlq-show- View dead letter queue messages
🎯 Try it Out
Once your server is running, visit:
http://localhost:8000/console- Interactive web console to send test webhooks and manage subscriptionshttp://localhost:8000/docs- API documentationhttp://localhost:8000/schema- View discovered event schemas
Send your first webhook:
curl -X POST http://localhost:8000/ingest/github \
-H "Content-Type: application/json" \
-d '{"action": "opened", "pull_request": {"number": 123}}'
🎯 Core Features
Universal Webhook Ingestion
- Single endpoint accepts webhooks from any source (GitHub, Stripe, Slack, etc.)
- HMAC signature verification ensures payload authenticity
- Rate limiting protects against abuse
- Dead letter queue for error handling
Intelligent Event Transformation
- JSONata mapping engine converts raw payloads to canonical format
- LLM-powered fallback generates mappings for unknown events
- Enhanced fingerprinting distinguishes events with same structure but different actions
- CloudEvents 1.0 compliance for interoperability
- Schema validation ensures data quality
Natural Language Subscriptions
- Plain English queries like "Notify me when PR 1374 is approved"
- LLM-generated NATS filter patterns automatically translate intent to code
- Multiple delivery channels (Slack, email, webhooks)
Dynamic Schema Registry
- Automatic schema discovery from all processed events
- Real-time schema API exposes available event types
- Schema management with deletion capabilities
- LLM grounding ensures subscriptions use real schemas
📊 Canonical Event Format
LangHook transforms any webhook into this standardized format:
{
"publisher": "github",
"resource": {
"type": "pull_request",
"id": 1374
},
"action": "updated",
"timestamp": "2025-06-03T15:45:02Z",
"payload": { /* original webhook payload */ }
}
⚙️ Configuration
LangHook uses environment variables for configuration. Copy .env.example to .env and customize:
Essential Settings
# Message broker (required)
NATS_URL=nats://localhost:4222
# Database (optional, for subscriptions)
POSTGRES_DSN=postgresql://user:pass@localhost:5432/langhook
# Cache and rate limiting (required)
REDIS_URL=redis://localhost:6379
AI Features (Required)
# Enable LLM-powered mapping suggestions
OPENAI_API_KEY=sk-your-openai-key
# Or use local Ollama
OLLAMA_BASE_URL=http://localhost:11434
See .env.example for all available options.
🛠 Usage Examples
1. Query Available Event Schemas
curl http://localhost:8000/schema/
2. Generate a Mapping Suggestion
curl -X POST http://localhost:8000/map/suggest-map \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"payload": {
"action": "opened",
"pull_request": {"number": 1374}
}
}'
3. Create a Natural Language Subscription
Visit http://localhost:8000/console and try:
"Notify me when any pull request is merged"
🏗 Architecture
graph TD
A[Webhooks] --> B[svc-ingest]
B --> C[NATS: raw.*]
C --> D[svc-map]
D --> E[NATS: langhook.events.*]
D --> SR[Schema Registry DB]
E --> F[Rule Engine]
F --> G[Channels]
H[JSONata Mappings] --> D
I[LLM Service] -.-> D
SR --> J[/schema API]
SR --> K[LLM Prompt Augmentation]
K --> L[Natural Language Subscriptions]
Services
- svc-ingest: HTTP webhook receiver with signature verification
- svc-map: Event transformation engine with LLM fallback and schema collection
- Schema Registry: Dynamic database tracking all event types
- Rule Engine: Natural language subscription matching
🧪 Testing
Unit Tests
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ --ignore=tests/e2e/
End-to-End Tests
# Complete E2E test suite (requires Docker)
./scripts/run-e2e-tests.sh
📚 Documentation
- Agent Documentation - For AI agents and contributors
- API Reference - Interactive OpenAPI docs
- Examples - Sample payloads and mappings
- Contributing Guide - Development setup
🤝 Contributing
We welcome contributions! Install development dependencies:
pip install -e ".[dev]"
# Run linting
ruff check langhook/
ruff format langhook/
# Run type checking
mypy langhook/
🌟 Why LangHook?
| Traditional Integration | LangHook |
|---|---|
| Write custom parsers for each webhook | Single canonical format |
| Maintain brittle glue code | JSONata mappings + LLM fallback |
| Technical expertise required | Natural language subscriptions |
| Vendor lock-in with iPaaS | Open source, self-hostable |
| Complex debugging | End-to-end observability |
📄 License
LangHook is licensed under the MIT License.
Ready to simplify your event integrations? Get started with the Quickstart or try the interactive demo.
For questions or support, visit our GitHub Issues.
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 Distribution
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 langhook-0.3.4.tar.gz.
File metadata
- Download URL: langhook-0.3.4.tar.gz
- Upload date:
- Size: 3.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b743978cb2a8e666d76dc526468e7efa5ba86c32d114191a5ac3581bc24f88db
|
|
| MD5 |
4d5a1160564e0c8ea7ab04fb66d8e315
|
|
| BLAKE2b-256 |
931b9ac979e0a744abb117909b43660c77871bc195c8001d4351c8aacca3c85d
|
File details
Details for the file langhook-0.3.4-py3-none-any.whl.
File metadata
- Download URL: langhook-0.3.4-py3-none-any.whl
- Upload date:
- Size: 89.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8497e9a9d721635a670e6c4b7f1c060ff48a6ad90ae2fce2c008c09316ff3ad7
|
|
| MD5 |
925f7452733490fa4508188252c2583f
|
|
| BLAKE2b-256 |
d7799b8f75ea9149cdfd8a31b58d074d671acf55679ebf0bb4dc0ea052a2c5d5
|