hammad-python 0.0.15__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 (111) hide show
  1. hammad/__init__.py +178 -0
  2. hammad/_internal.py +237 -0
  3. hammad/cache/__init__.py +40 -0
  4. hammad/cache/base_cache.py +181 -0
  5. hammad/cache/cache.py +169 -0
  6. hammad/cache/decorators.py +261 -0
  7. hammad/cache/file_cache.py +80 -0
  8. hammad/cache/ttl_cache.py +74 -0
  9. hammad/cli/__init__.py +35 -0
  10. hammad/cli/_runner.py +265 -0
  11. hammad/cli/animations.py +573 -0
  12. hammad/cli/plugins.py +836 -0
  13. hammad/cli/styles/__init__.py +55 -0
  14. hammad/cli/styles/settings.py +139 -0
  15. hammad/cli/styles/types.py +358 -0
  16. hammad/cli/styles/utils.py +626 -0
  17. hammad/data/__init__.py +83 -0
  18. hammad/data/collections/__init__.py +44 -0
  19. hammad/data/collections/collection.py +274 -0
  20. hammad/data/collections/indexes/__init__.py +37 -0
  21. hammad/data/collections/indexes/qdrant/__init__.py +1 -0
  22. hammad/data/collections/indexes/qdrant/index.py +735 -0
  23. hammad/data/collections/indexes/qdrant/settings.py +94 -0
  24. hammad/data/collections/indexes/qdrant/utils.py +220 -0
  25. hammad/data/collections/indexes/tantivy/__init__.py +1 -0
  26. hammad/data/collections/indexes/tantivy/index.py +428 -0
  27. hammad/data/collections/indexes/tantivy/settings.py +51 -0
  28. hammad/data/collections/indexes/tantivy/utils.py +200 -0
  29. hammad/data/configurations/__init__.py +35 -0
  30. hammad/data/configurations/configuration.py +564 -0
  31. hammad/data/models/__init__.py +55 -0
  32. hammad/data/models/extensions/__init__.py +4 -0
  33. hammad/data/models/extensions/pydantic/__init__.py +42 -0
  34. hammad/data/models/extensions/pydantic/converters.py +759 -0
  35. hammad/data/models/fields.py +546 -0
  36. hammad/data/models/model.py +1078 -0
  37. hammad/data/models/utils.py +280 -0
  38. hammad/data/sql/__init__.py +23 -0
  39. hammad/data/sql/database.py +578 -0
  40. hammad/data/sql/types.py +141 -0
  41. hammad/data/types/__init__.py +39 -0
  42. hammad/data/types/file.py +358 -0
  43. hammad/data/types/multimodal/__init__.py +24 -0
  44. hammad/data/types/multimodal/audio.py +96 -0
  45. hammad/data/types/multimodal/image.py +80 -0
  46. hammad/data/types/text.py +1066 -0
  47. hammad/formatting/__init__.py +20 -0
  48. hammad/formatting/json/__init__.py +27 -0
  49. hammad/formatting/json/converters.py +158 -0
  50. hammad/formatting/text/__init__.py +63 -0
  51. hammad/formatting/text/converters.py +723 -0
  52. hammad/formatting/text/markdown.py +131 -0
  53. hammad/formatting/yaml/__init__.py +26 -0
  54. hammad/formatting/yaml/converters.py +5 -0
  55. hammad/genai/__init__.py +78 -0
  56. hammad/genai/agents/__init__.py +1 -0
  57. hammad/genai/agents/types/__init__.py +35 -0
  58. hammad/genai/agents/types/history.py +277 -0
  59. hammad/genai/agents/types/tool.py +490 -0
  60. hammad/genai/embedding_models/__init__.py +41 -0
  61. hammad/genai/embedding_models/embedding_model.py +193 -0
  62. hammad/genai/embedding_models/embedding_model_name.py +77 -0
  63. hammad/genai/embedding_models/embedding_model_request.py +65 -0
  64. hammad/genai/embedding_models/embedding_model_response.py +69 -0
  65. hammad/genai/embedding_models/run.py +161 -0
  66. hammad/genai/language_models/__init__.py +35 -0
  67. hammad/genai/language_models/_streaming.py +622 -0
  68. hammad/genai/language_models/_types.py +276 -0
  69. hammad/genai/language_models/_utils/__init__.py +31 -0
  70. hammad/genai/language_models/_utils/_completions.py +131 -0
  71. hammad/genai/language_models/_utils/_messages.py +89 -0
  72. hammad/genai/language_models/_utils/_requests.py +202 -0
  73. hammad/genai/language_models/_utils/_structured_outputs.py +124 -0
  74. hammad/genai/language_models/language_model.py +734 -0
  75. hammad/genai/language_models/language_model_request.py +135 -0
  76. hammad/genai/language_models/language_model_response.py +219 -0
  77. hammad/genai/language_models/language_model_response_chunk.py +53 -0
  78. hammad/genai/language_models/run.py +530 -0
  79. hammad/genai/multimodal_models.py +48 -0
  80. hammad/genai/rerank_models.py +26 -0
  81. hammad/logging/__init__.py +35 -0
  82. hammad/logging/decorators.py +834 -0
  83. hammad/logging/logger.py +954 -0
  84. hammad/mcp/__init__.py +50 -0
  85. hammad/mcp/client/__init__.py +36 -0
  86. hammad/mcp/client/client.py +624 -0
  87. hammad/mcp/client/client_service.py +400 -0
  88. hammad/mcp/client/settings.py +178 -0
  89. hammad/mcp/servers/__init__.py +25 -0
  90. hammad/mcp/servers/launcher.py +1161 -0
  91. hammad/runtime/__init__.py +32 -0
  92. hammad/runtime/decorators.py +142 -0
  93. hammad/runtime/run.py +299 -0
  94. hammad/service/__init__.py +49 -0
  95. hammad/service/create.py +527 -0
  96. hammad/service/decorators.py +285 -0
  97. hammad/typing/__init__.py +435 -0
  98. hammad/web/__init__.py +43 -0
  99. hammad/web/http/__init__.py +1 -0
  100. hammad/web/http/client.py +944 -0
  101. hammad/web/models.py +277 -0
  102. hammad/web/openapi/__init__.py +1 -0
  103. hammad/web/openapi/client.py +740 -0
  104. hammad/web/search/__init__.py +1 -0
  105. hammad/web/search/client.py +1035 -0
  106. hammad/web/utils.py +472 -0
  107. {hammad_python-0.0.15.dist-info → hammad_python-0.0.16.dist-info}/METADATA +8 -1
  108. hammad_python-0.0.16.dist-info/RECORD +110 -0
  109. hammad_python-0.0.15.dist-info/RECORD +0 -4
  110. {hammad_python-0.0.15.dist-info → hammad_python-0.0.16.dist-info}/WHEEL +0 -0
  111. {hammad_python-0.0.15.dist-info → hammad_python-0.0.16.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,435 @@
1
+ """hammad.typing
2
+
3
+ 'Namespace' package extension for various **CORE** typing resources and
4
+ types. This is not a collection of built types, rather resources from the
5
+ core `typing` module, `typing_extensions`, `typing_inspect` and other
6
+ resources."""
7
+
8
+ from typing import Any, TYPE_CHECKING
9
+ import inspect
10
+ import typing_inspect as inspection
11
+
12
+ try:
13
+ from typing_extensions import *
14
+ except ImportError:
15
+ from typing import *
16
+
17
+ from typing_inspect import (
18
+ is_callable_type,
19
+ is_classvar,
20
+ is_final_type,
21
+ is_forward_ref,
22
+ is_generic_type,
23
+ is_literal_type,
24
+ is_new_type,
25
+ is_optional_type,
26
+ is_union_type,
27
+ is_typevar,
28
+ is_tuple_type,
29
+ get_origin,
30
+ get_args,
31
+ get_last_args,
32
+ get_last_origin,
33
+ get_generic_bases,
34
+ typed_dict_keys as get_typed_dict_keys,
35
+ )
36
+ from typing_inspection.introspection import (
37
+ is_union_origin,
38
+ inspect_annotation,
39
+ get_literal_values,
40
+ )
41
+ from dataclasses import is_dataclass
42
+
43
+ __all__ = (
44
+ # Super-special typing primitives.
45
+ "Any",
46
+ "ClassVar",
47
+ "Concatenate",
48
+ "Final",
49
+ "LiteralString",
50
+ "ParamSpec",
51
+ "ParamSpecArgs",
52
+ "ParamSpecKwargs",
53
+ "Self",
54
+ "Type",
55
+ "TypeVar",
56
+ "TypeVarTuple",
57
+ "Unpack",
58
+ # ABCs (from collections.abc).
59
+ "Awaitable",
60
+ "AsyncIterator",
61
+ "AsyncIterable",
62
+ "Coroutine",
63
+ "AsyncGenerator",
64
+ "AsyncContextManager",
65
+ "Buffer",
66
+ "ChainMap",
67
+ # Concrete collection types.
68
+ "ContextManager",
69
+ "Counter",
70
+ "Deque",
71
+ "DefaultDict",
72
+ "NamedTuple",
73
+ "OrderedDict",
74
+ "TypedDict",
75
+ # Structural checks, a.k.a. protocols.
76
+ "SupportsAbs",
77
+ "SupportsBytes",
78
+ "SupportsComplex",
79
+ "SupportsFloat",
80
+ "SupportsIndex",
81
+ "SupportsInt",
82
+ "SupportsRound",
83
+ "Reader",
84
+ "Writer",
85
+ # One-off things.
86
+ "Annotated",
87
+ "assert_never",
88
+ "assert_type",
89
+ "clear_overloads",
90
+ "dataclass_transform",
91
+ "deprecated",
92
+ "Doc",
93
+ "evaluate_forward_ref",
94
+ "get_overloads",
95
+ "final",
96
+ "Format",
97
+ "get_annotations",
98
+ "get_args",
99
+ "get_origin",
100
+ "get_original_bases",
101
+ "get_protocol_members",
102
+ "get_type_hints",
103
+ "IntVar",
104
+ "is_protocol",
105
+ "is_typeddict",
106
+ "Literal",
107
+ "NewType",
108
+ "overload",
109
+ "override",
110
+ "Protocol",
111
+ "Sentinel",
112
+ "reveal_type",
113
+ "runtime",
114
+ "runtime_checkable",
115
+ "Text",
116
+ "TypeAlias",
117
+ "TypeAliasType",
118
+ "TypeForm",
119
+ "TypeGuard",
120
+ "TypeIs",
121
+ "TYPE_CHECKING",
122
+ "Never",
123
+ "NoReturn",
124
+ "ReadOnly",
125
+ "Required",
126
+ "NotRequired",
127
+ "NoDefault",
128
+ "NoExtraItems",
129
+ # Pure aliases, have always been in typing
130
+ "AbstractSet",
131
+ "AnyStr",
132
+ "BinaryIO",
133
+ "Callable",
134
+ "Collection",
135
+ "Container",
136
+ "Dict",
137
+ "ForwardRef",
138
+ "FrozenSet",
139
+ "Generator",
140
+ "Generic",
141
+ "Hashable",
142
+ "IO",
143
+ "ItemsView",
144
+ "Iterable",
145
+ "Iterator",
146
+ "KeysView",
147
+ "List",
148
+ "Mapping",
149
+ "MappingView",
150
+ "Match",
151
+ "MutableMapping",
152
+ "MutableSequence",
153
+ "MutableSet",
154
+ "Optional",
155
+ "Pattern",
156
+ "Reversible",
157
+ "Sequence",
158
+ "Set",
159
+ "Sized",
160
+ "TextIO",
161
+ "Tuple",
162
+ "Union",
163
+ "ValuesView",
164
+ "cast",
165
+ "no_type_check",
166
+ "no_type_check_decorator",
167
+ "TypingError",
168
+ "get_type_description",
169
+ "inspection",
170
+ "is_pydantic_basemodel",
171
+ "is_pydantic_basemodel_instance",
172
+ "is_msgspec_struct",
173
+ "is_dataclass",
174
+ "is_callable_type",
175
+ "is_classvar",
176
+ "is_final_type",
177
+ "is_forward_ref",
178
+ "is_generic_type",
179
+ "is_literal_type",
180
+ "is_new_type",
181
+ "is_optional_type",
182
+ "is_union_type",
183
+ "is_typevar",
184
+ "is_tuple_type",
185
+ "get_origin",
186
+ "get_args",
187
+ "is_union_origin",
188
+ "inspect_annotation",
189
+ "get_literal_values",
190
+ "get_last_args",
191
+ "get_last_origin",
192
+ "get_generic_bases",
193
+ "get_typed_dict_keys",
194
+ "is_function",
195
+ )
196
+
197
+
198
+ class TypingError(Exception):
199
+ """An exception raised when a type utility raises an error."""
200
+
201
+
202
+ # ------------------------------------------------------------------------
203
+ # Inspection Extensions
204
+ # ------------------------------------------------------------------------
205
+
206
+
207
+ def is_function(t: "Any") -> bool:
208
+ """Check if an object is a callable function.
209
+
210
+ This function identifies whether the given object is a callable function,
211
+ including regular functions, built-in functions, and methods, but excluding
212
+ classes and other callable objects that are not strictly functions.
213
+
214
+ Args:
215
+ t: The object to check. Can be a function, method, or any other type.
216
+
217
+ Returns:
218
+ True if the object is a function or method, False otherwise.
219
+
220
+ Example:
221
+ >>> def my_func():
222
+ ... pass
223
+ >>> is_function(my_func)
224
+ True
225
+ >>> is_function(lambda x: x)
226
+ True
227
+ >>> is_function(str)
228
+ False
229
+ """
230
+ return inspect.isfunction(t) or inspect.ismethod(t)
231
+
232
+
233
+ def is_pydantic_basemodel(t: "Any") -> bool:
234
+ """Check if an object is a Pydantic BaseModel class or instance using duck typing.
235
+
236
+ This function uses duck typing to identify Pydantic BaseModel objects by checking
237
+ for the presence of characteristic attributes (`model_fields` and `model_dump`)
238
+ without requiring direct imports of Pydantic.
239
+
240
+ Args:
241
+ t: The object to check. Can be a class, instance, or any other type.
242
+
243
+ Returns:
244
+ True if the object appears to be a Pydantic BaseModel (class or instance),
245
+ False otherwise.
246
+
247
+ Example:
248
+ >>> from pydantic import BaseModel
249
+ >>> class User(BaseModel):
250
+ ... name: str
251
+ >>> is_pydantic_basemodel(User)
252
+ True
253
+ >>> is_pydantic_basemodel(User(name="John"))
254
+ True
255
+ >>> is_pydantic_basemodel(dict)
256
+ False
257
+ """
258
+ # Check if it's a class first
259
+ if isinstance(t, type):
260
+ return (
261
+ hasattr(t, "model_fields")
262
+ and hasattr(t, "model_dump")
263
+ and callable(getattr(t, "model_dump", None))
264
+ )
265
+
266
+ # For instances, check the class instead of the instance to avoid deprecation warning
267
+ return (
268
+ hasattr(t.__class__, "model_fields")
269
+ and hasattr(t, "model_dump")
270
+ and callable(getattr(t, "model_dump", None))
271
+ )
272
+
273
+
274
+ def is_pydantic_basemodel_instance(t: "Any") -> bool:
275
+ """Check if an object is an instance (not class) of a Pydantic BaseModel using duck typing.
276
+
277
+ This function specifically identifies Pydantic BaseModel instances by ensuring
278
+ the object is not a type/class itself and has the characteristic Pydantic attributes.
279
+
280
+ Args:
281
+ t: The object to check.
282
+
283
+ Returns:
284
+ True if the object is a Pydantic BaseModel instance (not the class itself),
285
+ False otherwise.
286
+
287
+ Example:
288
+ >>> from pydantic import BaseModel
289
+ >>> class User(BaseModel):
290
+ ... name: str
291
+ >>> user = User(name="John")
292
+ >>> is_pydantic_basemodel_instance(user)
293
+ True
294
+ >>> is_pydantic_basemodel_instance(User) # Class, not instance
295
+ False
296
+ """
297
+ return (
298
+ not isinstance(t, type)
299
+ and hasattr(t.__class__, "model_fields")
300
+ and hasattr(t, "model_dump")
301
+ and callable(getattr(t, "model_dump", None))
302
+ )
303
+
304
+
305
+ def is_msgspec_struct(t: "Any") -> bool:
306
+ """Check if an object is a msgspec Struct class or instance using duck typing.
307
+
308
+ This function uses duck typing to identify msgspec Struct objects by checking
309
+ for the presence of characteristic attributes (`__struct_fields__` and
310
+ `__struct_config__`) without requiring direct imports of msgspec.
311
+
312
+ Args:
313
+ t: The object to check. Can be a class, instance, or any other type.
314
+
315
+ Returns:
316
+ True if the object appears to be a msgspec Struct (class or instance),
317
+ False otherwise.
318
+
319
+ Example:
320
+ >>> import msgspec
321
+ >>> class User(msgspec.Struct):
322
+ ... name: str
323
+ >>> is_msgspec_struct(User)
324
+ True
325
+ >>> is_msgspec_struct(User(name="John"))
326
+ True
327
+ >>> is_msgspec_struct(dict)
328
+ False
329
+ """
330
+ return hasattr(t, "__struct_fields__") and hasattr(t, "__struct_config__")
331
+
332
+
333
+ def get_type_description(t: "Any") -> str:
334
+ """Creates a human-readable description of a type hint.
335
+
336
+ Args:
337
+ t : The type hint to create a description for.
338
+
339
+ Returns:
340
+ A human-readable description of the type hint.
341
+ """
342
+ origin = inspection.get_origin(t)
343
+ args = inspection.get_args(t)
344
+
345
+ if origin is None:
346
+ # Handle basic types that should have special names
347
+ if t is list:
348
+ return "array"
349
+ elif t is dict:
350
+ return "object"
351
+ elif t is tuple:
352
+ return "tuple"
353
+ elif hasattr(t, "__name__"):
354
+ return t.__name__
355
+ return str(t)
356
+
357
+ if origin is list:
358
+ if args:
359
+ return f"array of {get_type_description(args[0])}"
360
+ return "array"
361
+
362
+ if origin is dict:
363
+ if len(args) == 2:
364
+ return f"object with {get_type_description(args[0])} keys and {get_type_description(args[1])} values"
365
+ return "object"
366
+
367
+ if origin is tuple:
368
+ if args:
369
+ arg_descriptions = [get_type_description(arg) for arg in args]
370
+ return f"tuple of ({', '.join(arg_descriptions)})"
371
+ return "tuple"
372
+
373
+ if inspection.is_literal_type(t):
374
+ if args:
375
+ values = [repr(arg) for arg in args]
376
+ return f"one of: {', '.join(values)}"
377
+ return "literal"
378
+
379
+ # Handle Union types (including Optional)
380
+ if inspection.is_union_type(t):
381
+ if inspection.is_optional_type(t):
382
+ # This is Optional[T]
383
+ non_none_args = [arg for arg in args if arg is not type(None)]
384
+ if non_none_args:
385
+ return f"optional {get_type_description(non_none_args[0])}"
386
+ else:
387
+ # This is Union[T1, T2, ...]
388
+ arg_descriptions = [get_type_description(arg) for arg in args]
389
+ return f"one of: {', '.join(arg_descriptions)}"
390
+
391
+ # Handle callable types
392
+ if inspection.is_callable_type(t):
393
+ if args and len(args) >= 2:
394
+ param_types_arg = args[0] # First arg is the parameter types
395
+ return_type = args[1] # Second arg is the return type
396
+
397
+ # param_types_arg is either a list of types or ... (Ellipsis)
398
+ if param_types_arg is ...:
399
+ return f"function(...) -> {get_type_description(return_type)}"
400
+ elif isinstance(param_types_arg, (list, tuple)):
401
+ if param_types_arg:
402
+ param_descriptions = [
403
+ get_type_description(param) for param in param_types_arg
404
+ ]
405
+ return f"function({', '.join(param_descriptions)}) -> {get_type_description(return_type)}"
406
+ else:
407
+ return f"function() -> {get_type_description(return_type)}"
408
+ return "function"
409
+
410
+ # Handle generic types
411
+ if inspection.is_generic_type(t):
412
+ if args:
413
+ arg_descriptions = [get_type_description(arg) for arg in args]
414
+ return f"{origin.__name__}[{', '.join(arg_descriptions)}]"
415
+ return str(origin)
416
+
417
+ # Handle final types
418
+ if inspection.is_final_type(t):
419
+ if args:
420
+ return f"final {get_type_description(args[0])}"
421
+ return "final"
422
+
423
+ # Handle forward references
424
+ if inspection.is_forward_ref(t):
425
+ return f"forward_ref({t.__forward_arg__})"
426
+
427
+ # Handle new types
428
+ if inspection.is_new_type(t):
429
+ return f"new_type({t.__name__})"
430
+
431
+ # Handle type variables
432
+ if inspection.is_typevar(t):
433
+ return f"typevar({t.__name__})"
434
+
435
+ return str(t)
hammad/web/__init__.py ADDED
@@ -0,0 +1,43 @@
1
+ """hammad.web"""
2
+
3
+ from typing import TYPE_CHECKING
4
+ from .._internal import create_getattr_importer
5
+
6
+ if TYPE_CHECKING:
7
+ from .utils import (
8
+ run_web_request,
9
+ read_web_page,
10
+ read_web_pages,
11
+ web_search,
12
+ search_news,
13
+ extract_page_links,
14
+ )
15
+ from .http.client import AsyncHttpClient, HttpClient, create_http_client
16
+ from .openapi.client import AsyncOpenAPIClient, OpenAPIClient, create_openapi_client
17
+ from .search.client import AsyncSearchClient, SearchClient, create_search_client
18
+
19
+ __all__ = (
20
+ "run_web_request",
21
+ "read_web_page",
22
+ "read_web_pages",
23
+ "web_search",
24
+ "search_news",
25
+ "extract_page_links",
26
+ "AsyncHttpClient",
27
+ "HttpClient",
28
+ "create_http_client",
29
+ "AsyncOpenAPIClient",
30
+ "OpenAPIClient",
31
+ "create_openapi_client",
32
+ "AsyncSearchClient",
33
+ "SearchClient",
34
+ "create_search_client",
35
+ )
36
+
37
+
38
+ __getattr__ = create_getattr_importer(__all__)
39
+
40
+
41
+ def __dir__() -> list[str]:
42
+ """Get the attributes of the web module."""
43
+ return list(__all__)
@@ -0,0 +1 @@
1
+ """hammad.web.http"""