hammad-python 0.0.10__py3-none-any.whl → 0.0.11__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 (74) hide show
  1. hammad/__init__.py +64 -10
  2. hammad/based/__init__.py +52 -0
  3. hammad/based/fields.py +546 -0
  4. hammad/based/model.py +968 -0
  5. hammad/based/utils.py +455 -0
  6. hammad/cache/__init__.py +30 -0
  7. hammad/{cache.py → cache/_cache.py} +83 -12
  8. hammad/cli/__init__.py +25 -0
  9. hammad/cli/plugins/__init__.py +786 -0
  10. hammad/cli/styles/__init__.py +5 -0
  11. hammad/cli/styles/animations.py +548 -0
  12. hammad/cli/styles/settings.py +135 -0
  13. hammad/cli/styles/types.py +358 -0
  14. hammad/cli/styles/utils.py +480 -0
  15. hammad/data/__init__.py +51 -0
  16. hammad/data/collections/__init__.py +32 -0
  17. hammad/data/collections/base_collection.py +58 -0
  18. hammad/data/collections/collection.py +227 -0
  19. hammad/data/collections/searchable_collection.py +556 -0
  20. hammad/data/collections/vector_collection.py +497 -0
  21. hammad/data/databases/__init__.py +21 -0
  22. hammad/data/databases/database.py +551 -0
  23. hammad/data/types/__init__.py +33 -0
  24. hammad/data/types/files/__init__.py +1 -0
  25. hammad/data/types/files/audio.py +81 -0
  26. hammad/data/types/files/configuration.py +475 -0
  27. hammad/data/types/files/document.py +195 -0
  28. hammad/data/types/files/file.py +358 -0
  29. hammad/data/types/files/image.py +80 -0
  30. hammad/json/__init__.py +21 -0
  31. hammad/{utils/json → json}/converters.py +4 -1
  32. hammad/logging/__init__.py +27 -0
  33. hammad/logging/decorators.py +432 -0
  34. hammad/logging/logger.py +534 -0
  35. hammad/pydantic/__init__.py +43 -0
  36. hammad/{utils/pydantic → pydantic}/converters.py +2 -1
  37. hammad/pydantic/models/__init__.py +28 -0
  38. hammad/pydantic/models/arbitrary_model.py +46 -0
  39. hammad/pydantic/models/cacheable_model.py +79 -0
  40. hammad/pydantic/models/fast_model.py +318 -0
  41. hammad/pydantic/models/function_model.py +176 -0
  42. hammad/pydantic/models/subscriptable_model.py +63 -0
  43. hammad/text/__init__.py +37 -0
  44. hammad/text/text.py +1068 -0
  45. hammad/text/utils/__init__.py +1 -0
  46. hammad/{utils/text → text/utils}/converters.py +2 -2
  47. hammad/text/utils/markdown/__init__.py +1 -0
  48. hammad/{utils → text/utils}/markdown/converters.py +3 -3
  49. hammad/{utils → text/utils}/markdown/formatting.py +1 -1
  50. hammad/{utils/typing/utils.py → typing/__init__.py} +75 -2
  51. hammad/web/__init__.py +42 -0
  52. hammad/web/http/__init__.py +1 -0
  53. hammad/web/http/client.py +944 -0
  54. hammad/web/openapi/client.py +740 -0
  55. hammad/web/search/__init__.py +1 -0
  56. hammad/web/search/client.py +936 -0
  57. hammad/web/utils.py +463 -0
  58. hammad/yaml/__init__.py +30 -0
  59. hammad/yaml/converters.py +19 -0
  60. {hammad_python-0.0.10.dist-info → hammad_python-0.0.11.dist-info}/METADATA +14 -8
  61. hammad_python-0.0.11.dist-info/RECORD +65 -0
  62. hammad/database.py +0 -447
  63. hammad/logger.py +0 -273
  64. hammad/types/color.py +0 -951
  65. hammad/utils/json/__init__.py +0 -0
  66. hammad/utils/markdown/__init__.py +0 -0
  67. hammad/utils/pydantic/__init__.py +0 -0
  68. hammad/utils/text/__init__.py +0 -0
  69. hammad/utils/typing/__init__.py +0 -0
  70. hammad_python-0.0.10.dist-info/RECORD +0 -22
  71. /hammad/{types/__init__.py → py.typed} +0 -0
  72. /hammad/{utils → web/openapi}/__init__.py +0 -0
  73. {hammad_python-0.0.10.dist-info → hammad_python-0.0.11.dist-info}/WHEEL +0 -0
  74. {hammad_python-0.0.10.dist-info → hammad_python-0.0.11.dist-info}/licenses/LICENSE +0 -0
hammad/web/utils.py ADDED
@@ -0,0 +1,463 @@
1
+ """hammad.web.utils"""
2
+
3
+ import asyncio
4
+ from typing import Any, Dict, Optional, Union, Literal, List, overload, TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from .http.client import HttpResponse
8
+
9
+ __all__ = (
10
+ "run_web_request",
11
+ "search_web",
12
+ "read_web_page",
13
+ "read_web_pages",
14
+ "search_news",
15
+ "extract_page_links",
16
+ )
17
+
18
+
19
+ # Module-level singleton for performance
20
+ _search_client = None
21
+
22
+
23
+ def _get_search_client():
24
+ """Get a SearchClient instance using lazy import and singleton pattern."""
25
+ global _search_client
26
+ if _search_client is None:
27
+ from .search.client import AsyncSearchClient as SearchClient
28
+
29
+ _search_client = SearchClient()
30
+ return _search_client
31
+
32
+
33
+ @overload
34
+ def run_web_request(
35
+ type: Literal["http"],
36
+ method: Literal["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"],
37
+ url: str,
38
+ *,
39
+ headers: Optional[Dict[str, str]] = None,
40
+ params: Optional[Dict[str, Any]] = None,
41
+ json_data: Optional[Dict[str, Any]] = None,
42
+ form_data: Optional[Dict[str, Any]] = None,
43
+ content: Optional[Union[str, bytes]] = None,
44
+ timeout: Optional[float] = None,
45
+ follow_redirects: bool = True,
46
+ base_url: Optional[str] = None,
47
+ default_headers: Optional[Dict[str, str]] = None,
48
+ verify_ssl: bool = True,
49
+ # Semantic authentication parameters
50
+ api_key: Optional[str] = None,
51
+ api_key_header: str = "X-API-Key",
52
+ bearer_token: Optional[str] = None,
53
+ basic_auth: Optional[tuple[str, str]] = None,
54
+ user_agent: Optional[str] = None,
55
+ retry_attempts: int = 0,
56
+ retry_delay: float = 1.0,
57
+ ) -> "HttpResponse": ...
58
+
59
+
60
+ @overload
61
+ def run_web_request(
62
+ type: Literal["openapi"],
63
+ openapi_spec: Union[str, Dict[str, Any]],
64
+ operation_id: str,
65
+ *,
66
+ parameters: Optional[Dict[str, Any]] = None,
67
+ request_body: Optional[Dict[str, Any]] = None,
68
+ headers: Optional[Dict[str, str]] = None,
69
+ base_url: Optional[str] = None,
70
+ default_headers: Optional[Dict[str, str]] = None,
71
+ timeout: float = 30.0,
72
+ follow_redirects: bool = True,
73
+ verify_ssl: bool = True,
74
+ # Semantic authentication parameters
75
+ api_key: Optional[str] = None,
76
+ api_key_header: str = "X-API-Key",
77
+ bearer_token: Optional[str] = None,
78
+ basic_auth: Optional[tuple[str, str]] = None,
79
+ user_agent: Optional[str] = None,
80
+ ) -> "HttpResponse": ...
81
+
82
+
83
+ def run_web_request(
84
+ type: Literal["http", "openapi"], *args, **kwargs
85
+ ) -> "HttpResponse":
86
+ """
87
+ Create and execute a request using either HTTP or OpenAPI toolkits.
88
+
89
+ This function initializes the appropriate toolkit and sends the request,
90
+ returning the HTTP response.
91
+
92
+ Args:
93
+ type: Type of request - "http" for direct HTTP requests or "openapi" for OpenAPI operations
94
+
95
+ HTTP-specific args:
96
+ method: HTTP method
97
+ url: Request URL
98
+ headers: Request headers
99
+ params: Query parameters
100
+ json_data: JSON request body
101
+ form_data: Form data
102
+ content: Raw content
103
+ timeout: Request timeout
104
+ follow_redirects: Whether to follow redirects
105
+ base_url: Base URL for requests
106
+ default_headers: Default headers
107
+ verify_ssl: Whether to verify SSL certificates
108
+
109
+ OpenAPI-specific args:
110
+ openapi_spec: OpenAPI specification (dict, JSON string, or YAML string)
111
+ operation_id: OpenAPI operation ID to execute
112
+ parameters: Operation parameters
113
+ request_body: Request body for the operation
114
+ headers: Additional headers
115
+ base_url: Base URL override
116
+ default_headers: Default headers
117
+ timeout: Request timeout
118
+ follow_redirects: Whether to follow redirects
119
+ verify_ssl: Whether to verify SSL certificates
120
+
121
+ Returns:
122
+ HttpResponse object containing the response data
123
+
124
+ Raises:
125
+ ValueError: For invalid request type or missing required parameters
126
+ HttpToolkitError: For HTTP-related errors
127
+ OpenApiToolkitError: For OpenAPI-related errors
128
+ """
129
+
130
+ async def _run_web_request_async():
131
+ if type == "http":
132
+ if len(args) < 2:
133
+ raise ValueError(
134
+ "HTTP requests require method and url as positional arguments"
135
+ )
136
+
137
+ method, url = args[0], args[1]
138
+
139
+ # Import here to avoid circular imports
140
+ from .http.client import HttpClient as HttpToolkit
141
+
142
+ # Initialize the HTTP toolkit
143
+ toolkit = HttpToolkit(
144
+ base_url=kwargs.get("base_url"),
145
+ default_headers=kwargs.get("default_headers", {}),
146
+ timeout=kwargs.get("timeout", 30.0),
147
+ follow_redirects=kwargs.get("follow_redirects", True),
148
+ verify_ssl=kwargs.get("verify_ssl", True),
149
+ api_key=kwargs.get("api_key"),
150
+ api_key_header=kwargs.get("api_key_header", "X-API-Key"),
151
+ bearer_token=kwargs.get("bearer_token"),
152
+ basic_auth=kwargs.get("basic_auth"),
153
+ user_agent=kwargs.get("user_agent"),
154
+ )
155
+
156
+ # Execute the request based on method
157
+ if method.upper() == "GET":
158
+ return await toolkit.get(
159
+ url,
160
+ headers=kwargs.get("headers"),
161
+ params=kwargs.get("params"),
162
+ timeout=kwargs.get("timeout"),
163
+ retry_attempts=kwargs.get("retry_attempts", 0),
164
+ retry_delay=kwargs.get("retry_delay", 1.0),
165
+ )
166
+ elif method.upper() == "POST":
167
+ return await toolkit.post(
168
+ url,
169
+ headers=kwargs.get("headers"),
170
+ json_data=kwargs.get("json_data"),
171
+ form_data=kwargs.get("form_data"),
172
+ timeout=kwargs.get("timeout"),
173
+ retry_attempts=kwargs.get("retry_attempts", 0),
174
+ )
175
+ elif method.upper() == "PUT":
176
+ return await toolkit.put(
177
+ url,
178
+ headers=kwargs.get("headers"),
179
+ json_data=kwargs.get("json_data"),
180
+ form_data=kwargs.get("form_data"),
181
+ timeout=kwargs.get("timeout"),
182
+ retry_attempts=kwargs.get("retry_attempts", 0),
183
+ )
184
+ elif method.upper() == "PATCH":
185
+ return await toolkit.patch(
186
+ url,
187
+ headers=kwargs.get("headers"),
188
+ json_data=kwargs.get("json_data"),
189
+ form_data=kwargs.get("form_data"),
190
+ timeout=kwargs.get("timeout"),
191
+ retry_attempts=kwargs.get("retry_attempts", 0),
192
+ )
193
+ elif method.upper() == "DELETE":
194
+ return await toolkit.delete(
195
+ url,
196
+ headers=kwargs.get("headers"),
197
+ timeout=kwargs.get("timeout"),
198
+ retry_attempts=kwargs.get("retry_attempts", 0),
199
+ )
200
+ else:
201
+ raise ValueError(f"Unsupported HTTP method: {method}")
202
+
203
+ elif type == "openapi":
204
+ from .openapi.client import OpenAPIClient as OpenApiToolkit
205
+
206
+ if len(args) < 2:
207
+ raise ValueError(
208
+ "OpenAPI requests require openapi_spec and operation_id as positional arguments"
209
+ )
210
+
211
+ openapi_spec, operation_id = args[0], args[1]
212
+
213
+ # Initialize the OpenAPI toolkit
214
+ toolkit = OpenApiToolkit(
215
+ openapi_spec=openapi_spec,
216
+ base_url=kwargs.get("base_url"),
217
+ default_headers=kwargs.get("default_headers"),
218
+ timeout=kwargs.get("timeout", 30.0),
219
+ follow_redirects=kwargs.get("follow_redirects", True),
220
+ verify_ssl=kwargs.get("verify_ssl", True),
221
+ api_key=kwargs.get("api_key"),
222
+ api_key_header=kwargs.get("api_key_header", "X-API-Key"),
223
+ bearer_token=kwargs.get("bearer_token"),
224
+ basic_auth=kwargs.get("basic_auth"),
225
+ user_agent=kwargs.get("user_agent"),
226
+ )
227
+
228
+ # Execute the OpenAPI operation
229
+ return await toolkit.execute_operation(
230
+ operation_id=operation_id,
231
+ parameters=kwargs.get("parameters"),
232
+ request_body=kwargs.get("request_body"),
233
+ headers=kwargs.get("headers"),
234
+ )
235
+
236
+ else:
237
+ raise ValueError(
238
+ f"Invalid request type: {type}. Must be 'http' or 'openapi'"
239
+ )
240
+
241
+ return asyncio.run(_run_web_request_async())
242
+
243
+
244
+ def search_web(
245
+ query: str,
246
+ *,
247
+ max_results: int = 10,
248
+ region: str = "wt-wt",
249
+ safesearch: Literal["on", "moderate", "off"] = "moderate",
250
+ timelimit: Optional[Literal["d", "w", "m", "y"]] = None,
251
+ backend: Literal["auto", "html", "lite"] = "auto",
252
+ retry_attempts: int = 3,
253
+ retry_delay: float = 1.0,
254
+ ) -> List[Dict[str, str]]:
255
+ """
256
+ Search the web using DuckDuckGo search.
257
+
258
+ Args:
259
+ query: Search query string
260
+ max_results: Maximum number of results to return (default: 10)
261
+ region: Search region (default: "wt-wt" for worldwide)
262
+ safesearch: Safe search setting (default: "moderate")
263
+ timelimit: Time limit for results (d=day, w=week, m=month, y=year)
264
+ backend: Search backend to use (default: "auto")
265
+ retry_attempts: Number of retry attempts for rate limit errors (default: 3)
266
+ retry_delay: Initial delay between retries in seconds (default: 1.0)
267
+
268
+ Returns:
269
+ List of search result dictionaries with 'title', 'href', and 'body' keys
270
+
271
+ Raises:
272
+ ValueError: If query is empty
273
+ Exception: If search fails after all retries
274
+ """
275
+
276
+ async def _search_web_async():
277
+ client = _get_search_client()
278
+ return await client.search_web(
279
+ query=query,
280
+ max_results=max_results,
281
+ region=region,
282
+ safesearch=safesearch,
283
+ timelimit=timelimit,
284
+ backend=backend,
285
+ )
286
+
287
+ return asyncio.run(_search_web_async())
288
+
289
+
290
+ def read_web_page(
291
+ url: str,
292
+ *,
293
+ timeout: float = 30.0,
294
+ headers: Optional[Dict[str, str]] = None,
295
+ extract_text: bool = True,
296
+ extract_links: bool = False,
297
+ extract_images: bool = False,
298
+ css_selector: Optional[str] = None,
299
+ ) -> Dict[str, Any]:
300
+ """
301
+ Read and parse a single web page using selectolax.
302
+
303
+ Args:
304
+ url: URL to fetch and parse
305
+ timeout: Request timeout in seconds (default: 30.0)
306
+ headers: Optional HTTP headers to send
307
+ extract_text: Whether to extract text content (default: True)
308
+ extract_links: Whether to extract links (default: False)
309
+ extract_images: Whether to extract images (default: False)
310
+ css_selector: Optional CSS selector to extract specific elements
311
+
312
+ Returns:
313
+ Dictionary containing parsed content and metadata
314
+
315
+ Raises:
316
+ httpx.HTTPError: If request fails
317
+ Exception: If parsing fails
318
+ """
319
+
320
+ async def _read_web_page_async():
321
+ client = _get_search_client()
322
+ return await client.read_web_page(
323
+ url=url,
324
+ timeout=timeout,
325
+ headers=headers,
326
+ extract_text=extract_text,
327
+ extract_links=extract_links,
328
+ extract_images=extract_images,
329
+ css_selector=css_selector,
330
+ )
331
+
332
+ return asyncio.run(_read_web_page_async())
333
+
334
+
335
+ def read_web_pages(
336
+ urls: List[str],
337
+ *,
338
+ timeout: float = 30.0,
339
+ headers: Optional[Dict[str, str]] = None,
340
+ extract_text: bool = True,
341
+ extract_links: bool = False,
342
+ extract_images: bool = False,
343
+ css_selector: Optional[str] = None,
344
+ max_concurrent: int = 5,
345
+ ) -> List[Dict[str, Any]]:
346
+ """
347
+ Read and parse multiple web pages concurrently using selectolax.
348
+
349
+ Args:
350
+ urls: List of URLs to fetch and parse
351
+ timeout: Request timeout in seconds (default: 30.0)
352
+ headers: Optional HTTP headers to send
353
+ extract_text: Whether to extract text content (default: True)
354
+ extract_links: Whether to extract links (default: False)
355
+ extract_images: Whether to extract images (default: False)
356
+ css_selector: Optional CSS selector to extract specific elements
357
+ max_concurrent: Maximum number of concurrent requests (default: 5)
358
+
359
+ Returns:
360
+ List of dictionaries containing parsed content and metadata
361
+
362
+ Raises:
363
+ Exception: If any critical error occurs
364
+ """
365
+
366
+ async def _read_web_pages_async():
367
+ client = _get_search_client()
368
+ return await client.read_web_pages(
369
+ urls=urls,
370
+ timeout=timeout,
371
+ headers=headers,
372
+ extract_text=extract_text,
373
+ extract_links=extract_links,
374
+ extract_images=extract_images,
375
+ css_selector=css_selector,
376
+ max_concurrent=max_concurrent,
377
+ )
378
+
379
+ return asyncio.run(_read_web_pages_async())
380
+
381
+
382
+ def search_news(
383
+ query: str,
384
+ *,
385
+ max_results: int = 10,
386
+ region: str = "wt-wt",
387
+ safesearch: Literal["on", "moderate", "off"] = "moderate",
388
+ timelimit: Optional[Literal["d", "w", "m"]] = None,
389
+ ) -> List[Dict[str, str]]:
390
+ """
391
+ Search for news using DuckDuckGo news search.
392
+
393
+ Args:
394
+ query: Search query string
395
+ max_results: Maximum number of results to return (default: 10)
396
+ region: Search region (default: "wt-wt" for worldwide)
397
+ safesearch: Safe search setting (default: "moderate")
398
+ timelimit: Time limit for results (d=day, w=week, m=month)
399
+
400
+ Returns:
401
+ List of news result dictionaries with date, title, body, url, image, and source
402
+
403
+ Raises:
404
+ ValueError: If query is empty
405
+ Exception: If search fails
406
+ """
407
+
408
+ async def _search_news_async():
409
+ client = _get_search_client()
410
+ return await client.search_news(
411
+ query=query,
412
+ max_results=max_results,
413
+ region=region,
414
+ safesearch=safesearch,
415
+ timelimit=timelimit,
416
+ )
417
+
418
+ return asyncio.run(_search_news_async())
419
+
420
+
421
+ def extract_page_links(
422
+ url: str,
423
+ *,
424
+ timeout: float = 30.0,
425
+ headers: Optional[Dict[str, str]] = None,
426
+ css_selector: str = "a[href]",
427
+ include_external: bool = True,
428
+ include_internal: bool = True,
429
+ base_url: Optional[str] = None,
430
+ ) -> List[Dict[str, str]]:
431
+ """
432
+ Extract links from a web page using selectolax.
433
+
434
+ Args:
435
+ url: URL to fetch and extract links from
436
+ timeout: Request timeout in seconds (default: 30.0)
437
+ headers: Optional HTTP headers to send
438
+ css_selector: CSS selector for links (default: "a[href]")
439
+ include_external: Whether to include external links (default: True)
440
+ include_internal: Whether to include internal links (default: True)
441
+ base_url: Base URL for resolving relative links (uses page URL if not provided)
442
+
443
+ Returns:
444
+ List of link dictionaries with href, text, title, and type (internal/external)
445
+
446
+ Raises:
447
+ httpx.HTTPError: If request fails
448
+ Exception: If parsing fails
449
+ """
450
+
451
+ async def _extract_page_links_async():
452
+ client = _get_search_client()
453
+ return await client.extract_page_links(
454
+ url=url,
455
+ timeout=timeout,
456
+ headers=headers,
457
+ css_selector=css_selector,
458
+ include_external=include_external,
459
+ include_internal=include_internal,
460
+ base_url=base_url,
461
+ )
462
+
463
+ return asyncio.run(_extract_page_links_async())
@@ -0,0 +1,30 @@
1
+ """hammad.yaml
2
+
3
+ Simply extends the `msgspec.yaml` submodule."""
4
+
5
+ from typing import TYPE_CHECKING
6
+ from ..based.utils import auto_create_lazy_loader
7
+
8
+ if TYPE_CHECKING:
9
+ from .converters import (
10
+ Yaml,
11
+ encode_yaml,
12
+ decode_yaml,
13
+ read_yaml_file,
14
+ )
15
+
16
+
17
+ __all__ = (
18
+ "Yaml",
19
+ "encode_yaml",
20
+ "decode_yaml",
21
+ "read_yaml_file",
22
+ )
23
+
24
+
25
+ __getattr__ = auto_create_lazy_loader(__all__)
26
+
27
+
28
+ def __dir__() -> list[str]:
29
+ """Get the attributes of the yaml module."""
30
+ return list(__all__)
@@ -0,0 +1,19 @@
1
+ """hammad.yaml.converters"""
2
+
3
+ from msgspec.yaml import encode as encode_yaml, decode as decode_yaml
4
+ from ..data.types import Configuration as Yaml
5
+
6
+ __all__ = ("encode_yaml", "decode_yaml", "read_yaml_file", "Yaml")
7
+
8
+
9
+ def read_yaml_file(path: str) -> Yaml:
10
+ """Parses a YAML file to return a Configuration object.
11
+ This utilizes the following file types:
12
+
13
+ Args:
14
+ path (str): The path to the YAML file.
15
+
16
+ Returns:
17
+ Yaml: A Configuration object.
18
+ """
19
+ return Yaml.from_file(path)
@@ -1,23 +1,29 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hammad-python
3
- Version: 0.0.10
3
+ Version: 0.0.11
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
7
7
  Requires-Python: >=3.11
8
8
  Requires-Dist: docstring-parser>=0.16
9
- Requires-Dist: duckduckgo-search>=7.3.0
9
+ Requires-Dist: duckduckgo-search>=8.0.4
10
+ Requires-Dist: httpx>=0.28.1
10
11
  Requires-Dist: msgspec>=0.19.0
11
- Requires-Dist: platformdirs>=4.3.8
12
+ Requires-Dist: prompt-toolkit>=3.0.51
12
13
  Requires-Dist: pydantic>=2.11.5
13
- Requires-Dist: sqlalchemy>=2.0.41
14
+ Requires-Dist: python-dotenv>=1.1.0
15
+ Requires-Dist: pyyaml>=6.0.2
16
+ Requires-Dist: rich>=13.9.4
17
+ Requires-Dist: selectolax>=0.3.30
14
18
  Requires-Dist: tantivy>=0.24.0
19
+ Requires-Dist: tenacity>=9.0.0
15
20
  Requires-Dist: typing-inspect>=0.9.0
21
+ Requires-Dist: uvloop>=0.21.0
16
22
  Provides-Extra: ai
17
- Requires-Dist: instructor>=1.8.3; extra == 'ai'
18
- Requires-Dist: litellm; extra == 'ai'
19
- Requires-Dist: memvid; extra == 'ai'
20
- Requires-Dist: openai-agents; extra == 'ai'
23
+ Requires-Dist: instructor>=1.9.0; extra == 'ai'
24
+ Requires-Dist: litellm>=1.72.4; extra == 'ai'
25
+ Requires-Dist: openai-agents>=0.0.19; extra == 'ai'
26
+ Requires-Dist: qdrant-client>=1.14.3; extra == 'ai'
21
27
  Provides-Extra: serve
22
28
  Requires-Dist: fastapi>=0.115.8; extra == 'serve'
23
29
  Requires-Dist: python-multipart>=0.0.19; extra == 'serve'
@@ -0,0 +1,65 @@
1
+ hammad/__init__.py,sha256=eeb0R0wxMJGlYNT6ksfI_nWrVoFt5Oy7XnwYs0TbDpM,1355
2
+ hammad/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ hammad/based/__init__.py,sha256=cqAMf0nN2BzTMldMlh5ZvVrVRhSy5A0W9HxzHsXoLOY,1168
4
+ hammad/based/fields.py,sha256=dVwVx-hjDwxEkuqkndchZxGVWvAAl9B5XuLti2JziYA,19288
5
+ hammad/based/model.py,sha256=ROnby4MWqBDtgLG28Ywp4cmJJtGjXo1a4zjKPDYTWSc,35561
6
+ hammad/based/utils.py,sha256=0kEiHng2ybFk1YrDJHzzhsdwhhectfIbiWk0CvNGhzo,16023
7
+ hammad/cache/__init__.py,sha256=tFoiLMuw150cJ5tZTSMYa-H4n7mzhsCCjtD714RtH-0,515
8
+ hammad/cache/_cache.py,sha256=XBsRoPYT1bVYx9rLYKoD8whTUpepp91PYyJs6lhuB6o,25295
9
+ hammad/cli/__init__.py,sha256=mxlAWQnXBrPDBS0aneWe6j7snrzDgKp6wrd87qI8L9A,496
10
+ hammad/cli/plugins/__init__.py,sha256=1l4e68XzmMIaKXTkzLPoxECXosGaW8IOK1kEaqh9nJ0,25971
11
+ hammad/cli/styles/__init__.py,sha256=G-j_Sx8uOUYR4HjbcOYuA26HXZ5-yd5y8SS3Qj5o_7U,189
12
+ hammad/cli/styles/animations.py,sha256=vYEfOKBvCGvXMNu7jJGkxX8_XUjEuKoMvKCMGKIXMUg,17874
13
+ hammad/cli/styles/settings.py,sha256=i07i7y6YoTr5HkeWbgYRA9JwZv2AKcC0o4KBkHunARA,5409
14
+ hammad/cli/styles/types.py,sha256=vNIeQY_23m10K8qVT7Iy-PMwosGL-La-UAZKszHJjEE,7911
15
+ hammad/cli/styles/utils.py,sha256=BGFwQIEJHWlTAXed8ZxHeI_phLfEdh-_Mok2fe-jn7g,19356
16
+ hammad/data/__init__.py,sha256=B1g9mPhe9L6tQ9QbfiUEG16j16-jinaFQa9khTLoOMo,1273
17
+ hammad/data/collections/__init__.py,sha256=vujWqbnhTftqXjrmvKG949cLr6nD-azWHdng1jEpNvw,777
18
+ hammad/data/collections/base_collection.py,sha256=ZRht7OZjLIT8GxNvMgNxTarbCTY6EUUurEkGHZ3Rsy4,1419
19
+ hammad/data/collections/collection.py,sha256=JnOmD7E0GkBA7VBS7yJjXS76Rvo4dAT7KZk9SmLtZ1g,7436
20
+ hammad/data/collections/searchable_collection.py,sha256=vCV_JgMwB57QRi4Cri6dfEUzLCyTBN58_JfWEKL2h_0,21361
21
+ hammad/data/collections/vector_collection.py,sha256=D0aNyRwTe6VOyDAFS9Iyiw_4isvVNjudoGtd1KElSPU,17241
22
+ hammad/data/databases/__init__.py,sha256=NfRKlADRMzOsPrspOCyA0GmmCoHVXXqRfriqOZrDiYw,402
23
+ hammad/data/databases/database.py,sha256=jteV-P8BMsPd9NA_J-jeFkOQN3uFNitaDZN5uwv2yRY,18946
24
+ hammad/data/types/__init__.py,sha256=P_dM1RZf3W0zYpRV0KSZw24pHKQxCAl9tRV51BZwOHk,729
25
+ hammad/data/types/files/__init__.py,sha256=ufxESRe0PYBSxIs4FMhEUWK1DdlLpBFiaHyxsQuRtAg,30
26
+ hammad/data/types/files/audio.py,sha256=T5t4P6UN2oFUgzj-bVkWpEGZ91A8M-HxNxC65peOQjA,2361
27
+ hammad/data/types/files/configuration.py,sha256=PFg5InnHdGRyOMOySNL5u4ufo3uDORYAthgnlX2ATzQ,15457
28
+ hammad/data/types/files/document.py,sha256=9it-VC6gaTXqDGhFjzVenTr9Zb5RkXAcMpPaDWKC_Wk,6305
29
+ hammad/data/types/files/file.py,sha256=LWr5LaUljJfLTWvwDIAj37tuIa3Z7IG4SQcqn87xEwE,11204
30
+ hammad/data/types/files/image.py,sha256=orCnLwtthYV0ohzOLhIhWef6S4NgdBBw4udw-MbSnxI,2281
31
+ hammad/json/__init__.py,sha256=hCyzw5Hyyf7YqsED7P52DtMHM2XvZtdsaxV0y8nSkps,458
32
+ hammad/json/converters.py,sha256=gXWJRN6OlzqDoL69nZqtyn8ET22Sxv7znso-VVamDR4,5480
33
+ hammad/logging/__init__.py,sha256=FwpYFBF8wpYxDKXtRBhQQFP8ymFuNF5bnTBu5DFhK8s,557
34
+ hammad/logging/decorators.py,sha256=Wa3q063UxJDd9Orx-unkLkVF8Mt-KWNcWV6SwS5YOqg,14756
35
+ hammad/logging/logger.py,sha256=jk23wkdAf8qeKStBEUMWxEESuEXR4OWPYChEMsPYyrY,17543
36
+ hammad/pydantic/__init__.py,sha256=0qljzy1ZdTHSSly1KbhgdyLyVPU7JjX5uDKUdFuYFuA,994
37
+ hammad/pydantic/converters.py,sha256=d5fDXHTrxVCpBi3H-OuZShxD_BeCev5hupcsvC6csg8,20199
38
+ hammad/pydantic/models/__init__.py,sha256=HR9sQ_pC0Xaw8o_FgQwW-tT2hqHXRTLhhFxBXXcdKIY,648
39
+ hammad/pydantic/models/arbitrary_model.py,sha256=XSsB2hMC3bCHwyLXepe1D_S3M57yaWG5QUBo3pAoG_M,1524
40
+ hammad/pydantic/models/cacheable_model.py,sha256=JDzV5kZrgEPovE3M2bF4scoCAoGEhISeMhc69cifDfM,2809
41
+ hammad/pydantic/models/fast_model.py,sha256=WVJxcUQydScQLhzMOh88Kn2WIFtN5cel_srI6UL3kVk,11716
42
+ hammad/pydantic/models/function_model.py,sha256=pMtCM2slqJso77L5WuCMoNtm3gO_OMoSe87tgODaZJM,6300
43
+ hammad/pydantic/models/subscriptable_model.py,sha256=yJ-PpaXPu0eKEktNrGizj5rOSHLGclDAGjwtnYYAcgY,1706
44
+ hammad/text/__init__.py,sha256=5oDbPD74ziwPGew36SXeV0ltwutNyigzVRfj6y0WTfQ,771
45
+ hammad/text/text.py,sha256=F1XD2YvXlbS8N18eH97FTaKN5haODTgAA8vGzuy3dcs,33388
46
+ hammad/text/utils/__init__.py,sha256=c4GEfUadmnhrx3h5T0JT38icULObriObPOucrr1tiL4,24
47
+ hammad/text/utils/converters.py,sha256=cBlOJ5qPGsBhP7q785ITuuLRR0RPhr0HfAyaXGTsiCg,8208
48
+ hammad/text/utils/markdown/__init__.py,sha256=TK4Nm88dkMyemsUmWD8uS8zSo4hDwkFhElIcOyQkVPs,33
49
+ hammad/text/utils/markdown/converters.py,sha256=aZze09fEB__WHiV08DGGxXAZWX4OgR90m0P3bwy6Crk,15406
50
+ hammad/text/utils/markdown/formatting.py,sha256=XCldk1sVfkQF-c1aMZOjkIy8xNIddi0VGwQaOqmrWCY,3209
51
+ hammad/typing/__init__.py,sha256=UMUo_-BsDBGVfk7ByWzymsoaxnAcK-Svp-g3d9BN0CI,10694
52
+ hammad/web/__init__.py,sha256=vh1HjRhhHb0yESYf6JdSyaRjjTZVAn3Q3kJ8vu9uhO8,1054
53
+ hammad/web/utils.py,sha256=B4GAVsdKgFgVUMOGI0L2_3HKVSjeJsFRml4RevTA6Ic,15685
54
+ hammad/web/http/__init__.py,sha256=jn9Rn7Yg2cypD7duTTNFuW2wQZx9B63Bde4RJJeDYU0,22
55
+ hammad/web/http/client.py,sha256=N_w9WFwolrb43BTNbmi2feHJBoB7Z8PX-XOsHyS6efo,33147
56
+ hammad/web/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ hammad/web/openapi/client.py,sha256=1pXz7KAO_0pN4kQZoWKWskXDYGiJ535TsPO1GGCiC0E,26816
58
+ hammad/web/search/__init__.py,sha256=e9A6znPIiZCz-4secyHbUs0uUGf5yAqW6wGacgx961U,24
59
+ hammad/web/search/client.py,sha256=_ifT8RcW6Xibhg8J-ouEc7BRA2cTd0xQO3rzOjM53t0,33692
60
+ hammad/yaml/__init__.py,sha256=HJb_8-xFxizGFEIbELN2sTEfKB-_wQvA6spj_kkXuCo,524
61
+ hammad/yaml/converters.py,sha256=NQHetbxfkTS3jEJyThsz-hnG2IgRSbaGs_TnqNjFciA,510
62
+ hammad_python-0.0.11.dist-info/METADATA,sha256=buxO0GEAaH-EQG7As4C6B6jBs8MyjyHYime5L-WTjCw,1323
63
+ hammad_python-0.0.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
64
+ hammad_python-0.0.11.dist-info/licenses/LICENSE,sha256=h74yFUWjbBaodcWG5wNmm30npjl8obVcxD-1nQfUp2I,1069
65
+ hammad_python-0.0.11.dist-info/RECORD,,