tessera-llm-proxy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tessera_llm_proxy-0.1.0/.gitignore +6 -0
- tessera_llm_proxy-0.1.0/PKG-INFO +153 -0
- tessera_llm_proxy-0.1.0/README.md +123 -0
- tessera_llm_proxy-0.1.0/pyproject.toml +63 -0
- tessera_llm_proxy-0.1.0/tessera/__init__.py +47 -0
- tessera_llm_proxy-0.1.0/tessera/core.py +322 -0
- tessera_llm_proxy-0.1.0/tests/test_core.py +214 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tessera-llm-proxy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Tessera SDK — drop-in LLM cost optimization. One line patches OpenAI, Anthropic, Mistral, Groq, Cohere clients to route through Tessera's auto-route + auto-cache + auto-compress + auto-batch proxy. Free tier: 60M tokens/mo. Production: 20% of measured savings, $0 if none.
|
|
5
|
+
Project-URL: Homepage, https://tesseraai.io
|
|
6
|
+
Project-URL: Documentation, https://tesseraai.io/dev
|
|
7
|
+
Project-URL: Repository, https://github.com/tessera-llm/sdk
|
|
8
|
+
Project-URL: Issues, https://github.com/tessera-llm/sdk/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/tessera-llm/sdk/releases
|
|
10
|
+
Author-email: "Tessera (Fintechagency OÜ)" <contact@tesseraai.io>
|
|
11
|
+
License: Apache-2.0
|
|
12
|
+
Keywords: ai-cost,ai-proxy,anthropic,claude,cohere,cost-optimization,gemini,gpt-4o,groq,llm,llm-cost,llm-proxy,mistral,observability,openai,tessera
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest-mock>=3.0; extra == 'test'
|
|
28
|
+
Requires-Dist: pytest>=7.0; extra == 'test'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# tessera-llm-proxy
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/tessera-llm-proxy/)
|
|
34
|
+
[](https://pypi.org/project/tessera-llm-proxy/)
|
|
35
|
+
|
|
36
|
+
**Drop-in cost optimization for LLM applications.** One line of code patches your existing OpenAI / Anthropic / Mistral / DeepSeek / Groq / Together / Fireworks / OpenRouter / Perplexity / Cerebras / xAI client to route through Tessera's measurement + auto-optimize proxy. You keep your provider account and keys; we route + cache + compress and measure savings on every request.
|
|
37
|
+
|
|
38
|
+
> Free Dev tier: **60M tokens / month · no card required · no fee until you upgrade.** Get your free key at [tesseraai.io/dev](https://tesseraai.io/dev).
|
|
39
|
+
|
|
40
|
+
## Get a free API key
|
|
41
|
+
|
|
42
|
+
→ **[Get free key](https://ledger.tesseraai.io/signup-dev)** (email + ToS, 30 seconds, no card)
|
|
43
|
+
|
|
44
|
+
After signup you get:
|
|
45
|
+
- Your `tk_` API key (shown once)
|
|
46
|
+
- A magic-link for the [dashboard](https://ledger.tesseraai.io/portal) — see your token counter + savings counter live
|
|
47
|
+
- 60M tokens/month at 10 req/min — generous for hobby + side projects
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install tessera-llm-proxy
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## One-line setup
|
|
56
|
+
|
|
57
|
+
Drop this at the top of your application's entry point (`main.py`, `app.py`, `manage.py`, wherever your app boots):
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
import tessera
|
|
61
|
+
tessera.activate("tk_your_tessera_key")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
That's it. Your existing code runs unchanged — `openai.OpenAI()`, `anthropic.Anthropic()`, `mistralai.Mistral()`, and other supported SDK constructors are transparently patched to route through Tessera. Your provider keys (OpenAI `sk-...`, Anthropic `sk-ant-...`, etc.) stay in your environment as before; Tessera forwards them upstream untouched.
|
|
65
|
+
|
|
66
|
+
### Environment variable form
|
|
67
|
+
|
|
68
|
+
If you'd rather not put the key in code:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
export TESSERA_KEY=tk_your_tessera_key
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import tessera
|
|
76
|
+
tessera.activate() # reads TESSERA_KEY from environment
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## What gets patched
|
|
80
|
+
|
|
81
|
+
Calling `tessera.activate(...)` patches the following SDKs at import time (each is opt-in: only patched if the library is installed):
|
|
82
|
+
|
|
83
|
+
| SDK | Tessera route |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `openai` (≥1.0) | `https://api.tesseraai.io/v1/openai` |
|
|
86
|
+
| `anthropic` | `https://api.tesseraai.io/v1/anthropic` |
|
|
87
|
+
| `mistralai` | `https://api.tesseraai.io/v1/mistral` |
|
|
88
|
+
| `cohere` | `https://api.tesseraai.io/v1/cohere` *(Wave 2)* |
|
|
89
|
+
| `groq` | `https://api.tesseraai.io/v1/groq` |
|
|
90
|
+
|
|
91
|
+
If you use a framework that wraps these SDKs (LangChain, LlamaIndex, CrewAI, AutoGen, Mastra, Pydantic AI, etc.), the patch applies transparently because those frameworks call the underlying SDK constructors which are what we patched.
|
|
92
|
+
|
|
93
|
+
## Direct provider URLs
|
|
94
|
+
|
|
95
|
+
If you call providers that aren't covered by an official Python SDK (DeepSeek, Together, Fireworks, OpenRouter, Perplexity, Cerebras, xAI), construct an `openai.OpenAI` client manually with the matching Tessera URL:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from openai import OpenAI
|
|
99
|
+
|
|
100
|
+
# DeepSeek via Tessera
|
|
101
|
+
client = OpenAI(
|
|
102
|
+
api_key="sk-deepseek-...",
|
|
103
|
+
base_url=tessera.url("deepseek"), # → https://api.tesseraai.io/v1/deepseek
|
|
104
|
+
default_headers=tessera.headers(),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Same pattern for: together, fireworks, openrouter, perplexity, cerebras, groq, xai
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`tessera.url(provider)` and `tessera.headers()` are pure helpers — no globals, no patching. Use them when you want explicit, traceable wiring.
|
|
111
|
+
|
|
112
|
+
## Verification
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
import tessera
|
|
116
|
+
tessera.activate("tk_...")
|
|
117
|
+
|
|
118
|
+
assert tessera.is_active(), "Tessera should be active after activate()"
|
|
119
|
+
print(tessera.status()) # → ProxyStatus(active=True, providers_patched=['openai', 'anthropic'], proxy_base='https://api.tesseraai.io/v1')
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Deactivation
|
|
123
|
+
|
|
124
|
+
To restore the original SDK constructors (e.g. in test teardown):
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
tessera.deactivate()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
tessera.activate(
|
|
134
|
+
key="tk_...", # or TESSERA_KEY env var
|
|
135
|
+
proxy_base="https://api.tesseraai.io/v1", # default; override for staging/dev
|
|
136
|
+
feature_tag="checkout-summarizer", # attaches to every request for per-feature attribution
|
|
137
|
+
)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`feature_tag` lets you split savings reporting per workload (e.g. one tag per logical feature in your app). You can also set per-request tags by passing `extra_body={"tessera_feature_tag": "..."}` on individual SDK calls.
|
|
141
|
+
|
|
142
|
+
## How the pricing works
|
|
143
|
+
|
|
144
|
+
- **Free Sandbox tier:** 60M tokens/month, no card required, $0 fee.
|
|
145
|
+
- **Production tier:** **20%** of measured savings, debited daily from a prepaid balance you control ($100 minimum top-up via Stripe).
|
|
146
|
+
- **Zero savings = zero fee.** If our optimization doesn't save you anything in a period, you pay nothing for that period.
|
|
147
|
+
- **Kill-switch** available anytime from your portal — pauses optimization, traffic still flows passthrough.
|
|
148
|
+
|
|
149
|
+
Full terms: <https://tesseraai.io/terms>
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
Apache-2.0
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# tessera-llm-proxy
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/tessera-llm-proxy/)
|
|
4
|
+
[](https://pypi.org/project/tessera-llm-proxy/)
|
|
5
|
+
|
|
6
|
+
**Drop-in cost optimization for LLM applications.** One line of code patches your existing OpenAI / Anthropic / Mistral / DeepSeek / Groq / Together / Fireworks / OpenRouter / Perplexity / Cerebras / xAI client to route through Tessera's measurement + auto-optimize proxy. You keep your provider account and keys; we route + cache + compress and measure savings on every request.
|
|
7
|
+
|
|
8
|
+
> Free Dev tier: **60M tokens / month · no card required · no fee until you upgrade.** Get your free key at [tesseraai.io/dev](https://tesseraai.io/dev).
|
|
9
|
+
|
|
10
|
+
## Get a free API key
|
|
11
|
+
|
|
12
|
+
→ **[Get free key](https://ledger.tesseraai.io/signup-dev)** (email + ToS, 30 seconds, no card)
|
|
13
|
+
|
|
14
|
+
After signup you get:
|
|
15
|
+
- Your `tk_` API key (shown once)
|
|
16
|
+
- A magic-link for the [dashboard](https://ledger.tesseraai.io/portal) — see your token counter + savings counter live
|
|
17
|
+
- 60M tokens/month at 10 req/min — generous for hobby + side projects
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install tessera-llm-proxy
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## One-line setup
|
|
26
|
+
|
|
27
|
+
Drop this at the top of your application's entry point (`main.py`, `app.py`, `manage.py`, wherever your app boots):
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import tessera
|
|
31
|
+
tessera.activate("tk_your_tessera_key")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
That's it. Your existing code runs unchanged — `openai.OpenAI()`, `anthropic.Anthropic()`, `mistralai.Mistral()`, and other supported SDK constructors are transparently patched to route through Tessera. Your provider keys (OpenAI `sk-...`, Anthropic `sk-ant-...`, etc.) stay in your environment as before; Tessera forwards them upstream untouched.
|
|
35
|
+
|
|
36
|
+
### Environment variable form
|
|
37
|
+
|
|
38
|
+
If you'd rather not put the key in code:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
export TESSERA_KEY=tk_your_tessera_key
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import tessera
|
|
46
|
+
tessera.activate() # reads TESSERA_KEY from environment
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## What gets patched
|
|
50
|
+
|
|
51
|
+
Calling `tessera.activate(...)` patches the following SDKs at import time (each is opt-in: only patched if the library is installed):
|
|
52
|
+
|
|
53
|
+
| SDK | Tessera route |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| `openai` (≥1.0) | `https://api.tesseraai.io/v1/openai` |
|
|
56
|
+
| `anthropic` | `https://api.tesseraai.io/v1/anthropic` |
|
|
57
|
+
| `mistralai` | `https://api.tesseraai.io/v1/mistral` |
|
|
58
|
+
| `cohere` | `https://api.tesseraai.io/v1/cohere` *(Wave 2)* |
|
|
59
|
+
| `groq` | `https://api.tesseraai.io/v1/groq` |
|
|
60
|
+
|
|
61
|
+
If you use a framework that wraps these SDKs (LangChain, LlamaIndex, CrewAI, AutoGen, Mastra, Pydantic AI, etc.), the patch applies transparently because those frameworks call the underlying SDK constructors which are what we patched.
|
|
62
|
+
|
|
63
|
+
## Direct provider URLs
|
|
64
|
+
|
|
65
|
+
If you call providers that aren't covered by an official Python SDK (DeepSeek, Together, Fireworks, OpenRouter, Perplexity, Cerebras, xAI), construct an `openai.OpenAI` client manually with the matching Tessera URL:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from openai import OpenAI
|
|
69
|
+
|
|
70
|
+
# DeepSeek via Tessera
|
|
71
|
+
client = OpenAI(
|
|
72
|
+
api_key="sk-deepseek-...",
|
|
73
|
+
base_url=tessera.url("deepseek"), # → https://api.tesseraai.io/v1/deepseek
|
|
74
|
+
default_headers=tessera.headers(),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Same pattern for: together, fireworks, openrouter, perplexity, cerebras, groq, xai
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`tessera.url(provider)` and `tessera.headers()` are pure helpers — no globals, no patching. Use them when you want explicit, traceable wiring.
|
|
81
|
+
|
|
82
|
+
## Verification
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import tessera
|
|
86
|
+
tessera.activate("tk_...")
|
|
87
|
+
|
|
88
|
+
assert tessera.is_active(), "Tessera should be active after activate()"
|
|
89
|
+
print(tessera.status()) # → ProxyStatus(active=True, providers_patched=['openai', 'anthropic'], proxy_base='https://api.tesseraai.io/v1')
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Deactivation
|
|
93
|
+
|
|
94
|
+
To restore the original SDK constructors (e.g. in test teardown):
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
tessera.deactivate()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Configuration
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
tessera.activate(
|
|
104
|
+
key="tk_...", # or TESSERA_KEY env var
|
|
105
|
+
proxy_base="https://api.tesseraai.io/v1", # default; override for staging/dev
|
|
106
|
+
feature_tag="checkout-summarizer", # attaches to every request for per-feature attribution
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`feature_tag` lets you split savings reporting per workload (e.g. one tag per logical feature in your app). You can also set per-request tags by passing `extra_body={"tessera_feature_tag": "..."}` on individual SDK calls.
|
|
111
|
+
|
|
112
|
+
## How the pricing works
|
|
113
|
+
|
|
114
|
+
- **Free Sandbox tier:** 60M tokens/month, no card required, $0 fee.
|
|
115
|
+
- **Production tier:** **20%** of measured savings, debited daily from a prepaid balance you control ($100 minimum top-up via Stripe).
|
|
116
|
+
- **Zero savings = zero fee.** If our optimization doesn't save you anything in a period, you pay nothing for that period.
|
|
117
|
+
- **Kill-switch** available anytime from your portal — pauses optimization, traffic still flows passthrough.
|
|
118
|
+
|
|
119
|
+
Full terms: <https://tesseraai.io/terms>
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
Apache-2.0
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tessera-llm-proxy"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Tessera SDK — drop-in LLM cost optimization. One line patches OpenAI, Anthropic, Mistral, Groq, Cohere clients to route through Tessera's auto-route + auto-cache + auto-compress + auto-batch proxy. Free tier: 60M tokens/mo. Production: 20% of measured savings, $0 if none."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Tessera (Fintechagency OÜ)", email = "contact@tesseraai.io" }
|
|
14
|
+
]
|
|
15
|
+
keywords = [
|
|
16
|
+
"tessera",
|
|
17
|
+
"llm",
|
|
18
|
+
"openai",
|
|
19
|
+
"anthropic",
|
|
20
|
+
"mistral",
|
|
21
|
+
"groq",
|
|
22
|
+
"cohere",
|
|
23
|
+
"cost-optimization",
|
|
24
|
+
"ai-cost",
|
|
25
|
+
"llm-cost",
|
|
26
|
+
"ai-proxy",
|
|
27
|
+
"llm-proxy",
|
|
28
|
+
"observability",
|
|
29
|
+
"gpt-4o",
|
|
30
|
+
"claude",
|
|
31
|
+
"gemini",
|
|
32
|
+
]
|
|
33
|
+
classifiers = [
|
|
34
|
+
"Development Status :: 4 - Beta",
|
|
35
|
+
"Intended Audience :: Developers",
|
|
36
|
+
"License :: OSI Approved :: Apache Software License",
|
|
37
|
+
"Operating System :: OS Independent",
|
|
38
|
+
"Programming Language :: Python :: 3",
|
|
39
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
40
|
+
"Programming Language :: Python :: 3.9",
|
|
41
|
+
"Programming Language :: Python :: 3.10",
|
|
42
|
+
"Programming Language :: Python :: 3.11",
|
|
43
|
+
"Programming Language :: Python :: 3.12",
|
|
44
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
45
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
46
|
+
]
|
|
47
|
+
dependencies = []
|
|
48
|
+
|
|
49
|
+
[project.optional-dependencies]
|
|
50
|
+
test = [
|
|
51
|
+
"pytest>=7.0",
|
|
52
|
+
"pytest-mock>=3.0",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://tesseraai.io"
|
|
57
|
+
Documentation = "https://tesseraai.io/dev"
|
|
58
|
+
Repository = "https://github.com/tessera-llm/sdk"
|
|
59
|
+
Issues = "https://github.com/tessera-llm/sdk/issues"
|
|
60
|
+
Changelog = "https://github.com/tessera-llm/sdk/releases"
|
|
61
|
+
|
|
62
|
+
[tool.hatch.build.targets.wheel]
|
|
63
|
+
packages = ["tessera"]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Tessera Optimize Layer — drop-in cost optimization for LLM SDKs.
|
|
2
|
+
|
|
3
|
+
One line of code patches OpenAI / Anthropic / Mistral / Groq / Cohere client
|
|
4
|
+
constructors so requests route through Tessera's measurement + auto-optimize
|
|
5
|
+
proxy. Your existing application code runs unchanged.
|
|
6
|
+
|
|
7
|
+
Typical use::
|
|
8
|
+
|
|
9
|
+
import tessera
|
|
10
|
+
tessera.activate("tk_your_tessera_key")
|
|
11
|
+
|
|
12
|
+
# Now any existing OpenAI/Anthropic/etc client created in this Python
|
|
13
|
+
# process will transparently forward through Tessera. No further code
|
|
14
|
+
# changes required.
|
|
15
|
+
|
|
16
|
+
For SDKs we don't auto-patch (DeepSeek/Together/Fireworks/OpenRouter/etc),
|
|
17
|
+
use ``tessera.url(provider)`` + ``tessera.headers()`` to wire an
|
|
18
|
+
``openai.OpenAI`` client manually.
|
|
19
|
+
|
|
20
|
+
Locked 2026-05-17 — γ-mode integration per founder direction
|
|
21
|
+
("Cloudflare-стиль: дай ключ, остальное мы делаем").
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from .core import (
|
|
27
|
+
ProxyStatus,
|
|
28
|
+
activate,
|
|
29
|
+
deactivate,
|
|
30
|
+
headers,
|
|
31
|
+
is_active,
|
|
32
|
+
status,
|
|
33
|
+
url,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__version__ = "0.1.0"
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"activate",
|
|
40
|
+
"deactivate",
|
|
41
|
+
"headers",
|
|
42
|
+
"is_active",
|
|
43
|
+
"ProxyStatus",
|
|
44
|
+
"status",
|
|
45
|
+
"url",
|
|
46
|
+
"__version__",
|
|
47
|
+
]
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""Tessera SDK core — global activation + per-provider patchers.
|
|
2
|
+
|
|
3
|
+
`activate()` walks a registry of provider-specific patchers. Each patcher is
|
|
4
|
+
opt-in: only fires if the corresponding SDK is importable. So a Python process
|
|
5
|
+
that has only `openai` installed will see `openai` patched and `anthropic`
|
|
6
|
+
silently skipped.
|
|
7
|
+
|
|
8
|
+
Patchers wrap the SDK's primary client constructor(s). After the wrap, every
|
|
9
|
+
new client instance created in the process has its `base_url` pointed at the
|
|
10
|
+
Tessera proxy + `X-Tessera-Key` injected into default headers, while the
|
|
11
|
+
caller's existing provider key (e.g. `sk-...`) stays untouched and flows
|
|
12
|
+
upstream as before.
|
|
13
|
+
|
|
14
|
+
This is intentionally a **global side-effect** per founder direction — same
|
|
15
|
+
shape as `cloudflare.activate()` or `sentry.init()`. Reversal via
|
|
16
|
+
`deactivate()` for test teardown.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import dataclasses
|
|
22
|
+
import importlib
|
|
23
|
+
import logging
|
|
24
|
+
import os
|
|
25
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger("tessera")
|
|
28
|
+
|
|
29
|
+
DEFAULT_PROXY_BASE = "https://api.tesseraai.io/v1"
|
|
30
|
+
|
|
31
|
+
_state: Dict[str, Any] = {
|
|
32
|
+
"active": False,
|
|
33
|
+
"key": None,
|
|
34
|
+
"proxy_base": DEFAULT_PROXY_BASE,
|
|
35
|
+
"feature_tag": None,
|
|
36
|
+
"patched": [], # list of (provider_name, restore_callable)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclasses.dataclass
|
|
41
|
+
class ProxyStatus:
|
|
42
|
+
"""Current state of the Tessera SDK patch."""
|
|
43
|
+
|
|
44
|
+
active: bool
|
|
45
|
+
providers_patched: List[str]
|
|
46
|
+
proxy_base: str
|
|
47
|
+
feature_tag: Optional[str]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def url(provider: str) -> str:
|
|
51
|
+
"""Return the Tessera proxy URL for ``provider``.
|
|
52
|
+
|
|
53
|
+
Pure helper — no globals required. Use when wiring an SDK client manually
|
|
54
|
+
(e.g. for providers without an official Python SDK such as DeepSeek,
|
|
55
|
+
Together, Fireworks, OpenRouter, Perplexity, Cerebras, xAI).
|
|
56
|
+
"""
|
|
57
|
+
base = _state.get("proxy_base") or DEFAULT_PROXY_BASE
|
|
58
|
+
return f"{base.rstrip('/')}/{provider.strip('/')}"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def headers(key: Optional[str] = None) -> Dict[str, str]:
|
|
62
|
+
"""Return the headers required to authenticate against Tessera.
|
|
63
|
+
|
|
64
|
+
Reads the activated key by default; pass ``key`` explicitly to override.
|
|
65
|
+
Use alongside :func:`url` for manual SDK wiring.
|
|
66
|
+
"""
|
|
67
|
+
resolved_key = key or _state.get("key") or os.environ.get("TESSERA_KEY")
|
|
68
|
+
if not resolved_key:
|
|
69
|
+
raise RuntimeError(
|
|
70
|
+
"Tessera key not set. Call `tessera.activate('tk_...')` first or "
|
|
71
|
+
"pass key= to tessera.headers()."
|
|
72
|
+
)
|
|
73
|
+
result = {"X-Tessera-Key": resolved_key}
|
|
74
|
+
tag = _state.get("feature_tag")
|
|
75
|
+
if tag:
|
|
76
|
+
result["X-Tessera-Feature-Tag"] = tag
|
|
77
|
+
return result
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def is_active() -> bool:
|
|
81
|
+
"""True if :func:`activate` has been called and patches are installed."""
|
|
82
|
+
return bool(_state.get("active"))
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def status() -> ProxyStatus:
|
|
86
|
+
"""Snapshot the current SDK state — useful in health checks + logging."""
|
|
87
|
+
return ProxyStatus(
|
|
88
|
+
active=bool(_state.get("active")),
|
|
89
|
+
providers_patched=[name for name, _ in _state.get("patched", [])],
|
|
90
|
+
proxy_base=_state.get("proxy_base") or DEFAULT_PROXY_BASE,
|
|
91
|
+
feature_tag=_state.get("feature_tag"),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def activate(
|
|
96
|
+
key: Optional[str] = None,
|
|
97
|
+
*,
|
|
98
|
+
proxy_base: Optional[str] = None,
|
|
99
|
+
feature_tag: Optional[str] = None,
|
|
100
|
+
) -> ProxyStatus:
|
|
101
|
+
"""Install Tessera patches globally.
|
|
102
|
+
|
|
103
|
+
:param key: Tessera API key (``tk_...``). Falls back to ``TESSERA_KEY``
|
|
104
|
+
environment variable when omitted.
|
|
105
|
+
:param proxy_base: Override the proxy origin. Default
|
|
106
|
+
``https://api.tesseraai.io/v1``. Used by Tessera staff for staging.
|
|
107
|
+
:param feature_tag: Attach a default ``X-Tessera-Feature-Tag`` header to
|
|
108
|
+
every patched request — useful for per-workload attribution.
|
|
109
|
+
:returns: :class:`ProxyStatus` with the current state.
|
|
110
|
+
:raises RuntimeError: If no key is provided either argument-side or via
|
|
111
|
+
the environment variable.
|
|
112
|
+
"""
|
|
113
|
+
resolved_key = key or os.environ.get("TESSERA_KEY")
|
|
114
|
+
if not resolved_key:
|
|
115
|
+
raise RuntimeError(
|
|
116
|
+
"Tessera key not provided. Pass key= to tessera.activate() or set "
|
|
117
|
+
"TESSERA_KEY environment variable."
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if _state["active"]:
|
|
121
|
+
# Re-activating with new args: deactivate first so we can re-patch with
|
|
122
|
+
# the new state cleanly.
|
|
123
|
+
deactivate()
|
|
124
|
+
|
|
125
|
+
_state["key"] = resolved_key
|
|
126
|
+
_state["proxy_base"] = (proxy_base or DEFAULT_PROXY_BASE).rstrip("/")
|
|
127
|
+
_state["feature_tag"] = feature_tag
|
|
128
|
+
_state["active"] = True
|
|
129
|
+
_state["patched"] = []
|
|
130
|
+
|
|
131
|
+
for patcher in _PATCHERS:
|
|
132
|
+
try:
|
|
133
|
+
restore = patcher()
|
|
134
|
+
if restore is not None:
|
|
135
|
+
_state["patched"].append((patcher.__name__.replace("_patch_", ""), restore))
|
|
136
|
+
except Exception as err: # noqa: BLE001 — best-effort patching
|
|
137
|
+
logger.warning(
|
|
138
|
+
"tessera: failed to patch %s: %s",
|
|
139
|
+
patcher.__name__,
|
|
140
|
+
err,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return status()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def deactivate() -> None:
|
|
147
|
+
"""Reverse all patches installed by :func:`activate`.
|
|
148
|
+
|
|
149
|
+
SDK constructors are restored to their original values. Safe to call when
|
|
150
|
+
Tessera is not active — becomes a no-op.
|
|
151
|
+
"""
|
|
152
|
+
for _provider, restore in reversed(_state.get("patched", [])):
|
|
153
|
+
try:
|
|
154
|
+
restore()
|
|
155
|
+
except Exception as err: # noqa: BLE001
|
|
156
|
+
logger.warning("tessera: failed to restore patch: %s", err)
|
|
157
|
+
_state["active"] = False
|
|
158
|
+
_state["patched"] = []
|
|
159
|
+
_state["key"] = None
|
|
160
|
+
_state["feature_tag"] = None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# ─── per-provider patchers ──────────────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _safe_import(module_name: str):
|
|
167
|
+
try:
|
|
168
|
+
return importlib.import_module(module_name)
|
|
169
|
+
except ImportError:
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _wrap_constructor(
|
|
174
|
+
cls: type,
|
|
175
|
+
*,
|
|
176
|
+
base_url_attr: str = "base_url",
|
|
177
|
+
headers_attr: str = "default_headers",
|
|
178
|
+
proxy_path: str,
|
|
179
|
+
) -> Callable[[], None]:
|
|
180
|
+
"""Wrap ``cls.__init__`` so newly-constructed instances route via Tessera.
|
|
181
|
+
|
|
182
|
+
Returns a restore callable that undoes the wrap.
|
|
183
|
+
"""
|
|
184
|
+
original_init = cls.__init__
|
|
185
|
+
proxy_url = url(proxy_path)
|
|
186
|
+
|
|
187
|
+
def patched_init(self: Any, *args: Any, **kwargs: Any) -> None:
|
|
188
|
+
# Don't override an explicit base_url override — caller wins.
|
|
189
|
+
if base_url_attr not in kwargs:
|
|
190
|
+
kwargs[base_url_attr] = proxy_url
|
|
191
|
+
# Merge default headers — preserve any caller-provided headers.
|
|
192
|
+
merged_headers: Dict[str, str] = dict(kwargs.get(headers_attr) or {})
|
|
193
|
+
for header_key, header_value in headers().items():
|
|
194
|
+
merged_headers.setdefault(header_key, header_value)
|
|
195
|
+
kwargs[headers_attr] = merged_headers
|
|
196
|
+
original_init(self, *args, **kwargs)
|
|
197
|
+
|
|
198
|
+
cls.__init__ = patched_init # type: ignore[method-assign]
|
|
199
|
+
|
|
200
|
+
def restore() -> None:
|
|
201
|
+
cls.__init__ = original_init # type: ignore[method-assign]
|
|
202
|
+
|
|
203
|
+
return restore
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _patch_openai() -> Optional[Callable[[], None]]:
|
|
207
|
+
mod = _safe_import("openai")
|
|
208
|
+
if mod is None:
|
|
209
|
+
return None
|
|
210
|
+
restorers: List[Callable[[], None]] = []
|
|
211
|
+
for class_name in ("OpenAI", "AsyncOpenAI"):
|
|
212
|
+
cls = getattr(mod, class_name, None)
|
|
213
|
+
if cls is None:
|
|
214
|
+
continue
|
|
215
|
+
restorers.append(
|
|
216
|
+
_wrap_constructor(cls, proxy_path="openai")
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def restore_all() -> None:
|
|
220
|
+
for r in restorers:
|
|
221
|
+
r()
|
|
222
|
+
|
|
223
|
+
return restore_all if restorers else None
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _patch_anthropic() -> Optional[Callable[[], None]]:
|
|
227
|
+
mod = _safe_import("anthropic")
|
|
228
|
+
if mod is None:
|
|
229
|
+
return None
|
|
230
|
+
restorers: List[Callable[[], None]] = []
|
|
231
|
+
for class_name in ("Anthropic", "AsyncAnthropic"):
|
|
232
|
+
cls = getattr(mod, class_name, None)
|
|
233
|
+
if cls is None:
|
|
234
|
+
continue
|
|
235
|
+
restorers.append(
|
|
236
|
+
_wrap_constructor(cls, proxy_path="anthropic")
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
def restore_all() -> None:
|
|
240
|
+
for r in restorers:
|
|
241
|
+
r()
|
|
242
|
+
|
|
243
|
+
return restore_all if restorers else None
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def _patch_mistral() -> Optional[Callable[[], None]]:
|
|
247
|
+
# Newer Mistral SDK (>=1.0) exposes class `Mistral`; legacy uses
|
|
248
|
+
# `MistralClient`. Patch whichever is present.
|
|
249
|
+
mod = _safe_import("mistralai")
|
|
250
|
+
if mod is None:
|
|
251
|
+
return None
|
|
252
|
+
restorers: List[Callable[[], None]] = []
|
|
253
|
+
for class_name in ("Mistral", "MistralClient", "AsyncMistral"):
|
|
254
|
+
cls = getattr(mod, class_name, None)
|
|
255
|
+
if cls is None:
|
|
256
|
+
continue
|
|
257
|
+
# Mistral SDK uses `server_url` rather than `base_url`
|
|
258
|
+
restorers.append(
|
|
259
|
+
_wrap_constructor(
|
|
260
|
+
cls,
|
|
261
|
+
base_url_attr="server_url",
|
|
262
|
+
headers_attr="default_headers",
|
|
263
|
+
proxy_path="mistral",
|
|
264
|
+
)
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def restore_all() -> None:
|
|
268
|
+
for r in restorers:
|
|
269
|
+
r()
|
|
270
|
+
|
|
271
|
+
return restore_all if restorers else None
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def _patch_groq() -> Optional[Callable[[], None]]:
|
|
275
|
+
mod = _safe_import("groq")
|
|
276
|
+
if mod is None:
|
|
277
|
+
return None
|
|
278
|
+
restorers: List[Callable[[], None]] = []
|
|
279
|
+
for class_name in ("Groq", "AsyncGroq"):
|
|
280
|
+
cls = getattr(mod, class_name, None)
|
|
281
|
+
if cls is None:
|
|
282
|
+
continue
|
|
283
|
+
restorers.append(
|
|
284
|
+
_wrap_constructor(cls, proxy_path="groq")
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def restore_all() -> None:
|
|
288
|
+
for r in restorers:
|
|
289
|
+
r()
|
|
290
|
+
|
|
291
|
+
return restore_all if restorers else None
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def _patch_cohere() -> Optional[Callable[[], None]]:
|
|
295
|
+
mod = _safe_import("cohere")
|
|
296
|
+
if mod is None:
|
|
297
|
+
return None
|
|
298
|
+
restorers: List[Callable[[], None]] = []
|
|
299
|
+
# Cohere v5+ SDK class names — patch whichever exist.
|
|
300
|
+
for class_name in ("Client", "ClientV2", "AsyncClient", "AsyncClientV2"):
|
|
301
|
+
cls = getattr(mod, class_name, None)
|
|
302
|
+
if cls is None:
|
|
303
|
+
continue
|
|
304
|
+
# Cohere uses `base_url` keyword
|
|
305
|
+
restorers.append(
|
|
306
|
+
_wrap_constructor(cls, proxy_path="cohere")
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
def restore_all() -> None:
|
|
310
|
+
for r in restorers:
|
|
311
|
+
r()
|
|
312
|
+
|
|
313
|
+
return restore_all if restorers else None
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
_PATCHERS: Tuple[Callable[[], Optional[Callable[[], None]]], ...] = (
|
|
317
|
+
_patch_openai,
|
|
318
|
+
_patch_anthropic,
|
|
319
|
+
_patch_mistral,
|
|
320
|
+
_patch_groq,
|
|
321
|
+
_patch_cohere,
|
|
322
|
+
)
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""Tessera SDK core tests — unit-level (no network).
|
|
2
|
+
|
|
3
|
+
We don't have OpenAI/Anthropic installed in the test environment necessarily,
|
|
4
|
+
so tests focus on the pure helpers (url, headers, status, activate/deactivate
|
|
5
|
+
lifecycle) and use a stub class to verify the wrap behaviour without depending
|
|
6
|
+
on a specific provider SDK being importable.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import types
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
import tessera
|
|
18
|
+
from tessera import core as tessera_core
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture(autouse=True)
|
|
22
|
+
def reset_state():
|
|
23
|
+
"""Ensure each test starts fresh."""
|
|
24
|
+
tessera_core.deactivate()
|
|
25
|
+
yield
|
|
26
|
+
tessera_core.deactivate()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_default_proxy_base():
|
|
30
|
+
assert tessera_core.DEFAULT_PROXY_BASE == "https://api.tesseraai.io/v1"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_url_helper():
|
|
34
|
+
assert tessera.url("openai") == "https://api.tesseraai.io/v1/openai"
|
|
35
|
+
assert tessera.url("anthropic") == "https://api.tesseraai.io/v1/anthropic"
|
|
36
|
+
assert tessera.url("deepseek") == "https://api.tesseraai.io/v1/deepseek"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_url_helper_with_leading_slash():
|
|
40
|
+
assert tessera.url("/openai") == "https://api.tesseraai.io/v1/openai"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_headers_requires_key():
|
|
44
|
+
with pytest.raises(RuntimeError, match="Tessera key not set"):
|
|
45
|
+
tessera.headers()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_headers_with_explicit_key():
|
|
49
|
+
result = tessera.headers(key="tk_test123")
|
|
50
|
+
assert result == {"X-Tessera-Key": "tk_test123"}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_headers_reads_env_var(monkeypatch):
|
|
54
|
+
monkeypatch.setenv("TESSERA_KEY", "tk_env_key")
|
|
55
|
+
# Without activate, headers() falls back to env
|
|
56
|
+
result = tessera.headers()
|
|
57
|
+
assert result["X-Tessera-Key"] == "tk_env_key"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_activate_requires_key():
|
|
61
|
+
with pytest.raises(RuntimeError, match="Tessera key not provided"):
|
|
62
|
+
tessera.activate()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_activate_reads_env_var(monkeypatch):
|
|
66
|
+
monkeypatch.setenv("TESSERA_KEY", "tk_env_activate")
|
|
67
|
+
status = tessera.activate()
|
|
68
|
+
assert status.active is True
|
|
69
|
+
assert tessera.is_active() is True
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_activate_explicit_key():
|
|
73
|
+
status = tessera.activate("tk_explicit")
|
|
74
|
+
assert status.active is True
|
|
75
|
+
assert tessera.headers() == {"X-Tessera-Key": "tk_explicit"}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_activate_feature_tag():
|
|
79
|
+
tessera.activate("tk_test", feature_tag="checkout-summarizer")
|
|
80
|
+
result = tessera.headers()
|
|
81
|
+
assert result["X-Tessera-Key"] == "tk_test"
|
|
82
|
+
assert result["X-Tessera-Feature-Tag"] == "checkout-summarizer"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_activate_custom_proxy_base():
|
|
86
|
+
status = tessera.activate("tk_test", proxy_base="https://staging.tesseraai.io/v1")
|
|
87
|
+
assert status.proxy_base == "https://staging.tesseraai.io/v1"
|
|
88
|
+
assert tessera.url("openai") == "https://staging.tesseraai.io/v1/openai"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_deactivate_is_safe_when_inactive():
|
|
92
|
+
# Should not raise.
|
|
93
|
+
tessera.deactivate()
|
|
94
|
+
assert tessera.is_active() is False
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_activate_then_deactivate_lifecycle():
|
|
98
|
+
tessera.activate("tk_test")
|
|
99
|
+
assert tessera.is_active() is True
|
|
100
|
+
tessera.deactivate()
|
|
101
|
+
assert tessera.is_active() is False
|
|
102
|
+
# headers() should now raise again
|
|
103
|
+
with pytest.raises(RuntimeError):
|
|
104
|
+
tessera.headers()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def test_re_activate_replaces_key():
|
|
108
|
+
tessera.activate("tk_first")
|
|
109
|
+
assert tessera.headers()["X-Tessera-Key"] == "tk_first"
|
|
110
|
+
tessera.activate("tk_second")
|
|
111
|
+
assert tessera.headers()["X-Tessera-Key"] == "tk_second"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_status_snapshot():
|
|
115
|
+
tessera.activate("tk_test", feature_tag="alpha")
|
|
116
|
+
s = tessera.status()
|
|
117
|
+
assert s.active is True
|
|
118
|
+
assert s.proxy_base == "https://api.tesseraai.io/v1"
|
|
119
|
+
assert s.feature_tag == "alpha"
|
|
120
|
+
# providers_patched may be empty in test env (no SDKs installed), or
|
|
121
|
+
# contain anything that happened to import — just assert shape.
|
|
122
|
+
assert isinstance(s.providers_patched, list)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_wrap_constructor_injects_base_url_and_headers(monkeypatch):
|
|
126
|
+
"""Drop a fake SDK module + class into sys.modules then verify the
|
|
127
|
+
patcher wraps it correctly. Proves the wrap mechanic without needing the
|
|
128
|
+
real openai package."""
|
|
129
|
+
|
|
130
|
+
captured = {}
|
|
131
|
+
|
|
132
|
+
class FakeClient:
|
|
133
|
+
def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
|
|
134
|
+
captured["api_key"] = api_key
|
|
135
|
+
captured["base_url"] = base_url
|
|
136
|
+
captured["default_headers"] = default_headers
|
|
137
|
+
|
|
138
|
+
fake_module = types.SimpleNamespace(OpenAI=FakeClient)
|
|
139
|
+
monkeypatch.setitem(sys.modules, "openai", fake_module)
|
|
140
|
+
|
|
141
|
+
tessera.activate("tk_wrap_test")
|
|
142
|
+
|
|
143
|
+
# Construct a FakeClient — wrap should inject base_url + Tessera key.
|
|
144
|
+
instance = FakeClient(api_key="sk-user") # noqa: F841 — side-effect captures
|
|
145
|
+
assert captured["base_url"] == "https://api.tesseraai.io/v1/openai"
|
|
146
|
+
assert captured["default_headers"] == {"X-Tessera-Key": "tk_wrap_test"}
|
|
147
|
+
assert captured["api_key"] == "sk-user"
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_wrap_does_not_override_explicit_base_url(monkeypatch):
|
|
151
|
+
"""If caller passes their own base_url, Tessera should NOT override it
|
|
152
|
+
(caller-wins principle for transparent migration)."""
|
|
153
|
+
|
|
154
|
+
captured = {}
|
|
155
|
+
|
|
156
|
+
class FakeClient:
|
|
157
|
+
def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
|
|
158
|
+
captured["base_url"] = base_url
|
|
159
|
+
captured["default_headers"] = default_headers
|
|
160
|
+
|
|
161
|
+
fake_module = types.SimpleNamespace(OpenAI=FakeClient)
|
|
162
|
+
monkeypatch.setitem(sys.modules, "openai", fake_module)
|
|
163
|
+
|
|
164
|
+
tessera.activate("tk_wrap_test")
|
|
165
|
+
|
|
166
|
+
FakeClient(api_key="sk-x", base_url="https://my-custom-proxy.example.com")
|
|
167
|
+
assert captured["base_url"] == "https://my-custom-proxy.example.com"
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_wrap_preserves_user_headers(monkeypatch):
|
|
171
|
+
"""Caller-provided default_headers should merge with Tessera's, not be
|
|
172
|
+
overwritten. Tessera only adds X-Tessera-Key; caller-provided keys win
|
|
173
|
+
on conflict (setdefault semantics)."""
|
|
174
|
+
|
|
175
|
+
captured = {}
|
|
176
|
+
|
|
177
|
+
class FakeClient:
|
|
178
|
+
def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
|
|
179
|
+
captured["default_headers"] = default_headers
|
|
180
|
+
|
|
181
|
+
fake_module = types.SimpleNamespace(OpenAI=FakeClient)
|
|
182
|
+
monkeypatch.setitem(sys.modules, "openai", fake_module)
|
|
183
|
+
|
|
184
|
+
tessera.activate("tk_wrap_test")
|
|
185
|
+
FakeClient(api_key="sk-x", default_headers={"X-User-Trace": "abc123"})
|
|
186
|
+
|
|
187
|
+
headers = captured["default_headers"]
|
|
188
|
+
assert headers["X-User-Trace"] == "abc123" # user header preserved
|
|
189
|
+
assert headers["X-Tessera-Key"] == "tk_wrap_test" # Tessera injected
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def test_deactivate_restores_original_constructor(monkeypatch):
|
|
193
|
+
"""After deactivate(), newly-created clients should NOT have Tessera
|
|
194
|
+
patches applied. Verifies the restore callable works end-to-end."""
|
|
195
|
+
|
|
196
|
+
captured = {}
|
|
197
|
+
init_calls = []
|
|
198
|
+
|
|
199
|
+
class FakeClient:
|
|
200
|
+
def __init__(self, api_key=None, base_url=None, default_headers=None, **kwargs):
|
|
201
|
+
init_calls.append("called")
|
|
202
|
+
captured["base_url"] = base_url
|
|
203
|
+
|
|
204
|
+
fake_module = types.SimpleNamespace(OpenAI=FakeClient)
|
|
205
|
+
monkeypatch.setitem(sys.modules, "openai", fake_module)
|
|
206
|
+
|
|
207
|
+
tessera.activate("tk_wrap_test")
|
|
208
|
+
FakeClient(api_key="sk-x")
|
|
209
|
+
assert captured["base_url"] == "https://api.tesseraai.io/v1/openai"
|
|
210
|
+
|
|
211
|
+
tessera.deactivate()
|
|
212
|
+
FakeClient(api_key="sk-x") # should now use original __init__
|
|
213
|
+
assert captured["base_url"] is None # no Tessera injection
|
|
214
|
+
assert len(init_calls) == 2
|