hammad-python 0.0.11__py3-none-any.whl → 0.0.13__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 +169 -56
- hammad/_core/__init__.py +1 -0
- hammad/_core/_utils/__init__.py +4 -0
- hammad/_core/_utils/_import_utils.py +182 -0
- hammad/ai/__init__.py +59 -0
- hammad/ai/_utils.py +142 -0
- hammad/ai/completions/__init__.py +44 -0
- hammad/ai/completions/client.py +729 -0
- hammad/ai/completions/create.py +686 -0
- hammad/ai/completions/types.py +711 -0
- hammad/ai/completions/utils.py +374 -0
- hammad/ai/embeddings/__init__.py +35 -0
- hammad/ai/embeddings/client/__init__.py +1 -0
- hammad/ai/embeddings/client/base_embeddings_client.py +26 -0
- hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +200 -0
- hammad/ai/embeddings/client/litellm_embeddings_client.py +288 -0
- hammad/ai/embeddings/create.py +159 -0
- hammad/ai/embeddings/types.py +69 -0
- hammad/base/__init__.py +35 -0
- hammad/{based → base}/fields.py +23 -23
- hammad/{based → base}/model.py +124 -14
- hammad/base/utils.py +280 -0
- hammad/cache/__init__.py +30 -12
- hammad/cache/base_cache.py +181 -0
- hammad/cache/cache.py +169 -0
- hammad/cache/decorators.py +261 -0
- hammad/cache/file_cache.py +80 -0
- hammad/cache/ttl_cache.py +74 -0
- hammad/cli/__init__.py +10 -2
- hammad/cli/{styles/animations.py → animations.py} +79 -23
- hammad/cli/{plugins/__init__.py → plugins.py} +85 -90
- hammad/cli/styles/__init__.py +50 -0
- hammad/cli/styles/settings.py +4 -0
- hammad/configuration/__init__.py +35 -0
- hammad/{data/types/files → configuration}/configuration.py +96 -7
- hammad/data/__init__.py +14 -26
- hammad/data/collections/__init__.py +4 -2
- hammad/data/collections/collection.py +300 -75
- hammad/data/collections/vector_collection.py +118 -12
- hammad/data/databases/__init__.py +2 -2
- hammad/data/databases/database.py +383 -32
- hammad/json/__init__.py +2 -2
- hammad/logging/__init__.py +13 -5
- hammad/logging/decorators.py +404 -2
- hammad/logging/logger.py +442 -22
- hammad/multimodal/__init__.py +24 -0
- hammad/{data/types/files → multimodal}/audio.py +21 -6
- hammad/{data/types/files → multimodal}/image.py +5 -5
- hammad/multithreading/__init__.py +304 -0
- hammad/pydantic/__init__.py +2 -2
- hammad/pydantic/converters.py +1 -1
- hammad/pydantic/models/__init__.py +2 -2
- hammad/text/__init__.py +59 -14
- hammad/text/converters.py +723 -0
- hammad/text/{utils/markdown/formatting.py → markdown.py} +25 -23
- hammad/text/text.py +12 -14
- hammad/types/__init__.py +11 -0
- hammad/{data/types/files → types}/file.py +18 -18
- hammad/typing/__init__.py +138 -84
- hammad/web/__init__.py +3 -2
- hammad/web/models.py +245 -0
- hammad/web/search/client.py +75 -23
- hammad/web/utils.py +14 -5
- hammad/yaml/__init__.py +2 -2
- hammad/yaml/converters.py +1 -1
- {hammad_python-0.0.11.dist-info → hammad_python-0.0.13.dist-info}/METADATA +4 -1
- hammad_python-0.0.13.dist-info/RECORD +85 -0
- hammad/based/__init__.py +0 -52
- hammad/based/utils.py +0 -455
- hammad/cache/_cache.py +0 -746
- hammad/data/types/__init__.py +0 -33
- hammad/data/types/files/__init__.py +0 -1
- hammad/data/types/files/document.py +0 -195
- hammad/text/utils/__init__.py +0 -1
- hammad/text/utils/converters.py +0 -229
- hammad/text/utils/markdown/__init__.py +0 -1
- hammad/text/utils/markdown/converters.py +0 -506
- hammad_python-0.0.11.dist-info/RECORD +0 -65
- {hammad_python-0.0.11.dist-info → hammad_python-0.0.13.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.11.dist-info → hammad_python-0.0.13.dist-info}/licenses/LICENSE +0 -0
hammad/web/models.py
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
"""hammad.web.models
|
2
|
+
|
3
|
+
Output models for web search and parsing functionality.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
from typing import List, Dict, Any, Optional, Union
|
9
|
+
from typing_extensions import TypedDict, NotRequired
|
10
|
+
|
11
|
+
|
12
|
+
# -----------------------------------------------------------------------------
|
13
|
+
# Search Result Models
|
14
|
+
# -----------------------------------------------------------------------------
|
15
|
+
|
16
|
+
|
17
|
+
class SearchResult(TypedDict):
|
18
|
+
"""DuckDuckGo web search result."""
|
19
|
+
|
20
|
+
title: str
|
21
|
+
"""Title of the search result."""
|
22
|
+
|
23
|
+
href: str
|
24
|
+
"""URL of the search result."""
|
25
|
+
|
26
|
+
body: str
|
27
|
+
"""Description/snippet of the search result."""
|
28
|
+
|
29
|
+
|
30
|
+
class NewsResult(TypedDict):
|
31
|
+
"""DuckDuckGo news search result."""
|
32
|
+
|
33
|
+
date: str
|
34
|
+
"""Publication date of the news article."""
|
35
|
+
|
36
|
+
title: str
|
37
|
+
"""Title of the news article."""
|
38
|
+
|
39
|
+
body: str
|
40
|
+
"""Description/snippet of the news article."""
|
41
|
+
|
42
|
+
url: str
|
43
|
+
"""URL of the news article."""
|
44
|
+
|
45
|
+
image: str
|
46
|
+
"""Image URL associated with the news article."""
|
47
|
+
|
48
|
+
source: str
|
49
|
+
"""Source/publisher of the news article."""
|
50
|
+
|
51
|
+
|
52
|
+
# -----------------------------------------------------------------------------
|
53
|
+
# Web Page Parsing Models
|
54
|
+
# -----------------------------------------------------------------------------
|
55
|
+
|
56
|
+
|
57
|
+
class LinkInfo(TypedDict):
|
58
|
+
"""Information about a link extracted from a web page."""
|
59
|
+
|
60
|
+
href: str
|
61
|
+
"""Absolute URL of the link."""
|
62
|
+
|
63
|
+
text: str
|
64
|
+
"""Text content of the link."""
|
65
|
+
|
66
|
+
|
67
|
+
class ImageInfo(TypedDict):
|
68
|
+
"""Information about an image extracted from a web page."""
|
69
|
+
|
70
|
+
src: str
|
71
|
+
"""Source URL of the image."""
|
72
|
+
|
73
|
+
alt: str
|
74
|
+
"""Alt text of the image."""
|
75
|
+
|
76
|
+
title: str
|
77
|
+
"""Title attribute of the image."""
|
78
|
+
|
79
|
+
|
80
|
+
class SelectedElement(TypedDict):
|
81
|
+
"""Information about a selected element from CSS selector."""
|
82
|
+
|
83
|
+
tag: str
|
84
|
+
"""HTML tag name of the element."""
|
85
|
+
|
86
|
+
text: str
|
87
|
+
"""Text content of the element."""
|
88
|
+
|
89
|
+
html: str
|
90
|
+
"""HTML content of the element."""
|
91
|
+
|
92
|
+
attributes: Dict[str, str]
|
93
|
+
"""Attributes of the element."""
|
94
|
+
|
95
|
+
|
96
|
+
class WebPageResult(TypedDict):
|
97
|
+
"""Result from parsing a single web page."""
|
98
|
+
|
99
|
+
url: str
|
100
|
+
"""URL of the parsed page."""
|
101
|
+
|
102
|
+
status_code: int
|
103
|
+
"""HTTP status code of the response."""
|
104
|
+
|
105
|
+
content_type: str
|
106
|
+
"""Content-Type header from the response."""
|
107
|
+
|
108
|
+
title: str
|
109
|
+
"""Title of the web page."""
|
110
|
+
|
111
|
+
text: str
|
112
|
+
"""Extracted text content of the page."""
|
113
|
+
|
114
|
+
links: List[LinkInfo]
|
115
|
+
"""List of links found on the page."""
|
116
|
+
|
117
|
+
images: List[ImageInfo]
|
118
|
+
"""List of images found on the page."""
|
119
|
+
|
120
|
+
selected_elements: List[SelectedElement]
|
121
|
+
"""List of elements matching the CSS selector."""
|
122
|
+
|
123
|
+
|
124
|
+
class WebPageErrorResult(TypedDict):
|
125
|
+
"""Result from a failed web page parsing attempt."""
|
126
|
+
|
127
|
+
url: str
|
128
|
+
"""URL that failed to be parsed."""
|
129
|
+
|
130
|
+
error: str
|
131
|
+
"""Error message describing what went wrong."""
|
132
|
+
|
133
|
+
status_code: None
|
134
|
+
"""Always None for error results."""
|
135
|
+
|
136
|
+
content_type: str
|
137
|
+
"""Always empty string for error results."""
|
138
|
+
|
139
|
+
title: str
|
140
|
+
"""Always empty string for error results."""
|
141
|
+
|
142
|
+
text: str
|
143
|
+
"""Always empty string for error results."""
|
144
|
+
|
145
|
+
links: List[LinkInfo]
|
146
|
+
"""Always empty list for error results."""
|
147
|
+
|
148
|
+
images: List[ImageInfo]
|
149
|
+
"""Always empty list for error results."""
|
150
|
+
|
151
|
+
selected_elements: List[SelectedElement]
|
152
|
+
"""Always empty list for error results."""
|
153
|
+
|
154
|
+
|
155
|
+
# -----------------------------------------------------------------------------
|
156
|
+
# Enhanced Link Models
|
157
|
+
# -----------------------------------------------------------------------------
|
158
|
+
|
159
|
+
|
160
|
+
class ExtractedLink(TypedDict):
|
161
|
+
"""Information about a link extracted with classification."""
|
162
|
+
|
163
|
+
href: str
|
164
|
+
"""Absolute URL of the link."""
|
165
|
+
|
166
|
+
original_href: str
|
167
|
+
"""Original href attribute value (may be relative)."""
|
168
|
+
|
169
|
+
text: str
|
170
|
+
"""Text content of the link."""
|
171
|
+
|
172
|
+
title: str
|
173
|
+
"""Title attribute of the link."""
|
174
|
+
|
175
|
+
type: str
|
176
|
+
"""Type of link: 'internal' or 'external'."""
|
177
|
+
|
178
|
+
|
179
|
+
# -----------------------------------------------------------------------------
|
180
|
+
# HTTP Request Models
|
181
|
+
# -----------------------------------------------------------------------------
|
182
|
+
|
183
|
+
|
184
|
+
class HttpResponse(TypedDict):
|
185
|
+
"""HTTP response from web requests."""
|
186
|
+
|
187
|
+
status_code: int
|
188
|
+
"""HTTP status code."""
|
189
|
+
|
190
|
+
headers: Dict[str, str]
|
191
|
+
"""Response headers."""
|
192
|
+
|
193
|
+
content: Union[str, bytes]
|
194
|
+
"""Response content."""
|
195
|
+
|
196
|
+
url: str
|
197
|
+
"""Final URL after redirects."""
|
198
|
+
|
199
|
+
elapsed: float
|
200
|
+
"""Time elapsed for the request in seconds."""
|
201
|
+
|
202
|
+
json: NotRequired[Optional[Dict[str, Any]]]
|
203
|
+
"""Parsed JSON content if Content-Type is JSON."""
|
204
|
+
|
205
|
+
text: NotRequired[str]
|
206
|
+
"""Text content if response is text-based."""
|
207
|
+
|
208
|
+
|
209
|
+
# -----------------------------------------------------------------------------
|
210
|
+
# Batch Operation Models
|
211
|
+
# -----------------------------------------------------------------------------
|
212
|
+
|
213
|
+
|
214
|
+
WebPageResults = List[Union[WebPageResult, WebPageErrorResult]]
|
215
|
+
"""Results from batch web page parsing operations."""
|
216
|
+
|
217
|
+
SearchResults = List[SearchResult]
|
218
|
+
"""Results from web search operations."""
|
219
|
+
|
220
|
+
NewsResults = List[NewsResult]
|
221
|
+
"""Results from news search operations."""
|
222
|
+
|
223
|
+
ExtractedLinks = List[ExtractedLink]
|
224
|
+
"""Results from link extraction operations."""
|
225
|
+
|
226
|
+
|
227
|
+
__all__ = (
|
228
|
+
# Search models
|
229
|
+
"SearchResult",
|
230
|
+
"NewsResult",
|
231
|
+
"SearchResults",
|
232
|
+
"NewsResults",
|
233
|
+
# Web page models
|
234
|
+
"LinkInfo",
|
235
|
+
"ImageInfo",
|
236
|
+
"SelectedElement",
|
237
|
+
"WebPageResult",
|
238
|
+
"WebPageErrorResult",
|
239
|
+
"WebPageResults",
|
240
|
+
# Link extraction models
|
241
|
+
"ExtractedLink",
|
242
|
+
"ExtractedLinks",
|
243
|
+
# HTTP models
|
244
|
+
"HttpResponse",
|
245
|
+
)
|
hammad/web/search/client.py
CHANGED
@@ -16,6 +16,15 @@ from tenacity import (
|
|
16
16
|
before_sleep_log,
|
17
17
|
)
|
18
18
|
|
19
|
+
from ..models import (
|
20
|
+
SearchResults,
|
21
|
+
NewsResults,
|
22
|
+
WebPageResult,
|
23
|
+
WebPageErrorResult,
|
24
|
+
WebPageResults,
|
25
|
+
ExtractedLinks,
|
26
|
+
)
|
27
|
+
|
19
28
|
__all__ = ("AsyncSearchClient", "SearchClient", "create_search_client")
|
20
29
|
|
21
30
|
|
@@ -90,6 +99,49 @@ class AsyncSearchClient:
|
|
90
99
|
headers.update(self.default_headers)
|
91
100
|
return headers
|
92
101
|
|
102
|
+
async def search(
|
103
|
+
self,
|
104
|
+
query: str,
|
105
|
+
*,
|
106
|
+
max_results: int = 10,
|
107
|
+
region: str = "wt-wt",
|
108
|
+
safesearch: Literal["on", "moderate", "off"] = "moderate",
|
109
|
+
timelimit: Optional[Literal["d", "w", "m", "y"]] = None,
|
110
|
+
backend: Literal["auto", "html", "lite"] = "auto",
|
111
|
+
max_retries: Optional[int] = None,
|
112
|
+
) -> SearchResults:
|
113
|
+
"""
|
114
|
+
(deprecated in favor of `search_web`)
|
115
|
+
|
116
|
+
Args:
|
117
|
+
query: Search query string
|
118
|
+
max_results: Maximum number of results to return (default: 10)
|
119
|
+
region: Search region (default: "wt-wt" for worldwide)
|
120
|
+
safesearch: Safe search setting (default: "moderate")
|
121
|
+
timelimit: Time limit for results (d=day, w=week, m=month, y=year)
|
122
|
+
backend: Search backend to use (default: "auto")
|
123
|
+
max_retries: Maximum number of retry attempts (uses instance default if not provided)
|
124
|
+
|
125
|
+
Returns:
|
126
|
+
List of search result dictionaries with 'title', 'href', and 'body' keys
|
127
|
+
|
128
|
+
Raises:
|
129
|
+
ValueError: If query is empty
|
130
|
+
Exception: If search fails after all retries
|
131
|
+
"""
|
132
|
+
from rich import print
|
133
|
+
|
134
|
+
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]"
|
136
|
+
)
|
137
|
+
return await self.search_web(
|
138
|
+
query,
|
139
|
+
max_results=max_results,
|
140
|
+
region=region,
|
141
|
+
safesearch=safesearch,
|
142
|
+
timelimit=timelimit,
|
143
|
+
)
|
144
|
+
|
93
145
|
async def search_web(
|
94
146
|
self,
|
95
147
|
query: str,
|
@@ -100,7 +152,7 @@ class AsyncSearchClient:
|
|
100
152
|
timelimit: Optional[Literal["d", "w", "m", "y"]] = None,
|
101
153
|
backend: Literal["auto", "html", "lite"] = "auto",
|
102
154
|
max_retries: Optional[int] = None,
|
103
|
-
) ->
|
155
|
+
) -> SearchResults:
|
104
156
|
"""
|
105
157
|
Search the web using DuckDuckGo search.
|
106
158
|
|
@@ -158,7 +210,7 @@ class AsyncSearchClient:
|
|
158
210
|
safesearch: Literal["on", "moderate", "off"] = "moderate",
|
159
211
|
timelimit: Optional[Literal["d", "w", "m"]] = None,
|
160
212
|
max_retries: Optional[int] = None,
|
161
|
-
) ->
|
213
|
+
) -> NewsResults:
|
162
214
|
"""
|
163
215
|
Search for news using DuckDuckGo news search.
|
164
216
|
|
@@ -216,7 +268,7 @@ class AsyncSearchClient:
|
|
216
268
|
extract_images: bool = False,
|
217
269
|
css_selector: Optional[str] = None,
|
218
270
|
max_retries: Optional[int] = None,
|
219
|
-
) ->
|
271
|
+
) -> WebPageResult:
|
220
272
|
"""
|
221
273
|
Read and parse a single web page using selectolax.
|
222
274
|
|
@@ -342,7 +394,7 @@ class AsyncSearchClient:
|
|
342
394
|
css_selector: Optional[str] = None,
|
343
395
|
max_concurrent: Optional[int] = None,
|
344
396
|
max_retries: Optional[int] = None,
|
345
|
-
) ->
|
397
|
+
) -> WebPageResults:
|
346
398
|
"""
|
347
399
|
Read and parse multiple web pages concurrently using selectolax.
|
348
400
|
|
@@ -392,17 +444,17 @@ class AsyncSearchClient:
|
|
392
444
|
max_retries=max_retries,
|
393
445
|
)
|
394
446
|
except Exception as e:
|
395
|
-
return
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
447
|
+
return WebPageErrorResult(
|
448
|
+
url=url,
|
449
|
+
error=str(e),
|
450
|
+
status_code=None,
|
451
|
+
content_type="",
|
452
|
+
title="",
|
453
|
+
text="",
|
454
|
+
links=[],
|
455
|
+
images=[],
|
456
|
+
selected_elements=[],
|
457
|
+
)
|
406
458
|
|
407
459
|
# Execute all requests concurrently
|
408
460
|
tasks = [fetch_page(url) for url in unique_urls]
|
@@ -421,7 +473,7 @@ class AsyncSearchClient:
|
|
421
473
|
include_internal: bool = True,
|
422
474
|
base_url: Optional[str] = None,
|
423
475
|
max_retries: Optional[int] = None,
|
424
|
-
) ->
|
476
|
+
) -> ExtractedLinks:
|
425
477
|
"""
|
426
478
|
Extract links from a web page using selectolax.
|
427
479
|
|
@@ -572,7 +624,7 @@ class SearchClient:
|
|
572
624
|
region: str = "wt-wt",
|
573
625
|
safesearch: str = "moderate",
|
574
626
|
backend: str = "api",
|
575
|
-
) ->
|
627
|
+
) -> SearchResults:
|
576
628
|
"""
|
577
629
|
Synchronous web search using DuckDuckGo.
|
578
630
|
|
@@ -631,7 +683,7 @@ class SearchClient:
|
|
631
683
|
include_external: bool = True,
|
632
684
|
timeout: Optional[float] = None,
|
633
685
|
retries: int = 3,
|
634
|
-
) ->
|
686
|
+
) -> ExtractedLinks:
|
635
687
|
"""
|
636
688
|
Synchronously extract links from a web page.
|
637
689
|
|
@@ -667,7 +719,7 @@ class SearchClient:
|
|
667
719
|
timelimit: Optional[Literal["d", "w", "m", "y"]] = None,
|
668
720
|
backend: Literal["auto", "html", "lite"] = "auto",
|
669
721
|
max_retries: Optional[int] = None,
|
670
|
-
) ->
|
722
|
+
) -> SearchResults:
|
671
723
|
"""
|
672
724
|
Synchronously search the web using DuckDuckGo search.
|
673
725
|
|
@@ -708,7 +760,7 @@ class SearchClient:
|
|
708
760
|
safesearch: Literal["on", "moderate", "off"] = "moderate",
|
709
761
|
timelimit: Optional[Literal["d", "w", "m"]] = None,
|
710
762
|
max_retries: Optional[int] = None,
|
711
|
-
) ->
|
763
|
+
) -> NewsResults:
|
712
764
|
"""
|
713
765
|
Synchronously search for news using DuckDuckGo news search.
|
714
766
|
|
@@ -748,7 +800,7 @@ class SearchClient:
|
|
748
800
|
extract_links: bool = False,
|
749
801
|
extract_images: bool = False,
|
750
802
|
css_selector: Optional[str] = None,
|
751
|
-
) ->
|
803
|
+
) -> WebPageResult:
|
752
804
|
"""
|
753
805
|
Synchronously read and parse a single web page using selectolax.
|
754
806
|
|
@@ -791,7 +843,7 @@ class SearchClient:
|
|
791
843
|
extract_images: bool = False,
|
792
844
|
css_selector: Optional[str] = None,
|
793
845
|
max_concurrent: Optional[int] = None,
|
794
|
-
) ->
|
846
|
+
) -> WebPageResults:
|
795
847
|
"""
|
796
848
|
Synchronously read and parse multiple web pages concurrently using selectolax.
|
797
849
|
|
@@ -835,7 +887,7 @@ class SearchClient:
|
|
835
887
|
include_internal: bool = True,
|
836
888
|
include_external: bool = True,
|
837
889
|
base_url: Optional[str] = None,
|
838
|
-
) ->
|
890
|
+
) -> ExtractedLinks:
|
839
891
|
"""
|
840
892
|
Synchronously extract all links from a web page.
|
841
893
|
|
hammad/web/utils.py
CHANGED
@@ -6,6 +6,15 @@ from typing import Any, Dict, Optional, Union, Literal, List, overload, TYPE_CHE
|
|
6
6
|
if TYPE_CHECKING:
|
7
7
|
from .http.client import HttpResponse
|
8
8
|
|
9
|
+
from .models import (
|
10
|
+
SearchResults,
|
11
|
+
NewsResults,
|
12
|
+
WebPageResult,
|
13
|
+
WebPageResults,
|
14
|
+
ExtractedLinks,
|
15
|
+
HttpResponse as HttpResponseModel,
|
16
|
+
)
|
17
|
+
|
9
18
|
__all__ = (
|
10
19
|
"run_web_request",
|
11
20
|
"search_web",
|
@@ -251,7 +260,7 @@ def search_web(
|
|
251
260
|
backend: Literal["auto", "html", "lite"] = "auto",
|
252
261
|
retry_attempts: int = 3,
|
253
262
|
retry_delay: float = 1.0,
|
254
|
-
) ->
|
263
|
+
) -> SearchResults:
|
255
264
|
"""
|
256
265
|
Search the web using DuckDuckGo search.
|
257
266
|
|
@@ -296,7 +305,7 @@ def read_web_page(
|
|
296
305
|
extract_links: bool = False,
|
297
306
|
extract_images: bool = False,
|
298
307
|
css_selector: Optional[str] = None,
|
299
|
-
) ->
|
308
|
+
) -> WebPageResult:
|
300
309
|
"""
|
301
310
|
Read and parse a single web page using selectolax.
|
302
311
|
|
@@ -342,7 +351,7 @@ def read_web_pages(
|
|
342
351
|
extract_images: bool = False,
|
343
352
|
css_selector: Optional[str] = None,
|
344
353
|
max_concurrent: int = 5,
|
345
|
-
) ->
|
354
|
+
) -> WebPageResults:
|
346
355
|
"""
|
347
356
|
Read and parse multiple web pages concurrently using selectolax.
|
348
357
|
|
@@ -386,7 +395,7 @@ def search_news(
|
|
386
395
|
region: str = "wt-wt",
|
387
396
|
safesearch: Literal["on", "moderate", "off"] = "moderate",
|
388
397
|
timelimit: Optional[Literal["d", "w", "m"]] = None,
|
389
|
-
) ->
|
398
|
+
) -> NewsResults:
|
390
399
|
"""
|
391
400
|
Search for news using DuckDuckGo news search.
|
392
401
|
|
@@ -427,7 +436,7 @@ def extract_page_links(
|
|
427
436
|
include_external: bool = True,
|
428
437
|
include_internal: bool = True,
|
429
438
|
base_url: Optional[str] = None,
|
430
|
-
) ->
|
439
|
+
) -> ExtractedLinks:
|
431
440
|
"""
|
432
441
|
Extract links from a web page using selectolax.
|
433
442
|
|
hammad/yaml/__init__.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Simply extends the `msgspec.yaml` submodule."""
|
4
4
|
|
5
5
|
from typing import TYPE_CHECKING
|
6
|
-
from ..
|
6
|
+
from .._core._utils._import_utils import _auto_create_getattr_loader
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
9
|
from .converters import (
|
@@ -22,7 +22,7 @@ __all__ = (
|
|
22
22
|
)
|
23
23
|
|
24
24
|
|
25
|
-
__getattr__ =
|
25
|
+
__getattr__ = _auto_create_getattr_loader(__all__)
|
26
26
|
|
27
27
|
|
28
28
|
def __dir__() -> list[str]:
|
hammad/yaml/converters.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
"""hammad.yaml.converters"""
|
2
2
|
|
3
3
|
from msgspec.yaml import encode as encode_yaml, decode as decode_yaml
|
4
|
-
from ..
|
4
|
+
from ..configuration.configuration import Configuration as Yaml
|
5
5
|
|
6
6
|
__all__ = ("encode_yaml", "decode_yaml", "read_yaml_file", "Yaml")
|
7
7
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hammad-python
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.13
|
4
4
|
Summary: hammad - *Nightly* hyper-fast opinionated resources and modules built for quick development.
|
5
5
|
Author-email: Hammad Saeed <hammadaidev@gmail.com>
|
6
6
|
License-File: LICENSE
|
@@ -15,6 +15,7 @@ Requires-Dist: python-dotenv>=1.1.0
|
|
15
15
|
Requires-Dist: pyyaml>=6.0.2
|
16
16
|
Requires-Dist: rich>=13.9.4
|
17
17
|
Requires-Dist: selectolax>=0.3.30
|
18
|
+
Requires-Dist: sqlalchemy>=2.0.41
|
18
19
|
Requires-Dist: tantivy>=0.24.0
|
19
20
|
Requires-Dist: tenacity>=9.0.0
|
20
21
|
Requires-Dist: typing-inspect>=0.9.0
|
@@ -24,6 +25,8 @@ Requires-Dist: instructor>=1.9.0; extra == 'ai'
|
|
24
25
|
Requires-Dist: litellm>=1.72.4; extra == 'ai'
|
25
26
|
Requires-Dist: openai-agents>=0.0.19; extra == 'ai'
|
26
27
|
Requires-Dist: qdrant-client>=1.14.3; extra == 'ai'
|
28
|
+
Provides-Extra: fastembed
|
29
|
+
Requires-Dist: fastembed; extra == 'fastembed'
|
27
30
|
Provides-Extra: serve
|
28
31
|
Requires-Dist: fastapi>=0.115.8; extra == 'serve'
|
29
32
|
Requires-Dist: python-multipart>=0.0.19; extra == 'serve'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
hammad/__init__.py,sha256=q812SgfUvft8HbB1HLDfuBgt0dBpnTnHc1uprM3HOec,3962
|
2
|
+
hammad/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
hammad/_core/__init__.py,sha256=AOFUkG80nF2WSgQQSdFE_kehH77gBskKYrzKSNogi8Q,19
|
4
|
+
hammad/_core/_utils/__init__.py,sha256=pqNuAShC-0BJ4td85wrwSfXk7zOo1RFde-oO3VUA_iQ,133
|
5
|
+
hammad/_core/_utils/_import_utils.py,sha256=uO1XWolUV8Zcu1ZVeTAr6-_Zvwwvxjxew-te968kP0E,6048
|
6
|
+
hammad/ai/__init__.py,sha256=vfIDw17dy4ZKL44U7iz4-R5OzUQJFtQs1tAdWaNOWpI,1380
|
7
|
+
hammad/ai/_utils.py,sha256=axsCHv66zfjjhlEbxaF_049fClHjQgHtUReXs8nsMwc,3950
|
8
|
+
hammad/ai/completions/__init__.py,sha256=7JiR29M-AI5XOcD5lY85GolJcb0B6Jm67I7bbCz6n0g,1058
|
9
|
+
hammad/ai/completions/client.py,sha256=ulobB3PTY-hY7JTgMyqiguKhKTE8EivSDW_P1_6H3J8,27387
|
10
|
+
hammad/ai/completions/create.py,sha256=jXqBzZ0-K9BzVQX4X70sN8WYYnbcJL_1ZJelgDYd0fw,29970
|
11
|
+
hammad/ai/completions/types.py,sha256=9kD_eiZHZ52lKt72y4Nnfb9PmY7jWhq9Ncv5x4spRRI,25575
|
12
|
+
hammad/ai/completions/utils.py,sha256=Y9GVl_buljRDrbG0THG9398jJKy4wZc689D4PHiWfJc,13138
|
13
|
+
hammad/ai/embeddings/__init__.py,sha256=4KduX3CTfYG8acp9Smhvqhf_24o4eCZsq4c85fE1IXI,1105
|
14
|
+
hammad/ai/embeddings/create.py,sha256=voVD6WLvoyIgqIMYOmJKJFxUho8ZIl0YDfbgM4X6B6w,6590
|
15
|
+
hammad/ai/embeddings/types.py,sha256=O6MgrGl6431-cH5sRLyNz7BXIehVyfpMDqrCe4wHxyA,1761
|
16
|
+
hammad/ai/embeddings/client/__init__.py,sha256=F2SO89Q6xOYQWNfvAONBJdDLoXIsCxON6I1BxpjEkGQ,34
|
17
|
+
hammad/ai/embeddings/client/base_embeddings_client.py,sha256=EMT8jDMa0TKIV9XA9Tx9ze7eJ882OuCLL9KucI2EezQ,600
|
18
|
+
hammad/ai/embeddings/client/fastembed_text_embeddings_client.py,sha256=814inmH6YgA8mi0hSBKT2P-sCALaiotWNzlsMewQ-Z0,6945
|
19
|
+
hammad/ai/embeddings/client/litellm_embeddings_client.py,sha256=7aFspROjacnAA79jm7f0stzlSi4EHwEgZqI7Im2gNic,10031
|
20
|
+
hammad/base/__init__.py,sha256=PooFQh69XNCeySLj2bfAuwn5xMI2kesl3WjRmsxukiw,818
|
21
|
+
hammad/base/fields.py,sha256=n02Qqq1AkcxwGCGEjcBSu63uWSkcyfxisATr7nwc7DA,19173
|
22
|
+
hammad/base/model.py,sha256=_qyJ3IRJTwRXqZsYMpuYP8FTbMfLgh75VbTrTt1Wqx8,39121
|
23
|
+
hammad/base/utils.py,sha256=kmdWqDcCTB7y4w5pdAfyrOfpzqj1hjKILIklAwbvNxM,9957
|
24
|
+
hammad/cache/__init__.py,sha256=W5CK3JvbfHzS_-KmGIS_ZtjnXuXRjWGmSKaT2eeftEE,1104
|
25
|
+
hammad/cache/base_cache.py,sha256=kYJS2IcQtxhzT7BQBFtOWnhw4VkvAapPhAVkfbW5IeY,6353
|
26
|
+
hammad/cache/cache.py,sha256=bzDXxjSolrSdIxqES2VMfVZZGTk_8k4x9n0AW4tlifs,4621
|
27
|
+
hammad/cache/decorators.py,sha256=olYLK5x4JkxHpA8WIiplI45QYmNIzyGjNMrTKNRCSQg,9599
|
28
|
+
hammad/cache/file_cache.py,sha256=XjLJxM4Ql65OABxz8q1DtA_s8HZQJKywCw6MNVnC6YE,2485
|
29
|
+
hammad/cache/ttl_cache.py,sha256=-0pJ4lkVgg1OIb98bQFub9n6f4zgWVs-dQfKZe_DmpE,2153
|
30
|
+
hammad/cli/__init__.py,sha256=81UslbyYQ3-2tJNYQv1pHe5R0_nufAAo6ktpDeuEskQ,758
|
31
|
+
hammad/cli/animations.py,sha256=_ILMhyT_02FlLMhROe6br0Fhz2EVEwgOyKHY55qWsJY,20541
|
32
|
+
hammad/cli/plugins.py,sha256=61cljGF_V03_6xrBhO0tR-rrlgB44veHh5HXcxMTM3Y,26932
|
33
|
+
hammad/cli/styles/__init__.py,sha256=4HE20exLpIQgPGFt6KnCbjiYaK95fXvFJBGGjJZTwMM,1388
|
34
|
+
hammad/cli/styles/settings.py,sha256=irChf9RsMij3djx_n9D9duoVIzxLCpd9-BlKl6U_OLk,5532
|
35
|
+
hammad/cli/styles/types.py,sha256=vNIeQY_23m10K8qVT7Iy-PMwosGL-La-UAZKszHJjEE,7911
|
36
|
+
hammad/cli/styles/utils.py,sha256=BGFwQIEJHWlTAXed8ZxHeI_phLfEdh-_Mok2fe-jn7g,19356
|
37
|
+
hammad/configuration/__init__.py,sha256=d1ztew6E-7SsJa_yiBOfXULRAnuFcCCel_MkyrDajXs,852
|
38
|
+
hammad/configuration/configuration.py,sha256=Ssty95LALoS9QiviZByXHGyMMe43m63un-Ycz4DFeNw,17732
|
39
|
+
hammad/data/__init__.py,sha256=1PzfRx0bsv0AYkGlssCHxWE4zjSpnSTK_tG3uy6RZ-4,884
|
40
|
+
hammad/data/collections/__init__.py,sha256=jOl1B1avTYhrHuKi27Iq2n48CDTG9Id8W2xMagEiJ6I,838
|
41
|
+
hammad/data/collections/base_collection.py,sha256=ZRht7OZjLIT8GxNvMgNxTarbCTY6EUUurEkGHZ3Rsy4,1419
|
42
|
+
hammad/data/collections/collection.py,sha256=MWjyY3YqZa3U9WH3Br8v-Q_FLP5XWf3p0lIMGzfIeJ4,15758
|
43
|
+
hammad/data/collections/searchable_collection.py,sha256=vCV_JgMwB57QRi4Cri6dfEUzLCyTBN58_JfWEKL2h_0,21361
|
44
|
+
hammad/data/collections/vector_collection.py,sha256=f7GIbJdElmIzqcApcCCxmbXgAXng2EY20n2ttBopwE0,21129
|
45
|
+
hammad/data/databases/__init__.py,sha256=hPg0ujYlS6cqrNsI5CMqTtXWivXPuxm3nyY7_q63nxs,425
|
46
|
+
hammad/data/databases/database.py,sha256=7ngi-oWAsmAdtLTvpT4axw5ftcMzqsCtJmfmjzw5etk,31160
|
47
|
+
hammad/json/__init__.py,sha256=-7laMbXoayDBlFDYw9wGgMJSRJ_pnUsI30jJvQsK54M,481
|
48
|
+
hammad/json/converters.py,sha256=gXWJRN6OlzqDoL69nZqtyn8ET22Sxv7znso-VVamDR4,5480
|
49
|
+
hammad/logging/__init__.py,sha256=NbZO9drdBqYj33MKkISIdSI-xEVqtorxQNAyPL6ySpg,726
|
50
|
+
hammad/logging/decorators.py,sha256=xhHRA7WhesgdVMSwK_JvqZhGb90GF3TbYco13Y7aY0w,30119
|
51
|
+
hammad/logging/logger.py,sha256=8q-7anLeZk07QlPszdt_qzsQPaeuZyDHevV8C6R_okk,31451
|
52
|
+
hammad/multimodal/__init__.py,sha256=58zgdyWQTW9_YNED8mlOKBK6AgBjeuteOcvE3QZANRs,444
|
53
|
+
hammad/multimodal/audio.py,sha256=cnmjfnLAQxlh7b8EfDlfk541PzzLL102bOlj5atDSPA,2777
|
54
|
+
hammad/multimodal/image.py,sha256=eRlsCu1oSdlRtcJ8zGlD4np77pvqWMCDPU6FNJ6zNmg,2265
|
55
|
+
hammad/multithreading/__init__.py,sha256=akEIhZndORW1dg3HvfVjDaYJv4IyB_fP6DQt1fH_ums,10788
|
56
|
+
hammad/pydantic/__init__.py,sha256=5ZZfqSrXEapkDcEM5kcOcjs4_tfKlxHyIhK1u-veb3I,1017
|
57
|
+
hammad/pydantic/converters.py,sha256=vlxVoPMY6IpwH4U1B0iVnW3p6VC8M7tINx8o9FU1JOI,20203
|
58
|
+
hammad/pydantic/models/__init__.py,sha256=N8-B-_pAZ7mGpzEeE1M65hda8iQC-SWjDnzIS3gRTg8,671
|
59
|
+
hammad/pydantic/models/arbitrary_model.py,sha256=XSsB2hMC3bCHwyLXepe1D_S3M57yaWG5QUBo3pAoG_M,1524
|
60
|
+
hammad/pydantic/models/cacheable_model.py,sha256=JDzV5kZrgEPovE3M2bF4scoCAoGEhISeMhc69cifDfM,2809
|
61
|
+
hammad/pydantic/models/fast_model.py,sha256=WVJxcUQydScQLhzMOh88Kn2WIFtN5cel_srI6UL3kVk,11716
|
62
|
+
hammad/pydantic/models/function_model.py,sha256=pMtCM2slqJso77L5WuCMoNtm3gO_OMoSe87tgODaZJM,6300
|
63
|
+
hammad/pydantic/models/subscriptable_model.py,sha256=yJ-PpaXPu0eKEktNrGizj5rOSHLGclDAGjwtnYYAcgY,1706
|
64
|
+
hammad/text/__init__.py,sha256=xt4wjg5XvGMIEkr2mD5s__V6QHLX9C0GTIAtquNiyZM,1853
|
65
|
+
hammad/text/converters.py,sha256=LmgyPGrRQrvyNZQlWOiTKfnSQcEtSlTznN7blPIv6Qk,23800
|
66
|
+
hammad/text/markdown.py,sha256=13vS7HmBZIrktua5JoI1CBmigQkk7gJzndEzYkMYjvU,3402
|
67
|
+
hammad/text/text.py,sha256=Fjp0n6upyXLlzecamcY7xzx1j2rFlda_2qPoiyYinVo,33309
|
68
|
+
hammad/types/__init__.py,sha256=0ouYhOy3FydxEn4GUXbWWZ-5FMgLsU2NnQzyaCgKqBQ,336
|
69
|
+
hammad/types/file.py,sha256=o3JSqQyCcKmRtAzk4oltnmzXZ60STL0VEiunOGfNVfk,11102
|
70
|
+
hammad/typing/__init__.py,sha256=jQEwoJVMdgk1VQTLyMiJaU7l5P8JIvcvwcjMazE7iSo,10923
|
71
|
+
hammad/web/__init__.py,sha256=WQYIzWKMG7p1WqONX2P6V-jagmBK2TLe_1N4fio4lUE,1078
|
72
|
+
hammad/web/models.py,sha256=q9d4_3UPvHcvG_HuULxKHQuNrllA2S-3CSP3HdU21Cs,5637
|
73
|
+
hammad/web/utils.py,sha256=7jf_esoIwctKg1qxSaN6yAgzeo70HT1IdSVqoNdHFSQ,15815
|
74
|
+
hammad/web/http/__init__.py,sha256=jn9Rn7Yg2cypD7duTTNFuW2wQZx9B63Bde4RJJeDYU0,22
|
75
|
+
hammad/web/http/client.py,sha256=N_w9WFwolrb43BTNbmi2feHJBoB7Z8PX-XOsHyS6efo,33147
|
76
|
+
hammad/web/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
|
+
hammad/web/openapi/client.py,sha256=1pXz7KAO_0pN4kQZoWKWskXDYGiJ535TsPO1GGCiC0E,26816
|
78
|
+
hammad/web/search/__init__.py,sha256=e9A6znPIiZCz-4secyHbUs0uUGf5yAqW6wGacgx961U,24
|
79
|
+
hammad/web/search/client.py,sha256=4VEhctFf_4LRxM2TXsEssSW6tbaZnu0NYaIVMYQrJNs,35434
|
80
|
+
hammad/yaml/__init__.py,sha256=0w5YV4fOF33-9AyfKJcWhhCOnzrBOyzJAHXJLvTLml8,547
|
81
|
+
hammad/yaml/converters.py,sha256=h2tb7IxlXVvjQs_E2uyTo6LTklUzTVh8lehur-p6iGs,527
|
82
|
+
hammad_python-0.0.13.dist-info/METADATA,sha256=172JcN_IATs1WVRuluJTmq3d1qbQR48LKY-HQnxrOp4,1430
|
83
|
+
hammad_python-0.0.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
84
|
+
hammad_python-0.0.13.dist-info/licenses/LICENSE,sha256=h74yFUWjbBaodcWG5wNmm30npjl8obVcxD-1nQfUp2I,1069
|
85
|
+
hammad_python-0.0.13.dist-info/RECORD,,
|