prismer 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.
prismer-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,361 @@
1
+ Metadata-Version: 2.4
2
+ Name: prismer
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for Prismer Cloud API
5
+ Author-email: Prismer <dev@prismer.io>
6
+ License: MIT
7
+ Project-URL: Homepage, https://prismer.io
8
+ Project-URL: Documentation, https://docs.prismer.io
9
+ Project-URL: Repository, https://github.com/prismer-io/prismer-sdk-python
10
+ Keywords: prismer,ai,context,sdk,api
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: httpx>=0.24.0
24
+ Requires-Dist: pydantic>=2.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
27
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
28
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
29
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
30
+
31
+ # prismer
32
+
33
+ Official Python SDK for Prismer Cloud Context API.
34
+
35
+ Prismer Cloud provides AI agents with fast, cached access to web content. Load URLs or search queries, get compressed high-quality content (HQCC) optimized for LLM consumption.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install prismer
41
+ ```
42
+
43
+ ## Quick Start
44
+
45
+ ```python
46
+ from prismer import PrismerClient
47
+
48
+ client = PrismerClient(api_key="sk-prismer-...")
49
+
50
+ # Load content from a URL
51
+ result = client.load("https://example.com")
52
+ if result.success and result.result:
53
+ print(result.result.hqcc) # Compressed content for LLM
54
+ ```
55
+
56
+ ### Async Support
57
+
58
+ ```python
59
+ from prismer import AsyncPrismerClient
60
+
61
+ async with AsyncPrismerClient(api_key="sk-prismer-...") as client:
62
+ result = await client.load("https://example.com")
63
+ print(result.result.hqcc if result.result else None)
64
+ ```
65
+
66
+ ---
67
+
68
+ ## API Reference
69
+
70
+ ### Constructor
71
+
72
+ ```python
73
+ client = PrismerClient(
74
+ api_key="sk-prismer-...", # Required
75
+ base_url="https://api.prismer.io", # Optional
76
+ timeout=30.0, # Optional, seconds
77
+ )
78
+ ```
79
+
80
+ ---
81
+
82
+ ## `load(input, **options)`
83
+
84
+ Load content from URL(s) or search query. The API auto-detects input type.
85
+
86
+ ### Input Types
87
+
88
+ | Input | Mode | Description |
89
+ |-------|------|-------------|
90
+ | `"https://..."` | `single_url` | Fetch single URL, check cache first |
91
+ | `["url1", "url2"]` | `batch_urls` | Batch cache lookup |
92
+ | `"search query"` | `query` | Search → cache check → compress → rank |
93
+
94
+ ### Examples
95
+
96
+ #### Single URL
97
+
98
+ ```python
99
+ result = client.load("https://example.com")
100
+
101
+ # Result structure:
102
+ # LoadResult(
103
+ # success=True,
104
+ # request_id="load_abc123",
105
+ # mode="single_url",
106
+ # result=LoadResultItem(
107
+ # url="https://example.com",
108
+ # title="Example Domain",
109
+ # hqcc="# Example Domain\n\nThis domain is for...",
110
+ # cached=True,
111
+ # cached_at="2024-01-15T10:30:00Z",
112
+ # ),
113
+ # cost={"credits": 0, "cached": True},
114
+ # processing_time=45
115
+ # )
116
+ ```
117
+
118
+ #### Batch URLs
119
+
120
+ ```python
121
+ # Cache check only (default)
122
+ result = client.load(["url1", "url2", "url3"])
123
+
124
+ # With processing for uncached URLs
125
+ result = client.load(
126
+ ["url1", "url2", "url3"],
127
+ process_uncached=True,
128
+ processing={
129
+ "strategy": "fast", # "auto" | "fast" | "quality"
130
+ "maxConcurrent": 5 # Parallel compression limit
131
+ }
132
+ )
133
+
134
+ # Result:
135
+ # result.results = [
136
+ # LoadResultItem(url="url1", found=True, cached=True, hqcc="..."),
137
+ # LoadResultItem(url="url2", found=True, cached=False, processed=True, hqcc="..."),
138
+ # LoadResultItem(url="url3", found=False, cached=False, hqcc=None),
139
+ # ]
140
+ # result.summary = {"total": 3, "found": 2, "notFound": 1, "cached": 1, "processed": 1}
141
+ ```
142
+
143
+ #### Search Query
144
+
145
+ ```python
146
+ result = client.load(
147
+ "latest developments in AI agents 2024",
148
+ search={"topK": 15}, # Search results to fetch
149
+ processing={
150
+ "strategy": "quality",
151
+ "maxConcurrent": 3
152
+ },
153
+ return_config={
154
+ "topK": 5, # Results to return
155
+ "format": "both" # "hqcc" | "raw" | "both"
156
+ },
157
+ ranking={
158
+ "preset": "cache_first" # Prefer cached results
159
+ # Or custom weights:
160
+ # "custom": {"cacheHit": 0.3, "relevance": 0.4, "freshness": 0.2, "quality": 0.1}
161
+ }
162
+ )
163
+
164
+ # Result:
165
+ # result.results = [
166
+ # LoadResultItem(
167
+ # rank=1,
168
+ # url="https://...",
169
+ # title="AI Agents in 2024",
170
+ # hqcc="...",
171
+ # raw="...",
172
+ # cached=True,
173
+ # ranking=RankingInfo(
174
+ # score=0.85,
175
+ # factors=RankingFactors(cache=0.3, relevance=0.35, freshness=0.15, quality=0.05)
176
+ # )
177
+ # ),
178
+ # ...
179
+ # ]
180
+ # result.cost = {
181
+ # "searchCredits": 1,
182
+ # "compressionCredits": 3.5,
183
+ # "totalCredits": 4.5,
184
+ # "savedByCache": 4.0
185
+ # }
186
+ ```
187
+
188
+ ### Load Parameters
189
+
190
+ | Parameter | Type | Description |
191
+ |-----------|------|-------------|
192
+ | `input` | `str \| list[str]` | URL, URLs, or search query |
193
+ | `input_type` | `str` | Force type: `"url"`, `"urls"`, `"query"` |
194
+ | `process_uncached` | `bool` | Process uncached URLs in batch mode |
195
+ | `search` | `dict` | `{"topK": 15}` - search results to fetch |
196
+ | `processing` | `dict` | `{"strategy": "auto", "maxConcurrent": 3}` |
197
+ | `return_config` | `dict` | `{"format": "hqcc", "topK": 5}` |
198
+ | `ranking` | `dict` | `{"preset": "cache_first"}` or `{"custom": {...}}` |
199
+
200
+ ### Ranking Presets
201
+
202
+ | Preset | Description | Best For |
203
+ |--------|-------------|----------|
204
+ | `cache_first` | Strongly prefer cached results | Cost optimization |
205
+ | `relevance_first` | Prioritize search relevance | Accuracy-critical tasks |
206
+ | `balanced` | Equal weight to all factors | General use |
207
+
208
+ ---
209
+
210
+ ## `save()` / `save_batch()`
211
+
212
+ Save content to Prismer's global cache. Requires authentication.
213
+
214
+ ### Single Save
215
+
216
+ ```python
217
+ result = client.save(
218
+ url="https://example.com/article",
219
+ hqcc="Compressed content for LLM...",
220
+ raw="Original HTML/text content...", # Optional
221
+ meta={ # Optional
222
+ "source": "my-crawler",
223
+ "crawledAt": "2024-01-15T10:30:00Z"
224
+ }
225
+ )
226
+
227
+ # Result:
228
+ # SaveResult(success=True, status="created", url="...")
229
+ # Or if already exists:
230
+ # SaveResult(success=True, status="exists", url="...")
231
+ ```
232
+
233
+ ### Batch Save (max 50 items)
234
+
235
+ ```python
236
+ result = client.save(items=[
237
+ {"url": "url1", "hqcc": "content1"},
238
+ {"url": "url2", "hqcc": "content2", "raw": "raw2"},
239
+ {"url": "url3", "hqcc": "content3", "meta": {"source": "bot"}},
240
+ ])
241
+
242
+ # Or use SaveOptions for type safety:
243
+ from prismer import SaveOptions
244
+
245
+ result = client.save_batch([
246
+ SaveOptions(url="url1", hqcc="content1"),
247
+ SaveOptions(url="url2", hqcc="content2"),
248
+ ])
249
+
250
+ # Result:
251
+ # SaveResult(
252
+ # success=True,
253
+ # results=[
254
+ # SaveResultItem(url="url1", status="created"),
255
+ # SaveResultItem(url="url2", status="exists"),
256
+ # ],
257
+ # summary=SaveSummary(total=2, created=1, exists=1)
258
+ # )
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Error Handling
264
+
265
+ ```python
266
+ result = client.load("https://example.com")
267
+
268
+ if not result.success:
269
+ print(f"Error [{result.error.code}]: {result.error.message}")
270
+
271
+ # Handle specific errors:
272
+ if result.error.code == "UNAUTHORIZED":
273
+ # Invalid or missing API key
274
+ pass
275
+ elif result.error.code == "INVALID_INPUT":
276
+ # Bad request parameters
277
+ pass
278
+ elif result.error.code == "TIMEOUT":
279
+ # Request timed out
280
+ pass
281
+ elif result.error.code == "NETWORK_ERROR":
282
+ # Network connectivity issue
283
+ pass
284
+ return
285
+
286
+ # Safe to use result
287
+ print(result.result.hqcc if result.result else None)
288
+ ```
289
+
290
+ ---
291
+
292
+ ## Type Hints
293
+
294
+ Full type hints with Pydantic models:
295
+
296
+ ```python
297
+ from prismer import (
298
+ PrismerClient,
299
+ AsyncPrismerClient,
300
+ LoadResult,
301
+ LoadResultItem,
302
+ SaveResult,
303
+ SaveOptions,
304
+ PrismerError,
305
+ )
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Best Practices
311
+
312
+ ### 1. Use Context Manager for Async Client
313
+
314
+ ```python
315
+ # ✅ Properly closes connection
316
+ async with AsyncPrismerClient(api_key="...") as client:
317
+ result = await client.load("https://example.com")
318
+
319
+ # Or manually close:
320
+ client = AsyncPrismerClient(api_key="...")
321
+ try:
322
+ result = await client.load("https://example.com")
323
+ finally:
324
+ await client.close()
325
+ ```
326
+
327
+ ### 2. Batch URLs When Possible
328
+
329
+ ```python
330
+ # ❌ Multiple individual requests
331
+ for url in urls:
332
+ client.load(url)
333
+
334
+ # ✅ Single batch request
335
+ client.load(urls, process_uncached=True)
336
+ ```
337
+
338
+ ### 3. Use Cache-First Ranking for Cost Savings
339
+
340
+ ```python
341
+ result = client.load("AI news", ranking={"preset": "cache_first"})
342
+ print(f"Saved {result.cost.get('savedByCache', 0)} credits from cache")
343
+ ```
344
+
345
+ ---
346
+
347
+ ## Environment Variables
348
+
349
+ ```bash
350
+ # Optional: Set default API key
351
+ export PRISMER_API_KEY=sk-prismer-...
352
+
353
+ # Optional: Custom API endpoint
354
+ export PRISMER_BASE_URL=https://api.prismer.io
355
+ ```
356
+
357
+ ---
358
+
359
+ ## License
360
+
361
+ MIT
@@ -0,0 +1,331 @@
1
+ # prismer
2
+
3
+ Official Python SDK for Prismer Cloud Context API.
4
+
5
+ Prismer Cloud provides AI agents with fast, cached access to web content. Load URLs or search queries, get compressed high-quality content (HQCC) optimized for LLM consumption.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install prismer
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```python
16
+ from prismer import PrismerClient
17
+
18
+ client = PrismerClient(api_key="sk-prismer-...")
19
+
20
+ # Load content from a URL
21
+ result = client.load("https://example.com")
22
+ if result.success and result.result:
23
+ print(result.result.hqcc) # Compressed content for LLM
24
+ ```
25
+
26
+ ### Async Support
27
+
28
+ ```python
29
+ from prismer import AsyncPrismerClient
30
+
31
+ async with AsyncPrismerClient(api_key="sk-prismer-...") as client:
32
+ result = await client.load("https://example.com")
33
+ print(result.result.hqcc if result.result else None)
34
+ ```
35
+
36
+ ---
37
+
38
+ ## API Reference
39
+
40
+ ### Constructor
41
+
42
+ ```python
43
+ client = PrismerClient(
44
+ api_key="sk-prismer-...", # Required
45
+ base_url="https://api.prismer.io", # Optional
46
+ timeout=30.0, # Optional, seconds
47
+ )
48
+ ```
49
+
50
+ ---
51
+
52
+ ## `load(input, **options)`
53
+
54
+ Load content from URL(s) or search query. The API auto-detects input type.
55
+
56
+ ### Input Types
57
+
58
+ | Input | Mode | Description |
59
+ |-------|------|-------------|
60
+ | `"https://..."` | `single_url` | Fetch single URL, check cache first |
61
+ | `["url1", "url2"]` | `batch_urls` | Batch cache lookup |
62
+ | `"search query"` | `query` | Search → cache check → compress → rank |
63
+
64
+ ### Examples
65
+
66
+ #### Single URL
67
+
68
+ ```python
69
+ result = client.load("https://example.com")
70
+
71
+ # Result structure:
72
+ # LoadResult(
73
+ # success=True,
74
+ # request_id="load_abc123",
75
+ # mode="single_url",
76
+ # result=LoadResultItem(
77
+ # url="https://example.com",
78
+ # title="Example Domain",
79
+ # hqcc="# Example Domain\n\nThis domain is for...",
80
+ # cached=True,
81
+ # cached_at="2024-01-15T10:30:00Z",
82
+ # ),
83
+ # cost={"credits": 0, "cached": True},
84
+ # processing_time=45
85
+ # )
86
+ ```
87
+
88
+ #### Batch URLs
89
+
90
+ ```python
91
+ # Cache check only (default)
92
+ result = client.load(["url1", "url2", "url3"])
93
+
94
+ # With processing for uncached URLs
95
+ result = client.load(
96
+ ["url1", "url2", "url3"],
97
+ process_uncached=True,
98
+ processing={
99
+ "strategy": "fast", # "auto" | "fast" | "quality"
100
+ "maxConcurrent": 5 # Parallel compression limit
101
+ }
102
+ )
103
+
104
+ # Result:
105
+ # result.results = [
106
+ # LoadResultItem(url="url1", found=True, cached=True, hqcc="..."),
107
+ # LoadResultItem(url="url2", found=True, cached=False, processed=True, hqcc="..."),
108
+ # LoadResultItem(url="url3", found=False, cached=False, hqcc=None),
109
+ # ]
110
+ # result.summary = {"total": 3, "found": 2, "notFound": 1, "cached": 1, "processed": 1}
111
+ ```
112
+
113
+ #### Search Query
114
+
115
+ ```python
116
+ result = client.load(
117
+ "latest developments in AI agents 2024",
118
+ search={"topK": 15}, # Search results to fetch
119
+ processing={
120
+ "strategy": "quality",
121
+ "maxConcurrent": 3
122
+ },
123
+ return_config={
124
+ "topK": 5, # Results to return
125
+ "format": "both" # "hqcc" | "raw" | "both"
126
+ },
127
+ ranking={
128
+ "preset": "cache_first" # Prefer cached results
129
+ # Or custom weights:
130
+ # "custom": {"cacheHit": 0.3, "relevance": 0.4, "freshness": 0.2, "quality": 0.1}
131
+ }
132
+ )
133
+
134
+ # Result:
135
+ # result.results = [
136
+ # LoadResultItem(
137
+ # rank=1,
138
+ # url="https://...",
139
+ # title="AI Agents in 2024",
140
+ # hqcc="...",
141
+ # raw="...",
142
+ # cached=True,
143
+ # ranking=RankingInfo(
144
+ # score=0.85,
145
+ # factors=RankingFactors(cache=0.3, relevance=0.35, freshness=0.15, quality=0.05)
146
+ # )
147
+ # ),
148
+ # ...
149
+ # ]
150
+ # result.cost = {
151
+ # "searchCredits": 1,
152
+ # "compressionCredits": 3.5,
153
+ # "totalCredits": 4.5,
154
+ # "savedByCache": 4.0
155
+ # }
156
+ ```
157
+
158
+ ### Load Parameters
159
+
160
+ | Parameter | Type | Description |
161
+ |-----------|------|-------------|
162
+ | `input` | `str \| list[str]` | URL, URLs, or search query |
163
+ | `input_type` | `str` | Force type: `"url"`, `"urls"`, `"query"` |
164
+ | `process_uncached` | `bool` | Process uncached URLs in batch mode |
165
+ | `search` | `dict` | `{"topK": 15}` - search results to fetch |
166
+ | `processing` | `dict` | `{"strategy": "auto", "maxConcurrent": 3}` |
167
+ | `return_config` | `dict` | `{"format": "hqcc", "topK": 5}` |
168
+ | `ranking` | `dict` | `{"preset": "cache_first"}` or `{"custom": {...}}` |
169
+
170
+ ### Ranking Presets
171
+
172
+ | Preset | Description | Best For |
173
+ |--------|-------------|----------|
174
+ | `cache_first` | Strongly prefer cached results | Cost optimization |
175
+ | `relevance_first` | Prioritize search relevance | Accuracy-critical tasks |
176
+ | `balanced` | Equal weight to all factors | General use |
177
+
178
+ ---
179
+
180
+ ## `save()` / `save_batch()`
181
+
182
+ Save content to Prismer's global cache. Requires authentication.
183
+
184
+ ### Single Save
185
+
186
+ ```python
187
+ result = client.save(
188
+ url="https://example.com/article",
189
+ hqcc="Compressed content for LLM...",
190
+ raw="Original HTML/text content...", # Optional
191
+ meta={ # Optional
192
+ "source": "my-crawler",
193
+ "crawledAt": "2024-01-15T10:30:00Z"
194
+ }
195
+ )
196
+
197
+ # Result:
198
+ # SaveResult(success=True, status="created", url="...")
199
+ # Or if already exists:
200
+ # SaveResult(success=True, status="exists", url="...")
201
+ ```
202
+
203
+ ### Batch Save (max 50 items)
204
+
205
+ ```python
206
+ result = client.save(items=[
207
+ {"url": "url1", "hqcc": "content1"},
208
+ {"url": "url2", "hqcc": "content2", "raw": "raw2"},
209
+ {"url": "url3", "hqcc": "content3", "meta": {"source": "bot"}},
210
+ ])
211
+
212
+ # Or use SaveOptions for type safety:
213
+ from prismer import SaveOptions
214
+
215
+ result = client.save_batch([
216
+ SaveOptions(url="url1", hqcc="content1"),
217
+ SaveOptions(url="url2", hqcc="content2"),
218
+ ])
219
+
220
+ # Result:
221
+ # SaveResult(
222
+ # success=True,
223
+ # results=[
224
+ # SaveResultItem(url="url1", status="created"),
225
+ # SaveResultItem(url="url2", status="exists"),
226
+ # ],
227
+ # summary=SaveSummary(total=2, created=1, exists=1)
228
+ # )
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Error Handling
234
+
235
+ ```python
236
+ result = client.load("https://example.com")
237
+
238
+ if not result.success:
239
+ print(f"Error [{result.error.code}]: {result.error.message}")
240
+
241
+ # Handle specific errors:
242
+ if result.error.code == "UNAUTHORIZED":
243
+ # Invalid or missing API key
244
+ pass
245
+ elif result.error.code == "INVALID_INPUT":
246
+ # Bad request parameters
247
+ pass
248
+ elif result.error.code == "TIMEOUT":
249
+ # Request timed out
250
+ pass
251
+ elif result.error.code == "NETWORK_ERROR":
252
+ # Network connectivity issue
253
+ pass
254
+ return
255
+
256
+ # Safe to use result
257
+ print(result.result.hqcc if result.result else None)
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Type Hints
263
+
264
+ Full type hints with Pydantic models:
265
+
266
+ ```python
267
+ from prismer import (
268
+ PrismerClient,
269
+ AsyncPrismerClient,
270
+ LoadResult,
271
+ LoadResultItem,
272
+ SaveResult,
273
+ SaveOptions,
274
+ PrismerError,
275
+ )
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Best Practices
281
+
282
+ ### 1. Use Context Manager for Async Client
283
+
284
+ ```python
285
+ # ✅ Properly closes connection
286
+ async with AsyncPrismerClient(api_key="...") as client:
287
+ result = await client.load("https://example.com")
288
+
289
+ # Or manually close:
290
+ client = AsyncPrismerClient(api_key="...")
291
+ try:
292
+ result = await client.load("https://example.com")
293
+ finally:
294
+ await client.close()
295
+ ```
296
+
297
+ ### 2. Batch URLs When Possible
298
+
299
+ ```python
300
+ # ❌ Multiple individual requests
301
+ for url in urls:
302
+ client.load(url)
303
+
304
+ # ✅ Single batch request
305
+ client.load(urls, process_uncached=True)
306
+ ```
307
+
308
+ ### 3. Use Cache-First Ranking for Cost Savings
309
+
310
+ ```python
311
+ result = client.load("AI news", ranking={"preset": "cache_first"})
312
+ print(f"Saved {result.cost.get('savedByCache', 0)} credits from cache")
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Environment Variables
318
+
319
+ ```bash
320
+ # Optional: Set default API key
321
+ export PRISMER_API_KEY=sk-prismer-...
322
+
323
+ # Optional: Custom API endpoint
324
+ export PRISMER_BASE_URL=https://api.prismer.io
325
+ ```
326
+
327
+ ---
328
+
329
+ ## License
330
+
331
+ MIT
@@ -0,0 +1,35 @@
1
+ """
2
+ Prismer Cloud SDK for Python
3
+
4
+ Official Python SDK for Prismer Cloud API.
5
+
6
+ Example:
7
+ >>> from prismer import PrismerClient
8
+ >>> client = PrismerClient(api_key="sk-prismer-...")
9
+ >>> result = client.load("https://example.com")
10
+ >>> print(result.result.hqcc)
11
+ """
12
+
13
+ from .client import PrismerClient, AsyncPrismerClient
14
+ from .types import (
15
+ LoadOptions,
16
+ LoadResult,
17
+ LoadResultItem,
18
+ SaveOptions,
19
+ SaveBatchOptions,
20
+ SaveResult,
21
+ PrismerError,
22
+ )
23
+
24
+ __version__ = "0.1.0"
25
+ __all__ = [
26
+ "PrismerClient",
27
+ "AsyncPrismerClient",
28
+ "LoadOptions",
29
+ "LoadResult",
30
+ "LoadResultItem",
31
+ "SaveOptions",
32
+ "SaveBatchOptions",
33
+ "SaveResult",
34
+ "PrismerError",
35
+ ]