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
@@ -5,35 +5,46 @@ models, as well as modules & utilities specifically for various interfaces
5
5
  of models such as `pydantic`."""
6
6
 
7
7
  from typing import TYPE_CHECKING
8
- from ...performance.imports import create_getattr_importer
8
+ from ..._internal import create_getattr_importer
9
9
 
10
10
  if TYPE_CHECKING:
11
- from .base import (
11
+ from .model import (
12
12
  Model,
13
- field,
13
+ model_settings,
14
+ )
15
+ from .fields import (
16
+ field
17
+ )
18
+ from .utils import (
14
19
  validator,
15
20
  is_field,
16
21
  is_model,
17
- model_settings
18
22
  )
19
- from .pydantic import (
23
+ from .extensions.pydantic.converters import (
20
24
  convert_to_pydantic_model,
21
- convert_to_pydantic_field
25
+ convert_to_pydantic_field,
26
+ is_pydantic_model_class
22
27
  )
23
28
 
24
29
 
25
30
  __all__ = (
26
- # hammad.models.base
31
+ # hammad.lib.data.models.model
27
32
  "Model",
33
+ "model_settings",
34
+
35
+ # hammad.lib.data.models.fields
28
36
  "field",
37
+
38
+ # hammad.lib.data.models.utils
29
39
  "validator",
30
40
  "is_field",
31
41
  "is_model",
32
42
  "model_settings",
33
43
 
34
- # hammad.models.pydantic
44
+ # hammad.lib.data.models.extensions.pydantic.converters
35
45
  "convert_to_pydantic_model",
36
46
  "convert_to_pydantic_field",
47
+ "is_pydantic_model_class",
37
48
  )
38
49
 
39
50
 
@@ -41,4 +52,4 @@ __getattr__ = create_getattr_importer(__all__)
41
52
 
42
53
 
43
54
  def __dir__() -> list[str]:
44
- return list(__all__)
55
+ return list(__all__)
@@ -0,0 +1,4 @@
1
+ """hammad.models.extensions
2
+
3
+ Contains a collection of resources specifically for external schemas or
4
+ definitions for models."""
@@ -1,19 +1,12 @@
1
- """hammad.models.pydantic
1
+ """hammad.data.models.extensions.pydantic
2
2
 
3
3
  Contains both models and pydantic **specific** utiltiies / resources
4
4
  meant for general case usage."""
5
5
 
6
6
  from typing import TYPE_CHECKING
7
- from ....performance.imports import create_getattr_importer
7
+ from ....._internal import create_getattr_importer
8
8
 
9
9
  if TYPE_CHECKING:
10
- from .models import (
11
- ArbitraryModel,
12
- CacheableModel,
13
- FastModel,
14
- FunctionModel,
15
- SubscriptableModel,
16
- )
17
10
  from .converters import (
18
11
  convert_to_pydantic_model,
19
12
  convert_to_pydantic_field,
@@ -27,14 +20,8 @@ if TYPE_CHECKING:
27
20
  )
28
21
 
29
22
 
30
- __all__ = (
31
- # hammad.models.pydantic.models
32
- "ArbitraryModel",
33
- "CacheableModel",
34
- "FastModel",
35
- "FunctionModel",
36
- "SubscriptableModel",
37
- # hammad.models.pydantic.converters
23
+ __all__ = [
24
+ # hammad.lib.pydantic.converters
38
25
  "convert_to_pydantic_model",
39
26
  "convert_to_pydantic_field",
40
27
  "convert_dataclass_to_pydantic_model",
@@ -44,7 +31,7 @@ __all__ = (
44
31
  "convert_type_to_pydantic_model",
45
32
  "create_confirmation_pydantic_model",
46
33
  "create_selection_pydantic_model",
47
- )
34
+ ]
48
35
 
49
36
 
50
37
  __getattr__ = create_getattr_importer(__all__)
@@ -52,4 +39,4 @@ __getattr__ = create_getattr_importer(__all__)
52
39
 
53
40
  def __dir__() -> list[str]:
54
41
  """Get the attributes of the models module."""
55
- return list(__all__)
42
+ return __all__
@@ -1,4 +1,4 @@
1
- """hammad.data.models.pydantic.converters
1
+ """hammad.data.models.extensions.pydantic.converters
2
2
 
3
3
  Contains various converters for converting various objects into
4
4
  a Pydantic model. These converters are used to convert
@@ -28,8 +28,6 @@ from typing import (
28
28
  )
29
29
  from pydantic import BaseModel, Field, create_model
30
30
 
31
- from ....cache.decorators import cached
32
-
33
31
  from typing import get_origin, get_args
34
32
  from typing_inspect import is_generic_type
35
33
 
@@ -79,6 +77,38 @@ A mapping of types to their string representations. Used for hinting & JSON sche
79
77
  generation.
80
78
  """
81
79
 
80
+ TYPE_NAME_MAPPING: Dict[Type, str] = {
81
+ int: "Integer",
82
+ float: "Float",
83
+ bool: "Boolean",
84
+ str: "String",
85
+ bytes: "Bytes",
86
+ list: "List",
87
+ tuple: "Tuple",
88
+ dict: "Dict",
89
+ set: "Set",
90
+ frozenset: "FrozenSet",
91
+ }
92
+ """
93
+ A mapping of basic types to their semantic model names.
94
+ """
95
+
96
+ FIELD_NAME_MAPPING: Dict[Type, str] = {
97
+ int: "value",
98
+ float: "value",
99
+ bool: "flag",
100
+ str: "text",
101
+ bytes: "data",
102
+ list: "items",
103
+ tuple: "values",
104
+ dict: "mapping",
105
+ set: "elements",
106
+ frozenset: "elements",
107
+ }
108
+ """
109
+ A mapping of basic types to their semantic field names.
110
+ """
111
+
82
112
 
83
113
  # -----------------------------------------------------------------------------
84
114
  # Pydantic Model Utils
@@ -92,6 +122,104 @@ def is_pydantic_model_class(obj: Any) -> bool:
92
122
  return isinstance(obj, type) and issubclass(obj, BaseModel)
93
123
 
94
124
 
125
+ def generate_semantic_model_name(type_hint: Type) -> str:
126
+ """
127
+ Generates a semantic model name based on the type.
128
+
129
+ Examples:
130
+ int -> "Integer"
131
+ str -> "String"
132
+ List[int] -> "IntegerList"
133
+ Dict[str, int] -> "StringIntegerDict"
134
+ Optional[int] -> "OptionalInteger"
135
+ Union[str, int] -> "StringIntegerUnion"
136
+ """
137
+ # Handle basic types
138
+ if type_hint in TYPE_NAME_MAPPING:
139
+ return TYPE_NAME_MAPPING[type_hint]
140
+
141
+ # Handle Optional types
142
+ origin = get_origin(type_hint)
143
+ args = get_args(type_hint)
144
+
145
+ if origin is Union:
146
+ # Check if it's Optional (Union with None)
147
+ if type(None) in args and len(args) == 2:
148
+ # This is Optional[T]
149
+ inner_type = next(arg for arg in args if arg is not type(None))
150
+ return f"Optional{generate_semantic_model_name(inner_type)}"
151
+ else:
152
+ # Regular Union
153
+ type_names = [
154
+ generate_semantic_model_name(arg)
155
+ for arg in args
156
+ if arg is not type(None)
157
+ ]
158
+ return "".join(type_names) + "Union"
159
+
160
+ # Handle generic types
161
+ if origin is not None:
162
+ origin_name = TYPE_NAME_MAPPING.get(origin, origin.__name__.capitalize())
163
+
164
+ if args:
165
+ # Generate names for type arguments
166
+ arg_names = [generate_semantic_model_name(arg) for arg in args]
167
+ if origin in (list, set, frozenset):
168
+ # For collections, append the element type
169
+ return f"{arg_names[0]}{origin_name}"
170
+ elif origin is dict:
171
+ # For dict, include both key and value types
172
+ return f"{arg_names[0]}{arg_names[1]}Dict"
173
+ elif origin is tuple:
174
+ # For tuple, join all types
175
+ return "".join(arg_names) + "Tuple"
176
+ else:
177
+ # For other generics, prepend type arguments
178
+ return "".join(arg_names) + origin_name
179
+
180
+ return origin_name
181
+
182
+ # Fallback to the type's name
183
+ if hasattr(type_hint, "__name__"):
184
+ return type_hint.__name__.capitalize()
185
+
186
+ return "GeneratedModel"
187
+
188
+
189
+ def generate_semantic_field_name(type_hint: Type) -> str:
190
+ """
191
+ Generates a semantic field name based on the type.
192
+
193
+ Examples:
194
+ int -> "value"
195
+ str -> "text"
196
+ List[int] -> "items"
197
+ Dict[str, int] -> "mapping"
198
+ Optional[str] -> "text"
199
+ """
200
+ # Handle basic types
201
+ if type_hint in FIELD_NAME_MAPPING:
202
+ return FIELD_NAME_MAPPING[type_hint]
203
+
204
+ # Handle Optional types - use the inner type's field name
205
+ origin = get_origin(type_hint)
206
+ args = get_args(type_hint)
207
+
208
+ if origin is Union:
209
+ # Check if it's Optional (Union with None)
210
+ if type(None) in args and len(args) == 2:
211
+ # This is Optional[T] - use inner type's field name
212
+ inner_type = next(arg for arg in args if arg is not type(None))
213
+ return generate_semantic_field_name(inner_type)
214
+
215
+ # Handle generic types - use the origin's field name
216
+ if origin is not None and origin in FIELD_NAME_MAPPING:
217
+ return FIELD_NAME_MAPPING[origin]
218
+
219
+ # Default fallback
220
+ return "value"
221
+
222
+
95
223
  def get_pydantic_fields_from_function(func: Callable) -> Dict[str, Tuple[Type, Field]]:
96
224
  """
97
225
  Extracts Pydantic fields from a function's signature and docstring.
@@ -143,7 +271,6 @@ def get_pydantic_fields_from_function(func: Callable) -> Dict[str, Tuple[Type, F
143
271
  return {}
144
272
 
145
273
 
146
- @cached
147
274
  def convert_to_pydantic_field(
148
275
  type_hint: Type,
149
276
  index: Optional[int] = None,
@@ -155,8 +282,14 @@ def convert_to_pydantic_field(
155
282
  Returns a dictionary mapping a generated field name to its (type, Field) tuple.
156
283
  """
157
284
  try:
158
- base_name, _ = JSON_TYPE_MAPPING.get(type_hint, ("value", type_hint))
159
- field_name = f"value_{index}" if index is not None else "value"
285
+ # Use semantic field name if no index is provided
286
+ if index is None:
287
+ field_name = generate_semantic_field_name(type_hint)
288
+ else:
289
+ # Use indexed field name for sequences
290
+ base_name = generate_semantic_field_name(type_hint)
291
+ field_name = f"{base_name}_{index}"
292
+
160
293
  return {
161
294
  field_name: (
162
295
  type_hint,
@@ -178,7 +311,6 @@ def convert_to_pydantic_field(
178
311
  # -----------------------------------------------------------------------------
179
312
 
180
313
 
181
- @cached
182
314
  def convert_dataclass_to_pydantic_model(
183
315
  target: Union[Type, Any], # NOTE: DATACLASS TYPE OR INSTANCE
184
316
  init: bool,
@@ -229,7 +361,6 @@ def convert_dataclass_to_pydantic_model(
229
361
  return model_class
230
362
 
231
363
 
232
- @cached
233
364
  def convert_type_to_pydantic_model(
234
365
  target: Type,
235
366
  name: Optional[str],
@@ -237,19 +368,20 @@ def convert_type_to_pydantic_model(
237
368
  field_name: Optional[str],
238
369
  default: Any,
239
370
  ) -> Type[BaseModel]:
240
- model_name = name or "GeneratedModel"
371
+ # Use semantic naming if no name is provided
372
+ model_name = name or generate_semantic_model_name(target)
373
+
241
374
  field_mapping = convert_to_pydantic_field(
242
375
  target, description=description, default=default
243
376
  )
244
377
 
245
- if field_name: # Override default field name "value"
378
+ if field_name: # Override default field name if explicitly provided
246
379
  current_field_def = list(field_mapping.values())[0]
247
380
  field_mapping = {field_name: current_field_def}
248
381
 
249
382
  return create_model(model_name, __doc__=(description or ""), **field_mapping)
250
383
 
251
384
 
252
- @cached
253
385
  def convert_function_to_pydantic_model(
254
386
  target: Callable,
255
387
  name: Optional[str],
@@ -263,7 +395,6 @@ def convert_function_to_pydantic_model(
263
395
  return create_model(model_name, __doc__=model_doc, **fields)
264
396
 
265
397
 
266
- @cached
267
398
  def convert_sequence_to_pydantic_model(
268
399
  target: Sequence[Type],
269
400
  name: Optional[str],
@@ -308,7 +439,6 @@ def convert_sequence_to_pydantic_model(
308
439
  return create_model(model_name, __doc__=(description or ""), **pydantic_fields)
309
440
 
310
441
 
311
- @cached
312
442
  def convert_dict_to_pydantic_model(
313
443
  target: Dict[str, Any],
314
444
  init: bool,
@@ -330,7 +460,6 @@ def convert_dict_to_pydantic_model(
330
460
  return model_class
331
461
 
332
462
 
333
- @cached
334
463
  def _reconvert_to_pydantic_model_from_basemodel_instance(
335
464
  target: BaseModel,
336
465
  name: Optional[str],
@@ -563,7 +692,6 @@ def convert_to_pydantic_model(
563
692
  # -----------------------------------------------------------------------------
564
693
 
565
694
 
566
- @cached
567
695
  def create_selection_pydantic_model(
568
696
  fields: List[str],
569
697
  name: str = "Selection",
@@ -605,7 +733,6 @@ def create_selection_pydantic_model(
605
733
  )
606
734
 
607
735
 
608
- @cached
609
736
  def create_confirmation_pydantic_model(
610
737
  name: str = "Confirmation",
611
738
  description: Optional[str] = None,
@@ -1,4 +1,4 @@
1
- """hammad.base.fields"""
1
+ """hammad.data.models.fields"""
2
2
 
3
3
  import re
4
4
  from dataclasses import dataclass
@@ -1,4 +1,4 @@
1
- """hammad.base.model"""
1
+ """hammad.data.models.model"""
2
2
 
3
3
  import copy
4
4
  from functools import lru_cache
@@ -1,4 +1,4 @@
1
- """hammad.base.utils"""
1
+ """hammad.data.models.utils"""
2
2
 
3
3
  from functools import lru_cache
4
4
  from typing import Any, Callable, Optional, Union, Tuple, Dict
@@ -0,0 +1,23 @@
1
+ """hammad.data.sql"""
2
+
3
+ from typing import TYPE_CHECKING
4
+ from ..._internal import create_getattr_importer
5
+
6
+ if TYPE_CHECKING:
7
+ from .types import DatabaseItemType, DatabaseItem
8
+ from .database import Database
9
+
10
+
11
+ __all__ = (
12
+ "DatabaseItemType",
13
+ "DatabaseItem",
14
+ "Database",
15
+ )
16
+
17
+
18
+ __getattr__ = create_getattr_importer(__all__)
19
+
20
+
21
+ def __dir__() -> list[str]:
22
+ """Get the attributes of the hammad.data.sql module."""
23
+ return list(__all__)