hammad-python 0.0.14__py3-none-any.whl → 0.0.16__py3-none-any.whl
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.
- hammad/__init__.py +177 -0
- hammad/{performance/imports.py → _internal.py} +7 -1
- hammad/cache/__init__.py +1 -1
- hammad/cli/__init__.py +3 -1
- hammad/cli/_runner.py +265 -0
- hammad/cli/animations.py +1 -1
- hammad/cli/plugins.py +133 -78
- hammad/cli/styles/__init__.py +1 -1
- hammad/cli/styles/utils.py +149 -3
- hammad/data/__init__.py +56 -29
- hammad/data/collections/__init__.py +27 -17
- hammad/data/collections/collection.py +205 -383
- hammad/data/collections/indexes/__init__.py +37 -0
- hammad/data/collections/indexes/qdrant/__init__.py +1 -0
- hammad/data/collections/indexes/qdrant/index.py +735 -0
- hammad/data/collections/indexes/qdrant/settings.py +94 -0
- hammad/data/collections/indexes/qdrant/utils.py +220 -0
- hammad/data/collections/indexes/tantivy/__init__.py +1 -0
- hammad/data/collections/indexes/tantivy/index.py +428 -0
- hammad/data/collections/indexes/tantivy/settings.py +51 -0
- hammad/data/collections/indexes/tantivy/utils.py +200 -0
- hammad/data/configurations/__init__.py +2 -2
- hammad/data/configurations/configuration.py +2 -2
- hammad/data/models/__init__.py +20 -9
- hammad/data/models/extensions/__init__.py +4 -0
- hammad/data/models/{pydantic → extensions/pydantic}/__init__.py +6 -19
- hammad/data/models/{pydantic → extensions/pydantic}/converters.py +143 -16
- hammad/data/models/{base/fields.py → fields.py} +1 -1
- hammad/data/models/{base/model.py → model.py} +1 -1
- hammad/data/models/{base/utils.py → utils.py} +1 -1
- hammad/data/sql/__init__.py +23 -0
- hammad/data/sql/database.py +578 -0
- hammad/data/sql/types.py +141 -0
- hammad/data/types/__init__.py +1 -3
- hammad/data/types/file.py +3 -3
- hammad/data/types/multimodal/__init__.py +2 -2
- hammad/data/types/multimodal/audio.py +2 -2
- hammad/data/types/multimodal/image.py +2 -2
- hammad/formatting/__init__.py +9 -27
- hammad/formatting/json/__init__.py +8 -2
- hammad/formatting/json/converters.py +7 -1
- hammad/formatting/text/__init__.py +1 -1
- hammad/formatting/yaml/__init__.py +1 -1
- hammad/genai/__init__.py +78 -0
- hammad/genai/agents/__init__.py +1 -0
- hammad/genai/agents/types/__init__.py +35 -0
- hammad/genai/agents/types/history.py +277 -0
- hammad/genai/agents/types/tool.py +490 -0
- hammad/genai/embedding_models/__init__.py +41 -0
- hammad/{ai/embeddings/client/litellm_embeddings_client.py → genai/embedding_models/embedding_model.py} +47 -142
- hammad/genai/embedding_models/embedding_model_name.py +77 -0
- hammad/genai/embedding_models/embedding_model_request.py +65 -0
- hammad/{ai/embeddings/types.py → genai/embedding_models/embedding_model_response.py} +3 -3
- hammad/genai/embedding_models/run.py +161 -0
- hammad/genai/language_models/__init__.py +35 -0
- hammad/genai/language_models/_streaming.py +622 -0
- hammad/genai/language_models/_types.py +276 -0
- hammad/genai/language_models/_utils/__init__.py +31 -0
- hammad/genai/language_models/_utils/_completions.py +131 -0
- hammad/genai/language_models/_utils/_messages.py +89 -0
- hammad/genai/language_models/_utils/_requests.py +202 -0
- hammad/genai/language_models/_utils/_structured_outputs.py +124 -0
- hammad/genai/language_models/language_model.py +734 -0
- hammad/genai/language_models/language_model_request.py +135 -0
- hammad/genai/language_models/language_model_response.py +219 -0
- hammad/genai/language_models/language_model_response_chunk.py +53 -0
- hammad/genai/language_models/run.py +530 -0
- hammad/genai/multimodal_models.py +48 -0
- hammad/genai/rerank_models.py +26 -0
- hammad/logging/__init__.py +1 -1
- hammad/logging/decorators.py +1 -1
- hammad/logging/logger.py +2 -2
- hammad/mcp/__init__.py +1 -1
- hammad/mcp/client/__init__.py +35 -0
- hammad/mcp/client/client.py +105 -4
- hammad/mcp/client/client_service.py +10 -3
- hammad/mcp/servers/__init__.py +24 -0
- hammad/{performance/runtime → runtime}/__init__.py +2 -2
- hammad/{performance/runtime → runtime}/decorators.py +1 -1
- hammad/{performance/runtime → runtime}/run.py +1 -1
- hammad/service/__init__.py +1 -1
- hammad/service/create.py +3 -8
- hammad/service/decorators.py +8 -8
- hammad/typing/__init__.py +28 -0
- hammad/web/__init__.py +3 -3
- hammad/web/http/client.py +1 -1
- hammad/web/models.py +53 -21
- hammad/web/search/client.py +99 -52
- hammad/web/utils.py +13 -13
- hammad_python-0.0.16.dist-info/METADATA +191 -0
- hammad_python-0.0.16.dist-info/RECORD +110 -0
- hammad/ai/__init__.py +0 -1
- hammad/ai/_utils.py +0 -142
- hammad/ai/completions/__init__.py +0 -45
- hammad/ai/completions/client.py +0 -684
- hammad/ai/completions/create.py +0 -710
- hammad/ai/completions/settings.py +0 -100
- hammad/ai/completions/types.py +0 -792
- hammad/ai/completions/utils.py +0 -486
- hammad/ai/embeddings/__init__.py +0 -35
- hammad/ai/embeddings/client/__init__.py +0 -1
- hammad/ai/embeddings/client/base_embeddings_client.py +0 -26
- hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +0 -200
- hammad/ai/embeddings/create.py +0 -159
- hammad/data/collections/base_collection.py +0 -58
- hammad/data/collections/searchable_collection.py +0 -556
- hammad/data/collections/vector_collection.py +0 -596
- hammad/data/databases/__init__.py +0 -21
- hammad/data/databases/database.py +0 -902
- hammad/data/models/base/__init__.py +0 -35
- hammad/data/models/pydantic/models/__init__.py +0 -28
- hammad/data/models/pydantic/models/arbitrary_model.py +0 -46
- hammad/data/models/pydantic/models/cacheable_model.py +0 -79
- hammad/data/models/pydantic/models/fast_model.py +0 -318
- hammad/data/models/pydantic/models/function_model.py +0 -176
- hammad/data/models/pydantic/models/subscriptable_model.py +0 -63
- hammad/performance/__init__.py +0 -36
- hammad/py.typed +0 -0
- hammad_python-0.0.14.dist-info/METADATA +0 -70
- hammad_python-0.0.14.dist-info/RECORD +0 -99
- {hammad_python-0.0.14.dist-info → hammad_python-0.0.16.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.14.dist-info → hammad_python-0.0.16.dist-info}/licenses/LICENSE +0 -0
hammad/web/search/client.py
CHANGED
@@ -17,12 +17,18 @@ from tenacity import (
|
|
17
17
|
)
|
18
18
|
|
19
19
|
from ..models import (
|
20
|
+
SearchResult,
|
21
|
+
NewsResult,
|
20
22
|
SearchResults,
|
21
23
|
NewsResults,
|
22
24
|
WebPageResult,
|
23
25
|
WebPageErrorResult,
|
24
26
|
WebPageResults,
|
25
27
|
ExtractedLinks,
|
28
|
+
ExtractedLink,
|
29
|
+
LinkInfo,
|
30
|
+
ImageInfo,
|
31
|
+
SelectedElement,
|
26
32
|
)
|
27
33
|
|
28
34
|
__all__ = ("AsyncSearchClient", "SearchClient", "create_search_client")
|
@@ -69,7 +75,7 @@ class AsyncSearchClient:
|
|
69
75
|
"""Get a DuckDuckGo search client using lazy import and singleton pattern."""
|
70
76
|
if self._ddgs_client is None:
|
71
77
|
try:
|
72
|
-
from
|
78
|
+
from ddgs import DDGS
|
73
79
|
|
74
80
|
self._ddgs_client = DDGS
|
75
81
|
except ImportError as e:
|
@@ -111,7 +117,7 @@ class AsyncSearchClient:
|
|
111
117
|
max_retries: Optional[int] = None,
|
112
118
|
) -> SearchResults:
|
113
119
|
"""
|
114
|
-
(deprecated in favor of `
|
120
|
+
(deprecated in favor of `web_search`)
|
115
121
|
|
116
122
|
Args:
|
117
123
|
query: Search query string
|
@@ -132,9 +138,9 @@ class AsyncSearchClient:
|
|
132
138
|
from rich import print
|
133
139
|
|
134
140
|
print(
|
135
|
-
"[bold yellow]WARNING: [/bold yellow] [yellow]Using `AsyncSearchClient.[bold light_salmon3]search[/bold light_salmon3]` is now deprecated in favor of `AsyncSearchClient.[bold light_salmon3]
|
141
|
+
"[bold yellow]WARNING: [/bold yellow] [yellow]Using `AsyncSearchClient.[bold light_salmon3]search[/bold light_salmon3]` is now deprecated in favor of `AsyncSearchClient.[bold light_salmon3]web_search[/bold light_salmon3]`[/yellow]"
|
136
142
|
)
|
137
|
-
return await self.
|
143
|
+
return await self.web_search(
|
138
144
|
query,
|
139
145
|
max_results=max_results,
|
140
146
|
region=region,
|
@@ -142,7 +148,7 @@ class AsyncSearchClient:
|
|
142
148
|
timelimit=timelimit,
|
143
149
|
)
|
144
150
|
|
145
|
-
async def
|
151
|
+
async def web_search(
|
146
152
|
self,
|
147
153
|
query: str,
|
148
154
|
*,
|
@@ -180,7 +186,7 @@ class AsyncSearchClient:
|
|
180
186
|
async def _do_search():
|
181
187
|
DDGS = self._get_duckduckgo_client()
|
182
188
|
with DDGS() as ddgs:
|
183
|
-
|
189
|
+
raw_results = list(
|
184
190
|
ddgs.text(
|
185
191
|
keywords=query.strip(),
|
186
192
|
region=region,
|
@@ -190,7 +196,21 @@ class AsyncSearchClient:
|
|
190
196
|
max_results=max_results,
|
191
197
|
)
|
192
198
|
)
|
193
|
-
|
199
|
+
|
200
|
+
# Convert raw results to SearchResult models
|
201
|
+
search_results = [
|
202
|
+
SearchResult(
|
203
|
+
title=result.get("title", ""),
|
204
|
+
href=result.get("href", ""),
|
205
|
+
body=result.get("body", "")
|
206
|
+
)
|
207
|
+
for result in raw_results
|
208
|
+
]
|
209
|
+
|
210
|
+
return SearchResults(
|
211
|
+
query=query.strip(),
|
212
|
+
results=search_results
|
213
|
+
)
|
194
214
|
|
195
215
|
async for attempt in AsyncRetrying(
|
196
216
|
stop=stop_after_attempt(retries + 1),
|
@@ -237,7 +257,7 @@ class AsyncSearchClient:
|
|
237
257
|
async def _do_news_search():
|
238
258
|
DDGS = self._get_duckduckgo_client()
|
239
259
|
with DDGS() as ddgs:
|
240
|
-
|
260
|
+
raw_results = list(
|
241
261
|
ddgs.news(
|
242
262
|
keywords=query.strip(),
|
243
263
|
region=region,
|
@@ -246,7 +266,24 @@ class AsyncSearchClient:
|
|
246
266
|
max_results=max_results,
|
247
267
|
)
|
248
268
|
)
|
249
|
-
|
269
|
+
|
270
|
+
# Convert raw results to NewsResult models
|
271
|
+
news_results = [
|
272
|
+
NewsResult(
|
273
|
+
date=result.get("date", ""),
|
274
|
+
title=result.get("title", ""),
|
275
|
+
body=result.get("body", ""),
|
276
|
+
url=result.get("url", ""),
|
277
|
+
image=result.get("image", ""),
|
278
|
+
source=result.get("source", "")
|
279
|
+
)
|
280
|
+
for result in raw_results
|
281
|
+
]
|
282
|
+
|
283
|
+
return NewsResults(
|
284
|
+
query=query.strip(),
|
285
|
+
results=news_results
|
286
|
+
)
|
250
287
|
|
251
288
|
async for attempt in AsyncRetrying(
|
252
289
|
stop=stop_after_attempt(retries + 1),
|
@@ -307,40 +344,35 @@ class AsyncSearchClient:
|
|
307
344
|
HTMLParser = self._get_selectolax_parser()
|
308
345
|
parser = HTMLParser(response.text)
|
309
346
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
"text": "",
|
316
|
-
"links": [],
|
317
|
-
"images": [],
|
318
|
-
"selected_elements": [],
|
319
|
-
}
|
347
|
+
title = ""
|
348
|
+
text = ""
|
349
|
+
links = []
|
350
|
+
images = []
|
351
|
+
selected_elements = []
|
320
352
|
|
321
353
|
# Extract title
|
322
354
|
title_node = parser.css_first("title")
|
323
355
|
if title_node:
|
324
|
-
|
356
|
+
title = title_node.text(strip=True)
|
325
357
|
|
326
358
|
# Extract text content
|
327
359
|
if extract_text:
|
328
360
|
if css_selector:
|
329
361
|
selected_nodes = parser.css(css_selector)
|
330
|
-
|
362
|
+
text = " ".join(
|
331
363
|
node.text(strip=True) for node in selected_nodes
|
332
364
|
)
|
333
365
|
else:
|
334
|
-
|
366
|
+
text = parser.text(strip=True)
|
335
367
|
|
336
368
|
# Extract links
|
337
369
|
if extract_links:
|
338
370
|
link_nodes = parser.css("a[href]")
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
371
|
+
links = [
|
372
|
+
LinkInfo(
|
373
|
+
href=node.attrs.get("href", ""),
|
374
|
+
text=node.text(strip=True),
|
375
|
+
)
|
344
376
|
for node in link_nodes
|
345
377
|
if node.attrs.get("href")
|
346
378
|
]
|
@@ -348,12 +380,12 @@ class AsyncSearchClient:
|
|
348
380
|
# Extract images
|
349
381
|
if extract_images:
|
350
382
|
img_nodes = parser.css("img[src]")
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
383
|
+
images = [
|
384
|
+
ImageInfo(
|
385
|
+
src=node.attrs.get("src", ""),
|
386
|
+
alt=node.attrs.get("alt", ""),
|
387
|
+
title=node.attrs.get("title", ""),
|
388
|
+
)
|
357
389
|
for node in img_nodes
|
358
390
|
if node.attrs.get("src")
|
359
391
|
]
|
@@ -361,17 +393,26 @@ class AsyncSearchClient:
|
|
361
393
|
# Extract selected elements
|
362
394
|
if css_selector:
|
363
395
|
selected_nodes = parser.css(css_selector)
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
396
|
+
selected_elements = [
|
397
|
+
SelectedElement(
|
398
|
+
tag=node.tag,
|
399
|
+
text=node.text(strip=True),
|
400
|
+
html=node.html,
|
401
|
+
attributes=dict(node.attributes),
|
402
|
+
)
|
371
403
|
for node in selected_nodes
|
372
404
|
]
|
373
405
|
|
374
|
-
return
|
406
|
+
return WebPageResult(
|
407
|
+
url=url,
|
408
|
+
status_code=response.status_code,
|
409
|
+
content_type=response.headers.get("content-type", ""),
|
410
|
+
title=title,
|
411
|
+
text=text,
|
412
|
+
links=links,
|
413
|
+
images=images,
|
414
|
+
selected_elements=selected_elements,
|
415
|
+
)
|
375
416
|
|
376
417
|
async for attempt in AsyncRetrying(
|
377
418
|
stop=stop_after_attempt(retries + 1),
|
@@ -460,7 +501,10 @@ class AsyncSearchClient:
|
|
460
501
|
tasks = [fetch_page(url) for url in unique_urls]
|
461
502
|
results = await asyncio.gather(*tasks, return_exceptions=False)
|
462
503
|
|
463
|
-
return
|
504
|
+
return WebPageResults(
|
505
|
+
urls=unique_urls,
|
506
|
+
results=results
|
507
|
+
)
|
464
508
|
|
465
509
|
async def extract_page_links(
|
466
510
|
self,
|
@@ -544,17 +588,20 @@ class AsyncSearchClient:
|
|
544
588
|
):
|
545
589
|
continue
|
546
590
|
|
547
|
-
link_info =
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
591
|
+
link_info = ExtractedLink(
|
592
|
+
href=absolute_href,
|
593
|
+
original_href=href,
|
594
|
+
text=node.text(strip=True),
|
595
|
+
title=node.attrs.get("title", ""),
|
596
|
+
type=link_type,
|
597
|
+
)
|
554
598
|
|
555
599
|
links.append(link_info)
|
556
600
|
|
557
|
-
return
|
601
|
+
return ExtractedLinks(
|
602
|
+
url=url,
|
603
|
+
results=links
|
604
|
+
)
|
558
605
|
|
559
606
|
async for attempt in AsyncRetrying(
|
560
607
|
stop=stop_after_attempt(retries + 1),
|
@@ -709,7 +756,7 @@ class SearchClient:
|
|
709
756
|
)
|
710
757
|
)
|
711
758
|
|
712
|
-
def
|
759
|
+
def web_search(
|
713
760
|
self,
|
714
761
|
query: str,
|
715
762
|
*,
|
@@ -740,7 +787,7 @@ class SearchClient:
|
|
740
787
|
Exception: If search fails after all retries
|
741
788
|
"""
|
742
789
|
return self._run_async(
|
743
|
-
self._async_client.
|
790
|
+
self._async_client.web_search(
|
744
791
|
query=query,
|
745
792
|
max_results=max_results,
|
746
793
|
region=region,
|
hammad/web/utils.py
CHANGED
@@ -17,11 +17,11 @@ from .models import (
|
|
17
17
|
|
18
18
|
__all__ = (
|
19
19
|
"run_web_request",
|
20
|
-
"
|
20
|
+
"run_web_search",
|
21
21
|
"read_web_page",
|
22
22
|
"read_web_pages",
|
23
|
-
"
|
24
|
-
"
|
23
|
+
"run_news_search",
|
24
|
+
"extract_web_page_links",
|
25
25
|
)
|
26
26
|
|
27
27
|
|
@@ -250,7 +250,7 @@ def run_web_request(
|
|
250
250
|
return asyncio.run(_run_web_request_async())
|
251
251
|
|
252
252
|
|
253
|
-
def
|
253
|
+
def run_web_search(
|
254
254
|
query: str,
|
255
255
|
*,
|
256
256
|
max_results: int = 10,
|
@@ -282,9 +282,9 @@ def search_web(
|
|
282
282
|
Exception: If search fails after all retries
|
283
283
|
"""
|
284
284
|
|
285
|
-
async def
|
285
|
+
async def _run_web_search_async():
|
286
286
|
client = _get_search_client()
|
287
|
-
return await client.
|
287
|
+
return await client.web_search(
|
288
288
|
query=query,
|
289
289
|
max_results=max_results,
|
290
290
|
region=region,
|
@@ -293,7 +293,7 @@ def search_web(
|
|
293
293
|
backend=backend,
|
294
294
|
)
|
295
295
|
|
296
|
-
return asyncio.run(
|
296
|
+
return asyncio.run(_run_web_search_async())
|
297
297
|
|
298
298
|
|
299
299
|
def read_web_page(
|
@@ -388,7 +388,7 @@ def read_web_pages(
|
|
388
388
|
return asyncio.run(_read_web_pages_async())
|
389
389
|
|
390
390
|
|
391
|
-
def
|
391
|
+
def run_news_search(
|
392
392
|
query: str,
|
393
393
|
*,
|
394
394
|
max_results: int = 10,
|
@@ -414,7 +414,7 @@ def search_news(
|
|
414
414
|
Exception: If search fails
|
415
415
|
"""
|
416
416
|
|
417
|
-
async def
|
417
|
+
async def _run_news_search_async():
|
418
418
|
client = _get_search_client()
|
419
419
|
return await client.search_news(
|
420
420
|
query=query,
|
@@ -424,10 +424,10 @@ def search_news(
|
|
424
424
|
timelimit=timelimit,
|
425
425
|
)
|
426
426
|
|
427
|
-
return asyncio.run(
|
427
|
+
return asyncio.run(_run_news_search_async())
|
428
428
|
|
429
429
|
|
430
|
-
def
|
430
|
+
def extract_web_page_links(
|
431
431
|
url: str,
|
432
432
|
*,
|
433
433
|
timeout: float = 30.0,
|
@@ -457,7 +457,7 @@ def extract_page_links(
|
|
457
457
|
Exception: If parsing fails
|
458
458
|
"""
|
459
459
|
|
460
|
-
async def
|
460
|
+
async def _extract_web_page_links_async():
|
461
461
|
client = _get_search_client()
|
462
462
|
return await client.extract_page_links(
|
463
463
|
url=url,
|
@@ -469,4 +469,4 @@ def extract_page_links(
|
|
469
469
|
base_url=base_url,
|
470
470
|
)
|
471
471
|
|
472
|
-
return asyncio.run(
|
472
|
+
return asyncio.run(_extract_web_page_links_async())
|
@@ -0,0 +1,191 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: hammad-python
|
3
|
+
Version: 0.0.16
|
4
|
+
Author-email: Hammad Saeed <hammadaidev@gmail.com>
|
5
|
+
License: MIT License
|
6
|
+
|
7
|
+
Copyright (c) 2025 Hammad Saeed
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
11
|
+
in the Software without restriction, including without limitation the rights
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
14
|
+
furnished to do so, subject to the following conditions:
|
15
|
+
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
17
|
+
copies or substantial portions of the Software.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
25
|
+
SOFTWARE.
|
26
|
+
License-File: LICENSE
|
27
|
+
Requires-Python: >=3.11
|
28
|
+
Requires-Dist: ddgs>=9.0.0
|
29
|
+
Requires-Dist: httpx>=0.28.1
|
30
|
+
Requires-Dist: msgspec>=0.19.0
|
31
|
+
Requires-Dist: pydantic>=2.11.7
|
32
|
+
Requires-Dist: rich>=14.0.0
|
33
|
+
Requires-Dist: selectolax>=0.3.31
|
34
|
+
Requires-Dist: sqlalchemy>=2.0.41
|
35
|
+
Requires-Dist: tantivy>=0.24.0
|
36
|
+
Requires-Dist: tenacity>=9.1.2
|
37
|
+
Requires-Dist: typing-inspect>=0.9.0
|
38
|
+
Provides-Extra: ai
|
39
|
+
Requires-Dist: instructor>=1.9.0; extra == 'ai'
|
40
|
+
Requires-Dist: litellm>=1.73.6; extra == 'ai'
|
41
|
+
Requires-Dist: qdrant-client>=1.14.3; extra == 'ai'
|
42
|
+
Provides-Extra: all
|
43
|
+
Requires-Dist: fastapi>=0.115.6; extra == 'all'
|
44
|
+
Requires-Dist: instructor>=1.9.0; extra == 'all'
|
45
|
+
Requires-Dist: litellm>=1.73.6; extra == 'all'
|
46
|
+
Requires-Dist: mcp>=1.10.1; extra == 'all'
|
47
|
+
Requires-Dist: qdrant-client>=1.14.3; extra == 'all'
|
48
|
+
Requires-Dist: uvicorn>=0.34.0; extra == 'all'
|
49
|
+
Provides-Extra: mcp
|
50
|
+
Requires-Dist: mcp>=1.10.1; extra == 'mcp'
|
51
|
+
Provides-Extra: serve
|
52
|
+
Requires-Dist: fastapi>=0.115.6; extra == 'serve'
|
53
|
+
Requires-Dist: uvicorn>=0.34.0; extra == 'serve'
|
54
|
+
Description-Content-Type: text/markdown
|
55
|
+
|
56
|
+
## hammad-python
|
57
|
+
|
58
|
+
> __Happily Accelerated Micro-Modules (_for_) Application Development__
|
59
|
+
|
60
|
+
## Introduction
|
61
|
+
|
62
|
+
The `hammad-python` library, is a mix of a love letter and collection of mixed resources for
|
63
|
+
developing Python applications. This library is meant to be used for rapid prototyping and
|
64
|
+
development, and is focused on providing styled placeholder tools for common patterns, tasks
|
65
|
+
and workflows.
|
66
|
+
|
67
|
+
The package is currently built into the following structures:
|
68
|
+
|
69
|
+
- `hammad-python` : Contains most core functionality and resources.
|
70
|
+
- `hammad-python[ai]` : Contains easy to use resources for Generative AI related tasks such as
|
71
|
+
generating completions with language models, or creating embeddings.
|
72
|
+
- `hammad-python[serve]` : Contains FastAPI / Uvicorn based resources for serving and running applications.
|
73
|
+
|
74
|
+
## Installation
|
75
|
+
|
76
|
+
You can install the package using `pip` or `uv`:
|
77
|
+
|
78
|
+
```bash
|
79
|
+
pip install hammad-python
|
80
|
+
|
81
|
+
# or install the `ai` extension
|
82
|
+
# pip install 'hammad-python[ai]'
|
83
|
+
|
84
|
+
# or install the `serve` extension
|
85
|
+
# pip install 'hammad-python[serve]'
|
86
|
+
```
|
87
|
+
|
88
|
+
```bash
|
89
|
+
uv pip install hammad-python
|
90
|
+
|
91
|
+
# or install the `ai` extension
|
92
|
+
# uv pip install 'hammad-python[ai]'
|
93
|
+
|
94
|
+
# or install the `serve` extension
|
95
|
+
# uv pip install 'hammad-python[serve]'
|
96
|
+
```
|
97
|
+
|
98
|
+
## Basic Usage
|
99
|
+
|
100
|
+
### Data Structures, Databases and Other Data Related Resources
|
101
|
+
|
102
|
+
#### Collections
|
103
|
+
|
104
|
+
Using `hammad.data.collections` is a simple way to create searchable collections of
|
105
|
+
data using both `bm25` and `vector` based search.
|
106
|
+
|
107
|
+
```python
|
108
|
+
from hammad.data.collections import create_collection
|
109
|
+
|
110
|
+
# Create either a `vector` or `searchable` collection
|
111
|
+
col = create_collection(type = "searchable")
|
112
|
+
|
113
|
+
# add anything to the collection
|
114
|
+
col.add("This is some text")
|
115
|
+
col.add(5)
|
116
|
+
col.add({'text' : "this is a dictionary"})
|
117
|
+
|
118
|
+
# search the collection
|
119
|
+
print(col.query("text"))
|
120
|
+
```
|
121
|
+
|
122
|
+
#### Databases
|
123
|
+
|
124
|
+
Any collection can be either used as a standalone database, or can be added as one
|
125
|
+
of the collections within a database. Databases provide a unified interface for handling
|
126
|
+
both `Searchable` and `Vector` based collections.
|
127
|
+
|
128
|
+
```python
|
129
|
+
from hammad.data.collections import create_collection
|
130
|
+
from hammad.data.databases import Database
|
131
|
+
|
132
|
+
# Create either a `vector` or `searchable` collection
|
133
|
+
col = create_collection(type = "searchable")
|
134
|
+
|
135
|
+
col.add("This is some text")
|
136
|
+
|
137
|
+
# Databases can either be created on memory or using a path
|
138
|
+
db = Database(location = "memory")
|
139
|
+
|
140
|
+
db.add_collection(col)
|
141
|
+
|
142
|
+
# search globally or within a single collection
|
143
|
+
print(db.query("text"))
|
144
|
+
```
|
145
|
+
|
146
|
+
### Styling / Introspection Resources
|
147
|
+
|
148
|
+
The `hammad-python` package contains a variety of components that can be used
|
149
|
+
to easily style, or run introspection (logging) on your code.
|
150
|
+
|
151
|
+
```python
|
152
|
+
from hammad.cli import print, input, animate
|
153
|
+
|
154
|
+
# Use extended `rich` styling easily
|
155
|
+
print("Hello, World", bg_settings = {"title" : "This is a title"})
|
156
|
+
|
157
|
+
# Easily collect various forms of input in a single function
|
158
|
+
class User(BaseModel):
|
159
|
+
name : str
|
160
|
+
age : int
|
161
|
+
|
162
|
+
# TIP:
|
163
|
+
# you can style this the same way with `print`
|
164
|
+
user = input("Enter some information about yourself: ", schema = User)
|
165
|
+
|
166
|
+
# easily run a collection of prebuilt animations
|
167
|
+
animate("This is a rainbow!", type = "rainbow", duration = 2, refresh_rate = 20)
|
168
|
+
```
|
169
|
+
|
170
|
+
Using the various `hammad.logging` resources, you can both create custom & styled
|
171
|
+
loggers, as well as easily inspect various aspects of your code during runtime.
|
172
|
+
|
173
|
+
```python
|
174
|
+
from hammad.logging import Logger
|
175
|
+
|
176
|
+
# create standard / file based loggers easily
|
177
|
+
logger = Logger("hammad", level = "info", rich = Trues)
|
178
|
+
|
179
|
+
file_logger = Logger("hammad-file", level = "info", file = "hammad.log")
|
180
|
+
|
181
|
+
# log to the console
|
182
|
+
logger.info("This is an info message")
|
183
|
+
|
184
|
+
# Use the various `trace_` methods to run various introspection tasks
|
185
|
+
from hammad.logging import (
|
186
|
+
trace,
|
187
|
+
trace_cls,
|
188
|
+
trace_function,
|
189
|
+
trace_http
|
190
|
+
)
|
191
|
+
```
|
@@ -0,0 +1,110 @@
|
|
1
|
+
hammad/__init__.py,sha256=oFJJe9k2BTTPxkvJwsbr7d_HejtUl9clSsgxsHPU_Mk,3619
|
2
|
+
hammad/_internal.py,sha256=00ZXmXIlE3P_cewYrPsJuO38vYqhHY2XnFzFpzXgoyY,7871
|
3
|
+
hammad/cache/__init__.py,sha256=29vI8UkVITtiEe7fTr9UR5Q0lV7tr_SVe7tLlJmm1Ks,954
|
4
|
+
hammad/cache/base_cache.py,sha256=kYJS2IcQtxhzT7BQBFtOWnhw4VkvAapPhAVkfbW5IeY,6353
|
5
|
+
hammad/cache/cache.py,sha256=bzDXxjSolrSdIxqES2VMfVZZGTk_8k4x9n0AW4tlifs,4621
|
6
|
+
hammad/cache/decorators.py,sha256=olYLK5x4JkxHpA8WIiplI45QYmNIzyGjNMrTKNRCSQg,9599
|
7
|
+
hammad/cache/file_cache.py,sha256=XjLJxM4Ql65OABxz8q1DtA_s8HZQJKywCw6MNVnC6YE,2485
|
8
|
+
hammad/cache/ttl_cache.py,sha256=-0pJ4lkVgg1OIb98bQFub9n6f4zgWVs-dQfKZe_DmpE,2153
|
9
|
+
hammad/cli/__init__.py,sha256=DkBgA8zkdsOmReoPI5dqni5l5DGkaA7TzrIFvmy5MIo,785
|
10
|
+
hammad/cli/_runner.py,sha256=hZVS_hQbxazfdWFog9V1pQeD11XU7pT7H8_Gop8Xd5c,9539
|
11
|
+
hammad/cli/animations.py,sha256=h68OuJBkDiYTLdB5pLPgQ2gpPT2c3dNulkDv2BtKHFA,19507
|
12
|
+
hammad/cli/plugins.py,sha256=433XcqVmNB50_CqeL2_HOziFwacU9tQeluys7ZegZ4s,30802
|
13
|
+
hammad/cli/styles/__init__.py,sha256=Ok7J_uhJgyswNkBWnDw50oTX9Xk1HPksUl3UbmT1qTI,1363
|
14
|
+
hammad/cli/styles/settings.py,sha256=irChf9RsMij3djx_n9D9duoVIzxLCpd9-BlKl6U_OLk,5532
|
15
|
+
hammad/cli/styles/types.py,sha256=vNIeQY_23m10K8qVT7Iy-PMwosGL-La-UAZKszHJjEE,7911
|
16
|
+
hammad/cli/styles/utils.py,sha256=hIpQcDFjyJpRE0gp3RRXVlWfZ83hMGAKD_uQZmAIwrk,28292
|
17
|
+
hammad/data/__init__.py,sha256=5htef4M7fsd0wPuGIT0bpBpHeImYEn8pBsS7SxG4Tkk,1827
|
18
|
+
hammad/data/collections/__init__.py,sha256=xC1DzECEdL6WU01WDu41eAIcVadUGLWctcD_xspdxb4,1045
|
19
|
+
hammad/data/collections/collection.py,sha256=Qg1Kq9nhe6x0U60UXvosVBU08Boxi1qsZZ3SmfqtkT0,10779
|
20
|
+
hammad/data/collections/indexes/__init__.py,sha256=MKwemZ59F1No5deRYpft_Dg6x9yUcz0PC0fvEE7eF9o,959
|
21
|
+
hammad/data/collections/indexes/qdrant/__init__.py,sha256=yFS70aPt9QRYVjRT5hU8_29OqMNMgmujtMyY1vIStBE,48
|
22
|
+
hammad/data/collections/indexes/qdrant/index.py,sha256=KJVON-RDgMJbhTIGvRT6mFIV2cGKLI21g3IZRsMkUGU,26665
|
23
|
+
hammad/data/collections/indexes/qdrant/settings.py,sha256=hr5eXTAbesGHDcseA6whIIAUfWMm7zcvIQbRVMlzBdQ,2505
|
24
|
+
hammad/data/collections/indexes/qdrant/utils.py,sha256=kqLo1yRhpF20L0t1k54PG3BqG8m7sbXqkov_H9FktDA,6576
|
25
|
+
hammad/data/collections/indexes/tantivy/__init__.py,sha256=ugbv5tChrgyM5jN-czXOu5DLsweMgWiqKt5YAKFayDw,45
|
26
|
+
hammad/data/collections/indexes/tantivy/index.py,sha256=m02-NPlnSnKrGysZt8L2BtudFZtthNwo6yKcQzgbaO0,13954
|
27
|
+
hammad/data/collections/indexes/tantivy/settings.py,sha256=ACR67704pqLsTwCvSpLhi52Oun5s9E5LpUH_OrQwlM4,1397
|
28
|
+
hammad/data/collections/indexes/tantivy/utils.py,sha256=fi0EckbRdvLUKSWAAhId8j6JrQ7iI76Y3Ytm3g7udsM,5599
|
29
|
+
hammad/data/configurations/__init__.py,sha256=1vJMpKKItA_aCDtOV7ouNpNAwOXhCJ28H_8dilrAzz0,834
|
30
|
+
hammad/data/configurations/configuration.py,sha256=ijm2FAyQjZ66Jo2RlT5hjCiAZdC9EnnghmR7Pj5z0Gw,17737
|
31
|
+
hammad/data/models/__init__.py,sha256=1s7_qeAA94i0-1wKkfAi4Ee83EZwNaNldJKOvBpPiBE,1172
|
32
|
+
hammad/data/models/fields.py,sha256=6H5SbrXhC0KEge5PJNFqN-Ek8RKxt7-eRKC2E7xmoe8,19180
|
33
|
+
hammad/data/models/model.py,sha256=gBH6fL9TjSYfAyDHuw-VJdTorML62iisokvTlVzOnhY,39128
|
34
|
+
hammad/data/models/utils.py,sha256=KNtr1PlxBizs14gmZqQeG1A7EQ6JHPRrRN0pTr3ucR8,9964
|
35
|
+
hammad/data/models/extensions/__init__.py,sha256=dfVDCMBKZYtaMHJRQBShaoMHFcQ6VJcD_5q5Fcc77mQ,128
|
36
|
+
hammad/data/models/extensions/pydantic/__init__.py,sha256=2ipoelO4knYSug47Vdt0URHtBNCQIFixJ3tTcawaCtE,1205
|
37
|
+
hammad/data/models/extensions/pydantic/converters.py,sha256=_485-4EUQe7-fxlPG2o1wnaU8SDA79AhxMitiUMoIYY,24545
|
38
|
+
hammad/data/sql/__init__.py,sha256=ewHFbnGeqYr2Fs51du5dqepUC98qa4eBSQWnbtuYq40,452
|
39
|
+
hammad/data/sql/database.py,sha256=S2-MCmgYzgtjwFGzFQjVBUxZMrtdvBj9IGZxh_mKnGo,18780
|
40
|
+
hammad/data/sql/types.py,sha256=B89Xu6x0qQCxlRNe8ob-lJAWfHONKCeFUK0TIjyFB5E,3707
|
41
|
+
hammad/data/types/__init__.py,sha256=LeyrRKKBbDP2VaTaNEiyJU_1rs52LofD18WUS8rl5gw,758
|
42
|
+
hammad/data/types/file.py,sha256=l1mXtyxsmbx0P_U_rnjkgc4N_UQBevAESTAZmBc8eVc,11111
|
43
|
+
hammad/data/types/text.py,sha256=rATiwkTsAJ8pWzZ7OBsWX7rDNoKvkeuWsGWd_sbuUaM,33369
|
44
|
+
hammad/data/types/multimodal/__init__.py,sha256=LQzomOVQFYnmkQT7hFIxcM261FDXtV3i0uEHB7GXIwU,427
|
45
|
+
hammad/data/types/multimodal/audio.py,sha256=rn1G1vwDlt4d30ZumzYBeO0f0OhdtIQBJRCaSkyPHRA,2786
|
46
|
+
hammad/data/types/multimodal/image.py,sha256=xp9aWeGkg6FReuFLA63CQ81tv74nFxVtgVjpoDZNjjw,2274
|
47
|
+
hammad/formatting/__init__.py,sha256=CkPXIGHLP7xUfRiIPsqBZUCw98uW5HnD1H7uQXZHl8k,346
|
48
|
+
hammad/formatting/json/__init__.py,sha256=V4uODCUQdptfyw_D96R3XDopw1bgNIR2ogiEG-Z-FtQ,525
|
49
|
+
hammad/formatting/json/converters.py,sha256=usnqYc5N9GHOkTIJKNKiJ3GO9oQo5zYOGmupvJkqUjk,5597
|
50
|
+
hammad/formatting/text/__init__.py,sha256=ZAA7D4pwKFjeUxHsnm21QKSTtQ7Fj8ncO__m5Ry_eHY,1506
|
51
|
+
hammad/formatting/text/converters.py,sha256=g3z-ZGTaKNVbLFFKBSh6qN2Uz0BSkdxCaN3LR9cAyV8,23806
|
52
|
+
hammad/formatting/text/markdown.py,sha256=D17NOoGkoXUBhoOGKelKHwi72iqsAwPU5HEFjRJtLQI,3407
|
53
|
+
hammad/formatting/yaml/__init__.py,sha256=4dBeXPi0jx7ELT2_sC2fUYaiY8b8wFiUScLODc9ISEw,462
|
54
|
+
hammad/formatting/yaml/converters.py,sha256=zvSB8QGb56uvwO0KjXllfTj9g1FmNINOKR06DTjvXw8,153
|
55
|
+
hammad/genai/__init__.py,sha256=tDBxnxcDfa1M2LVGfyj8YnY47yg197aTvW4qWVwTFjM,1952
|
56
|
+
hammad/genai/multimodal_models.py,sha256=nBoc-KiWkeOXotAiYiZRnU9DrbDR7Gex0mgYvt6QTbo,1291
|
57
|
+
hammad/genai/rerank_models.py,sha256=JFiIQ8AuQVoYcFQHR9iuq_tiocwvlIq1bFTWbGF-_T0,434
|
58
|
+
hammad/genai/agents/__init__.py,sha256=AyFkBd70jrLGWa6va1BoiNPutdkwySgeCv_lo97aZB4,25
|
59
|
+
hammad/genai/agents/types/__init__.py,sha256=vrIY5_Z2gYINnd5BO5ZbxKS0mW7aqcTWW_1icYFn1Ew,618
|
60
|
+
hammad/genai/agents/types/history.py,sha256=YN7vudPkhI1mnQgtf12nw-p2xaqxc4rtc9lruo_RWCw,10043
|
61
|
+
hammad/genai/agents/types/tool.py,sha256=EqPaJ2c8z6S5poA-eq8ex6acJ0Vc2_kQ2ePY5triwlU,16780
|
62
|
+
hammad/genai/embedding_models/__init__.py,sha256=GAjlkZjX2tMRKqP6AKY0rokRSiRZRpa4T-NbtpldEfc,1085
|
63
|
+
hammad/genai/embedding_models/embedding_model.py,sha256=9JiJLarsl2PwP_IGPXPU1Vkh6CpQZJVN7y1VAXPYS-U,6968
|
64
|
+
hammad/genai/embedding_models/embedding_model_name.py,sha256=bsHc-3Xx6X5EU6LuiPPlkyZa4W_oTwW4AJhm4hBAs8Y,2504
|
65
|
+
hammad/genai/embedding_models/embedding_model_request.py,sha256=nZyUmUaNHR4OTJXFLDE9BACFJ-D8QMECxcDxtlVWPWg,1562
|
66
|
+
hammad/genai/embedding_models/embedding_model_response.py,sha256=xrHDej5Ic-R-JAyc6LeDqomCL88w-nv3B42cBZIdTnE,1809
|
67
|
+
hammad/genai/embedding_models/run.py,sha256=mq_G5kGkZYf7ZdpCeh7mtyb5GBjrK67065C6R9TgrvY,5083
|
68
|
+
hammad/genai/language_models/__init__.py,sha256=BbIFRpC-z02kvUHmPHP7Yo3wrXUkwPGcskB84N3Qz74,1103
|
69
|
+
hammad/genai/language_models/_streaming.py,sha256=Rmjnhl_QRu1FpaBBSbX8ijZbyqpNKOJxjyGZ1sY_UYw,23884
|
70
|
+
hammad/genai/language_models/_types.py,sha256=9VorMf71rOV5ftBEItsMJmgBocZZPKWrP8yhncA-wd0,8906
|
71
|
+
hammad/genai/language_models/language_model.py,sha256=ZOBJjZd0kpHda9hCUcTlxR7-9WB-ZX5wGGJcMZasthY,28782
|
72
|
+
hammad/genai/language_models/language_model_request.py,sha256=blGgLaZvEfFUVmT2NHPH9OuCQrfhHQhenRk6QLeTWeI,4378
|
73
|
+
hammad/genai/language_models/language_model_response.py,sha256=epq9_kM-KPDoRXWk9SiD07w_i7rOXdCtdOHRGUJgA6g,7709
|
74
|
+
hammad/genai/language_models/language_model_response_chunk.py,sha256=2-hJfW0wSdxXTRKxmYZH97PjC9oiOtghzPt4FhPWXRE,1735
|
75
|
+
hammad/genai/language_models/run.py,sha256=dA7Ws44H0rpB_WAyWIPKoR5XfHva9FjMC1tNYKOh8mk,21239
|
76
|
+
hammad/genai/language_models/_utils/__init__.py,sha256=MjS_wQ5AaGvP806cQ3EboOABHJH3EHkm7Llpdf6uYQM,789
|
77
|
+
hammad/genai/language_models/_utils/_completions.py,sha256=nDPMKrIjiMO2FKrxbLgOc4oitiVcAk-c3iVDXKLb3PY,3777
|
78
|
+
hammad/genai/language_models/_utils/_messages.py,sha256=WupMWUbEC_QDuDp3ML-AfbCqK8HBRGptn3PqX7ywA0Y,2684
|
79
|
+
hammad/genai/language_models/_utils/_requests.py,sha256=_-6wK-3nkHYiVMEN2yxDur5ALOXeiK5wX96MvCTQS5w,7200
|
80
|
+
hammad/genai/language_models/_utils/_structured_outputs.py,sha256=Uo60SMM6r6SDtdJnh2tmvdgs9znmmpRvzfMgnAkm8zs,3880
|
81
|
+
hammad/logging/__init__.py,sha256=VtskZx0bKEAJ9FHTMflhB1CzeFUxLpDT5HPgcecAXUo,701
|
82
|
+
hammad/logging/decorators.py,sha256=VbI1x3P4ft0-0BGjXq7nQgiuNqcXAA51CGmoSn47iSw,30122
|
83
|
+
hammad/logging/logger.py,sha256=GQ2SvrRe0igWlVExZKS99QtCENtwP9uX-5FbsvUAazY,31475
|
84
|
+
hammad/mcp/__init__.py,sha256=5oTU-BLYjfz6fBHDH9cyWg3DpQ6Qar-jodbCR05SuWo,1123
|
85
|
+
hammad/mcp/client/__init__.py,sha256=i6aAYLoMkm78hOog4OssnT7jgkUXHDBQsdtvDLirSmA,795
|
86
|
+
hammad/mcp/client/client.py,sha256=ZAyeBEZKXg_ft7wirri1R4w4RXlMuet_z0yDuLxH3-M,20637
|
87
|
+
hammad/mcp/client/client_service.py,sha256=quJp02n9tp70l0SJd9jkIuRkdSPeWegzusk-eiV41b0,14990
|
88
|
+
hammad/mcp/client/settings.py,sha256=7bLpJYyiUT_H7zp3SDwLyAt9fmiQwL3L89qVTAZYpi8,5913
|
89
|
+
hammad/mcp/servers/__init__.py,sha256=5S5JrdkzMRmW1iIlZeQOblx7SFj8sTpG6w0tKLZrNMM,583
|
90
|
+
hammad/mcp/servers/launcher.py,sha256=jQDQOqz-cKK2PSEOxoPBCVsBeTABNNjcwTXSWE4-LQA,41606
|
91
|
+
hammad/runtime/__init__.py,sha256=qXmY4zP75nv7tRGDe-AizHB76KfDNdXHafnGQCiho8Y,667
|
92
|
+
hammad/runtime/decorators.py,sha256=5T56nAwwfH0ZKfnLlDGkDNFYaGBBSrH1i4_yX3Dt5GA,4524
|
93
|
+
hammad/runtime/run.py,sha256=VFzoXieSaEg1KlDTTepDIsSyISkWXuxHpNs_AgHX5nM,10802
|
94
|
+
hammad/service/__init__.py,sha256=B7wnQkT8e2kFwaigpAcXI_PJ8jlQzxcgTtDDH1p4KSU,1222
|
95
|
+
hammad/service/create.py,sha256=Z0Vy-nQUKk_zqLuVOKJye6gLdVSU5HNlPgm4irvRgu8,16224
|
96
|
+
hammad/service/decorators.py,sha256=bw-fgnvIjivLjbXUrBxcx-fsEZZI4Evl5zxNnC1HA-o,9940
|
97
|
+
hammad/typing/__init__.py,sha256=P9XCKrn-kxyfSLHpY9vraOLV9vyoBz_DzEm6eIH5xWY,11712
|
98
|
+
hammad/web/__init__.py,sha256=qg1DcwWRtDhRdQKwEiS2I-GT8ftdHhQ_WYpWzldSJ4Y,1053
|
99
|
+
hammad/web/models.py,sha256=LivyMeLnjyRYqCNYzJRu_--IYjOzBiySYXYB9obqlnU,6421
|
100
|
+
hammad/web/utils.py,sha256=o-ys9anLDtOTkqvk0Z8gxc-V0lhp0LB03DHFpoj6Ous,15863
|
101
|
+
hammad/web/http/__init__.py,sha256=jn9Rn7Yg2cypD7duTTNFuW2wQZx9B63Bde4RJJeDYU0,22
|
102
|
+
hammad/web/http/client.py,sha256=LWBSVjvHEuHmOOWq5EUT4zN5w6zSG45bOTk6FiSPHuA,33082
|
103
|
+
hammad/web/openapi/__init__.py,sha256=JhJQ6_laBmB2djIYFc0vgGha2GsdUe4FP1LDdZCQ5J4,25
|
104
|
+
hammad/web/openapi/client.py,sha256=1pXz7KAO_0pN4kQZoWKWskXDYGiJ535TsPO1GGCiC0E,26816
|
105
|
+
hammad/web/search/__init__.py,sha256=e9A6znPIiZCz-4secyHbUs0uUGf5yAqW6wGacgx961U,24
|
106
|
+
hammad/web/search/client.py,sha256=T1--L-EWe8AA9nZPxEehhHTNmWkGCcbQrhZxY84zTYs,36964
|
107
|
+
hammad_python-0.0.16.dist-info/METADATA,sha256=viS2fJ0oeUr6yjSPwlfVzK0_6K_jPtlG5h7uJcPDW9c,6214
|
108
|
+
hammad_python-0.0.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
109
|
+
hammad_python-0.0.16.dist-info/licenses/LICENSE,sha256=h74yFUWjbBaodcWG5wNmm30npjl8obVcxD-1nQfUp2I,1069
|
110
|
+
hammad_python-0.0.16.dist-info/RECORD,,
|