# sp-obs
SP-OBS is Spinal's cost tracking library built on top of OpenTelemetry. It works by automatically instrumenting HTTP libraries (httpx, requests) and
attaching a processor to existing OpenTelemetry setups. This dual approach allows it to integrate seamlessly with existing observability frameworks while
selectively forwarding AI/LLM operations and billing events to Spinal's platform.
## Features
- Seamlessly integrates with existing OpenTelemetry setups
- Works with Logfire, vanilla OpenTelemetry, or any OTEL-compatible framework
- Automatic instrumentation of httpx and requests libraries
- Adds user and workflow context to spans for better tracking
- Selective span processing - only sends relevant AI/billing spans
- Built-in data scrubbing for sensitive information
## Installation
```bash
pip install sp-obs
```
## Quick Start
```python
import sp_obs
# Configure with your API key
sp_obs.configure(api_key="your-api-key")
# That's it! AI calls are now tracked automatically
```
## Adding Context
Use tags to add business context to your AI operations:
```python
# Context manager (recommended)
with sp_obs.tag(user_id="user-123", workflow_id="chat-session"):
# All AI calls here will be tagged
response = openai_client.chat.completions.create(...)
# Or set tags globally
sp_obs.tag(user_id="user-123", workflow_id="chat-session")
```
## Supported Providers
- **OpenAI** - GPT-4, GPT-3.5, DALL-E, Whisper, Embeddings
- **Anthropic** - Claude 3 (Opus, Sonnet, Haiku), Claude 2
- **ElevenLabs** - Text-to-speech
- **Perplexity** - Online LLMs with search
- **Deepgram** - Speech-to-text
- **SerpAPI** - Search results
- **ScrapingBee** - Web scraping
- **Firecrawl** - Web crawling
## Billing Events
Track custom billing events:
```python
sp_obs.add_billing_event(
success=True,
user_id="user-123",
amount=99.99,
currency="USD"
)
```
## Environment Variables
- `SPINAL_API_KEY` - Your API key
- `SPINAL_TRACING_ENDPOINT` - Custom endpoint (default: https://cloud.withspinal.com)
## Advanced Configuration
### Batch Processing
Control how spans are batched and exported:
```python
sp_obs.configure(
api_key="your-api-key",
max_queue_size=2048, # Max buffered spans before dropping
max_export_batch_size=512, # Spans per batch
schedule_delay_millis=5000, # Export interval (ms)
export_timeout_millis=30000 # Export timeout (ms)
)
```
### Data Scrubbing
Automatically redact sensitive information from spans:
```python
from sp_obs import DefaultScrubber, NoOpScrubber
# Use default scrubber (removes tokens, keys, passwords)
sp_obs.configure(
api_key="your-api-key",
scrubber=DefaultScrubber()
)
# Disable scrubbing
sp_obs.configure(
api_key="your-api-key",
scrubber=NoOpScrubber()
)
# Custom scrubber
class CustomScrubber:
def scrub_attributes(self, attributes: dict) -> dict:
# Your scrubbing logic
return attributes
sp_obs.configure(
api_key="your-api-key",
scrubber=CustomScrubber()
)
```
### Additional Options
```python
sp_obs.configure(
api_key="your-api-key",
endpoint="https://custom.endpoint.com", # Custom endpoint
headers={"X-Custom": "header"}, # Additional headers
timeout=10, # Request timeout (seconds)
set_global_tracer=False # Disable if using another tracer
)
```
## License
MIT
Raw data
{
"_id": null,
"home_page": null,
"name": "sp-obs",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "ai, llm, monitoring, observability, opentelemetry, spinal, tracing",
"author": null,
"author_email": "Andrew van Rensburg <andrew@withspinal.com>",
"download_url": "https://files.pythonhosted.org/packages/a0/84/572170155bceeb10387bf307692ea390e9d3f0a987843d9cca351a4960d9/sp_obs-0.5.1.tar.gz",
"platform": null,
"description": "# sp-obs\n\nSP-OBS is Spinal's cost tracking library built on top of OpenTelemetry. It works by automatically instrumenting HTTP libraries (httpx, requests) and \nattaching a processor to existing OpenTelemetry setups. This dual approach allows it to integrate seamlessly with existing observability frameworks while \nselectively forwarding AI/LLM operations and billing events to Spinal's platform.\n\n## Features\n\n- Seamlessly integrates with existing OpenTelemetry setups\n- Works with Logfire, vanilla OpenTelemetry, or any OTEL-compatible framework\n- Automatic instrumentation of httpx and requests libraries\n- Adds user and workflow context to spans for better tracking\n- Selective span processing - only sends relevant AI/billing spans\n- Built-in data scrubbing for sensitive information\n\n## Installation\n\n```bash\npip install sp-obs\n```\n\n## Quick Start\n\n```python\nimport sp_obs\n\n# Configure with your API key\nsp_obs.configure(api_key=\"your-api-key\")\n\n# That's it! AI calls are now tracked automatically\n```\n\n## Adding Context\n\nUse tags to add business context to your AI operations:\n\n```python\n# Context manager (recommended)\nwith sp_obs.tag(user_id=\"user-123\", workflow_id=\"chat-session\"):\n # All AI calls here will be tagged\n response = openai_client.chat.completions.create(...)\n\n# Or set tags globally\nsp_obs.tag(user_id=\"user-123\", workflow_id=\"chat-session\")\n```\n\n## Supported Providers\n\n- **OpenAI** - GPT-4, GPT-3.5, DALL-E, Whisper, Embeddings\n- **Anthropic** - Claude 3 (Opus, Sonnet, Haiku), Claude 2\n- **ElevenLabs** - Text-to-speech\n- **Perplexity** - Online LLMs with search\n- **Deepgram** - Speech-to-text\n- **SerpAPI** - Search results\n- **ScrapingBee** - Web scraping\n- **Firecrawl** - Web crawling\n\n## Billing Events\n\nTrack custom billing events:\n\n```python\nsp_obs.add_billing_event(\n success=True,\n user_id=\"user-123\",\n amount=99.99,\n currency=\"USD\"\n)\n```\n\n## Environment Variables\n\n- `SPINAL_API_KEY` - Your API key\n- `SPINAL_TRACING_ENDPOINT` - Custom endpoint (default: https://cloud.withspinal.com)\n\n## Advanced Configuration\n\n### Batch Processing\n\nControl how spans are batched and exported:\n\n```python\nsp_obs.configure(\n api_key=\"your-api-key\",\n max_queue_size=2048, # Max buffered spans before dropping\n max_export_batch_size=512, # Spans per batch\n schedule_delay_millis=5000, # Export interval (ms)\n export_timeout_millis=30000 # Export timeout (ms)\n)\n```\n\n### Data Scrubbing\n\nAutomatically redact sensitive information from spans:\n\n```python\nfrom sp_obs import DefaultScrubber, NoOpScrubber\n\n# Use default scrubber (removes tokens, keys, passwords)\nsp_obs.configure(\n api_key=\"your-api-key\",\n scrubber=DefaultScrubber()\n)\n\n# Disable scrubbing\nsp_obs.configure(\n api_key=\"your-api-key\",\n scrubber=NoOpScrubber()\n)\n\n# Custom scrubber\nclass CustomScrubber:\n def scrub_attributes(self, attributes: dict) -> dict:\n # Your scrubbing logic\n return attributes\n\nsp_obs.configure(\n api_key=\"your-api-key\",\n scrubber=CustomScrubber()\n)\n```\n\n### Additional Options\n\n```python\nsp_obs.configure(\n api_key=\"your-api-key\",\n endpoint=\"https://custom.endpoint.com\", # Custom endpoint\n headers={\"X-Custom\": \"header\"}, # Additional headers\n timeout=10, # Request timeout (seconds)\n set_global_tracer=False # Disable if using another tracer\n)\n```\n\n## License\n\nMIT",
"bugtrack_url": null,
"license": null,
"summary": "Observability integration with Spinal",
"version": "0.5.1",
"project_urls": {
"Homepage": "https://github.com/withspinal/sp-obs",
"Issues": "https://github.com/withspinal/sp-obs/issues"
},
"split_keywords": [
"ai",
" llm",
" monitoring",
" observability",
" opentelemetry",
" spinal",
" tracing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5dd96b308213395c994ad1694ee7558e995a5ca030f7cccf3f72003513921dd5",
"md5": "b9220bf7c500fcfd44add878adddf76e",
"sha256": "46393c42fd80015be937283c319054f111327a419692de04ebd4b3acb4b90d90"
},
"downloads": -1,
"filename": "sp_obs-0.5.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b9220bf7c500fcfd44add878adddf76e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 33993,
"upload_time": "2025-10-17T16:41:08",
"upload_time_iso_8601": "2025-10-17T16:41:08.113257Z",
"url": "https://files.pythonhosted.org/packages/5d/d9/6b308213395c994ad1694ee7558e995a5ca030f7cccf3f72003513921dd5/sp_obs-0.5.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a084572170155bceeb10387bf307692ea390e9d3f0a987843d9cca351a4960d9",
"md5": "d5cada96f1f17f2d90955c88eb913d09",
"sha256": "8fea2db6f4ae7e63b4df564d0fdd62b62f2dd6ef1047a9bddcbfa078c8ad30f1"
},
"downloads": -1,
"filename": "sp_obs-0.5.1.tar.gz",
"has_sig": false,
"md5_digest": "d5cada96f1f17f2d90955c88eb913d09",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 118599,
"upload_time": "2025-10-17T16:41:09",
"upload_time_iso_8601": "2025-10-17T16:41:09.590790Z",
"url": "https://files.pythonhosted.org/packages/a0/84/572170155bceeb10387bf307692ea390e9d3f0a987843d9cca351a4960d9/sp_obs-0.5.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-17 16:41:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "withspinal",
"github_project": "sp-obs",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "sp-obs"
}