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.
Files changed (122) hide show
  1. hammad/__init__.py +177 -0
  2. hammad/{performance/imports.py → _internal.py} +7 -1
  3. hammad/cache/__init__.py +1 -1
  4. hammad/cli/__init__.py +3 -1
  5. hammad/cli/_runner.py +265 -0
  6. hammad/cli/animations.py +1 -1
  7. hammad/cli/plugins.py +133 -78
  8. hammad/cli/styles/__init__.py +1 -1
  9. hammad/cli/styles/utils.py +149 -3
  10. hammad/data/__init__.py +56 -29
  11. hammad/data/collections/__init__.py +27 -17
  12. hammad/data/collections/collection.py +205 -383
  13. hammad/data/collections/indexes/__init__.py +37 -0
  14. hammad/data/collections/indexes/qdrant/__init__.py +1 -0
  15. hammad/data/collections/indexes/qdrant/index.py +735 -0
  16. hammad/data/collections/indexes/qdrant/settings.py +94 -0
  17. hammad/data/collections/indexes/qdrant/utils.py +220 -0
  18. hammad/data/collections/indexes/tantivy/__init__.py +1 -0
  19. hammad/data/collections/indexes/tantivy/index.py +428 -0
  20. hammad/data/collections/indexes/tantivy/settings.py +51 -0
  21. hammad/data/collections/indexes/tantivy/utils.py +200 -0
  22. hammad/data/configurations/__init__.py +2 -2
  23. hammad/data/configurations/configuration.py +2 -2
  24. hammad/data/models/__init__.py +20 -9
  25. hammad/data/models/extensions/__init__.py +4 -0
  26. hammad/data/models/{pydantic → extensions/pydantic}/__init__.py +6 -19
  27. hammad/data/models/{pydantic → extensions/pydantic}/converters.py +143 -16
  28. hammad/data/models/{base/fields.py → fields.py} +1 -1
  29. hammad/data/models/{base/model.py → model.py} +1 -1
  30. hammad/data/models/{base/utils.py → utils.py} +1 -1
  31. hammad/data/sql/__init__.py +23 -0
  32. hammad/data/sql/database.py +578 -0
  33. hammad/data/sql/types.py +141 -0
  34. hammad/data/types/__init__.py +1 -3
  35. hammad/data/types/file.py +3 -3
  36. hammad/data/types/multimodal/__init__.py +2 -2
  37. hammad/data/types/multimodal/audio.py +2 -2
  38. hammad/data/types/multimodal/image.py +2 -2
  39. hammad/formatting/__init__.py +9 -27
  40. hammad/formatting/json/__init__.py +8 -2
  41. hammad/formatting/json/converters.py +7 -1
  42. hammad/formatting/text/__init__.py +1 -1
  43. hammad/formatting/yaml/__init__.py +1 -1
  44. hammad/genai/__init__.py +78 -0
  45. hammad/genai/agents/__init__.py +1 -0
  46. hammad/genai/agents/types/__init__.py +35 -0
  47. hammad/genai/agents/types/history.py +277 -0
  48. hammad/genai/agents/types/tool.py +490 -0
  49. hammad/genai/embedding_models/__init__.py +41 -0
  50. hammad/{ai/embeddings/client/litellm_embeddings_client.py → genai/embedding_models/embedding_model.py} +47 -142
  51. hammad/genai/embedding_models/embedding_model_name.py +77 -0
  52. hammad/genai/embedding_models/embedding_model_request.py +65 -0
  53. hammad/{ai/embeddings/types.py → genai/embedding_models/embedding_model_response.py} +3 -3
  54. hammad/genai/embedding_models/run.py +161 -0
  55. hammad/genai/language_models/__init__.py +35 -0
  56. hammad/genai/language_models/_streaming.py +622 -0
  57. hammad/genai/language_models/_types.py +276 -0
  58. hammad/genai/language_models/_utils/__init__.py +31 -0
  59. hammad/genai/language_models/_utils/_completions.py +131 -0
  60. hammad/genai/language_models/_utils/_messages.py +89 -0
  61. hammad/genai/language_models/_utils/_requests.py +202 -0
  62. hammad/genai/language_models/_utils/_structured_outputs.py +124 -0
  63. hammad/genai/language_models/language_model.py +734 -0
  64. hammad/genai/language_models/language_model_request.py +135 -0
  65. hammad/genai/language_models/language_model_response.py +219 -0
  66. hammad/genai/language_models/language_model_response_chunk.py +53 -0
  67. hammad/genai/language_models/run.py +530 -0
  68. hammad/genai/multimodal_models.py +48 -0
  69. hammad/genai/rerank_models.py +26 -0
  70. hammad/logging/__init__.py +1 -1
  71. hammad/logging/decorators.py +1 -1
  72. hammad/logging/logger.py +2 -2
  73. hammad/mcp/__init__.py +1 -1
  74. hammad/mcp/client/__init__.py +35 -0
  75. hammad/mcp/client/client.py +105 -4
  76. hammad/mcp/client/client_service.py +10 -3
  77. hammad/mcp/servers/__init__.py +24 -0
  78. hammad/{performance/runtime → runtime}/__init__.py +2 -2
  79. hammad/{performance/runtime → runtime}/decorators.py +1 -1
  80. hammad/{performance/runtime → runtime}/run.py +1 -1
  81. hammad/service/__init__.py +1 -1
  82. hammad/service/create.py +3 -8
  83. hammad/service/decorators.py +8 -8
  84. hammad/typing/__init__.py +28 -0
  85. hammad/web/__init__.py +3 -3
  86. hammad/web/http/client.py +1 -1
  87. hammad/web/models.py +53 -21
  88. hammad/web/search/client.py +99 -52
  89. hammad/web/utils.py +13 -13
  90. hammad_python-0.0.16.dist-info/METADATA +191 -0
  91. hammad_python-0.0.16.dist-info/RECORD +110 -0
  92. hammad/ai/__init__.py +0 -1
  93. hammad/ai/_utils.py +0 -142
  94. hammad/ai/completions/__init__.py +0 -45
  95. hammad/ai/completions/client.py +0 -684
  96. hammad/ai/completions/create.py +0 -710
  97. hammad/ai/completions/settings.py +0 -100
  98. hammad/ai/completions/types.py +0 -792
  99. hammad/ai/completions/utils.py +0 -486
  100. hammad/ai/embeddings/__init__.py +0 -35
  101. hammad/ai/embeddings/client/__init__.py +0 -1
  102. hammad/ai/embeddings/client/base_embeddings_client.py +0 -26
  103. hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +0 -200
  104. hammad/ai/embeddings/create.py +0 -159
  105. hammad/data/collections/base_collection.py +0 -58
  106. hammad/data/collections/searchable_collection.py +0 -556
  107. hammad/data/collections/vector_collection.py +0 -596
  108. hammad/data/databases/__init__.py +0 -21
  109. hammad/data/databases/database.py +0 -902
  110. hammad/data/models/base/__init__.py +0 -35
  111. hammad/data/models/pydantic/models/__init__.py +0 -28
  112. hammad/data/models/pydantic/models/arbitrary_model.py +0 -46
  113. hammad/data/models/pydantic/models/cacheable_model.py +0 -79
  114. hammad/data/models/pydantic/models/fast_model.py +0 -318
  115. hammad/data/models/pydantic/models/function_model.py +0 -176
  116. hammad/data/models/pydantic/models/subscriptable_model.py +0 -63
  117. hammad/performance/__init__.py +0 -36
  118. hammad/py.typed +0 -0
  119. hammad_python-0.0.14.dist-info/METADATA +0 -70
  120. hammad_python-0.0.14.dist-info/RECORD +0 -99
  121. {hammad_python-0.0.14.dist-info → hammad_python-0.0.16.dist-info}/WHEEL +0 -0
  122. {hammad_python-0.0.14.dist-info → hammad_python-0.0.16.dist-info}/licenses/LICENSE +0 -0
@@ -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 duckduckgo_search import DDGS
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 `search_web`)
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]search_web[/bold light_salmon3]`[/yellow]"
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.search_web(
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 search_web(
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
- results = list(
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
- return results
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
- results = list(
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
- return results
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
- result = {
311
- "url": url,
312
- "status_code": response.status_code,
313
- "content_type": response.headers.get("content-type", ""),
314
- "title": "",
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
- result["title"] = title_node.text(strip=True)
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
- result["text"] = " ".join(
362
+ text = " ".join(
331
363
  node.text(strip=True) for node in selected_nodes
332
364
  )
333
365
  else:
334
- result["text"] = parser.text(strip=True)
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
- result["links"] = [
340
- {
341
- "href": node.attrs.get("href", ""),
342
- "text": node.text(strip=True),
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
- result["images"] = [
352
- {
353
- "src": node.attrs.get("src", ""),
354
- "alt": node.attrs.get("alt", ""),
355
- "title": node.attrs.get("title", ""),
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
- result["selected_elements"] = [
365
- {
366
- "tag": node.tag,
367
- "text": node.text(strip=True),
368
- "html": node.html,
369
- "attributes": dict(node.attributes),
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 result
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 results
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
- "href": absolute_href,
549
- "original_href": href,
550
- "text": node.text(strip=True),
551
- "title": node.attrs.get("title", ""),
552
- "type": link_type,
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 links
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 search_web(
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.search_web(
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
- "search_web",
20
+ "run_web_search",
21
21
  "read_web_page",
22
22
  "read_web_pages",
23
- "search_news",
24
- "extract_page_links",
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 search_web(
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 _search_web_async():
285
+ async def _run_web_search_async():
286
286
  client = _get_search_client()
287
- return await client.search_web(
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(_search_web_async())
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 search_news(
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 _search_news_async():
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(_search_news_async())
427
+ return asyncio.run(_run_news_search_async())
428
428
 
429
429
 
430
- def extract_page_links(
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 _extract_page_links_async():
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(_extract_page_links_async())
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,,