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,285 @@
1
+ """hammad.service.decorators"""
2
+
3
+ from typing import (
4
+ Any,
5
+ Callable,
6
+ Dict,
7
+ List,
8
+ Literal,
9
+ Optional,
10
+ Type,
11
+ Union,
12
+ ParamSpec,
13
+ TypeVar,
14
+ )
15
+
16
+
17
+ ServiceFunctionParams = ParamSpec("ServiceFunctionParams")
18
+ ServiceFunctionReturn = TypeVar("ServiceFunctionReturn")
19
+
20
+
21
+ def serve(
22
+ func: Optional[Callable[ServiceFunctionParams, ServiceFunctionReturn]] = None,
23
+ *,
24
+ # Overrides
25
+ name: Optional[str] = None,
26
+ method: Literal[
27
+ "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"
28
+ ] = "POST",
29
+ path: str = "/",
30
+ # Server configuration
31
+ host: str = "0.0.0.0",
32
+ port: int = 8000,
33
+ log_level: str = "info",
34
+ reload: bool = False,
35
+ workers: int = 1,
36
+ timeout_keep_alive: int = 5,
37
+ access_log: bool = True,
38
+ use_colors: bool = True,
39
+ auto_start: bool = True,
40
+ # FastAPI
41
+ include_in_schema: bool = True,
42
+ dependencies: Optional[List[Callable[..., Any]]] = None,
43
+ tags: Optional[List[str]] = None,
44
+ description: Optional[str] = None,
45
+ ) -> Union[Callable[ServiceFunctionParams, ServiceFunctionReturn], Callable]:
46
+ """Decorator to serve a function as a FastAPI endpoint.
47
+
48
+ Can be used as a decorator (@serve) or as a function (serve(func)).
49
+
50
+ Args:
51
+ func: Function to serve (when used as decorator, this is None initially)
52
+ name: Service name (defaults to function name)
53
+ method: HTTP method to use
54
+ path: API endpoint path
55
+ host: Host to bind to
56
+ port: Port to bind to
57
+ log_level: Uvicorn log level
58
+ reload: Enable auto-reload
59
+ workers: Number of worker processes
60
+ timeout_keep_alive: Keep-alive timeout
61
+ access_log: Enable access logging
62
+ use_colors: Use colored logs
63
+ auto_start: Automatically start the server
64
+ include_in_schema: Include in OpenAPI schema
65
+ dependencies: FastAPI dependencies
66
+ tags: API tags
67
+ description: API description
68
+
69
+ Returns:
70
+ The original function (when used as decorator)
71
+ """
72
+ from .create import create_service
73
+ from ..mcp.servers.launcher import find_next_free_port
74
+
75
+ def decorator(
76
+ f: Callable[ServiceFunctionParams, ServiceFunctionReturn],
77
+ ) -> Callable[ServiceFunctionParams, ServiceFunctionReturn]:
78
+ # Find next available port if auto_start is True
79
+ actual_port = port
80
+ if auto_start:
81
+ actual_port = find_next_free_port(port, host)
82
+
83
+ # Handle dependencies - convert raw functions to FastAPI Depends
84
+ processed_dependencies = None
85
+ if dependencies is not None:
86
+ from fastapi import Depends
87
+
88
+ processed_dependencies = [
89
+ Depends(dep) if callable(dep) else dep for dep in dependencies
90
+ ]
91
+
92
+ # Store the service configuration on the function
93
+ f._service_config = {
94
+ "name": name or f.__name__,
95
+ "method": method,
96
+ "path": path,
97
+ "host": host,
98
+ "port": actual_port,
99
+ "log_level": log_level,
100
+ "reload": reload,
101
+ "workers": workers,
102
+ "timeout_keep_alive": timeout_keep_alive,
103
+ "access_log": access_log,
104
+ "use_colors": use_colors,
105
+ "auto_start": auto_start,
106
+ "include_in_schema": include_in_schema,
107
+ "dependencies": processed_dependencies,
108
+ "tags": tags,
109
+ "description": description,
110
+ }
111
+
112
+ # Create and start the service immediately if auto_start is True
113
+ if auto_start:
114
+ create_service(f, **f._service_config)
115
+
116
+ return f
117
+
118
+ if func is None:
119
+ # Called as @serve(...)
120
+ return decorator
121
+ else:
122
+ # Called as @serve (without parentheses)
123
+ return decorator(func)
124
+
125
+
126
+ def serve_mcp(
127
+ fn: Optional[Union[Callable, List[Callable]]] = None,
128
+ *,
129
+ # MCP Server configuration
130
+ name: Optional[str] = None,
131
+ instructions: Optional[str] = None,
132
+ transport: Literal["stdio", "sse", "streamable-http"] = "stdio",
133
+ # Server settings (for sse/http transports)
134
+ host: str = "127.0.0.1",
135
+ port: int = 8000,
136
+ mount_path: str = "/",
137
+ sse_path: str = "/sse",
138
+ message_path: str = "/messages/",
139
+ streamable_http_path: str = "/mcp",
140
+ json_response: bool = False,
141
+ stateless_http: bool = False,
142
+ warn_on_duplicate_resources: bool = True,
143
+ warn_on_duplicate_tools: bool = True,
144
+ # FastMCP settings
145
+ dependencies: Optional[List[str]] = None,
146
+ log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO",
147
+ debug_mode: bool = False,
148
+ cwd: Optional[str] = None,
149
+ # Launch settings
150
+ auto_restart: bool = False,
151
+ check_interval: float = 1.0,
152
+ # Function-specific parameters (only when single function)
153
+ single_func_name: Optional[str] = None,
154
+ single_func_description: Optional[str] = None,
155
+ ) -> Union[Callable, List[Callable]]:
156
+ """Decorator/function to serve functions as MCP server tools.
157
+
158
+ Can be used in multiple ways:
159
+ 1. As a decorator: @serve_mcp
160
+ 2. As a decorator with params: @serve_mcp(name="MyServer")
161
+ 3. As a function with single function: serve_mcp(my_func)
162
+ 4. As a function with multiple functions: serve_mcp([func1, func2])
163
+
164
+ Args:
165
+ fn: Function or list of functions to serve
166
+ name: MCP server name
167
+ instructions: Server instructions
168
+ transport: Transport type (stdio, sse, streamable-http)
169
+ host: Host for HTTP transports
170
+ port: Starting port for HTTP transports
171
+ mount_path: Mount path for HTTP servers
172
+ sse_path: SSE endpoint path
173
+ message_path: Message endpoint path
174
+ streamable_http_path: StreamableHTTP endpoint path
175
+ json_response: Use JSON responses for HTTP
176
+ stateless_http: Use stateless HTTP mode
177
+ warn_on_duplicate_resources: Warn on duplicate resources
178
+ warn_on_duplicate_tools: Warn on duplicate tools
179
+ dependencies: FastMCP dependencies
180
+ log_level: Logging level
181
+ debug_mode: Enable debug mode
182
+ cwd: Working directory
183
+ auto_restart: Automatically restart failed servers
184
+ check_interval: Health check interval in seconds
185
+ single_func_name: Name override for single function
186
+ single_func_description: Description for single function
187
+
188
+ Returns:
189
+ Original function(s) unchanged
190
+ """
191
+ from ..mcp.servers.launcher import (
192
+ launch_mcp_servers,
193
+ MCPServerStdioSettings,
194
+ MCPServerSseSettings,
195
+ MCPServerStreamableHttpSettings,
196
+ )
197
+
198
+ def _create_server_config(
199
+ tools: List[Callable], server_name: str, server_instructions: Optional[str]
200
+ ):
201
+ """Create the appropriate server configuration based on transport type."""
202
+ base_config = {
203
+ "name": server_name,
204
+ "instructions": server_instructions,
205
+ "tools": tools,
206
+ "dependencies": dependencies or [],
207
+ "log_level": log_level,
208
+ "debug_mode": debug_mode,
209
+ "cwd": cwd,
210
+ }
211
+
212
+ if transport == "stdio":
213
+ return MCPServerStdioSettings(**base_config)
214
+ elif transport == "sse":
215
+ return MCPServerSseSettings(
216
+ **base_config,
217
+ host=host,
218
+ start_port=port,
219
+ mount_path=mount_path,
220
+ sse_path=sse_path,
221
+ message_path=message_path,
222
+ json_response=json_response,
223
+ stateless_http=stateless_http,
224
+ warn_on_duplicate_resources=warn_on_duplicate_resources,
225
+ warn_on_duplicate_tools=warn_on_duplicate_tools,
226
+ )
227
+ elif transport == "streamable-http":
228
+ return MCPServerStreamableHttpSettings(
229
+ **base_config,
230
+ host=host,
231
+ start_port=port,
232
+ mount_path=mount_path,
233
+ streamable_http_path=streamable_http_path,
234
+ json_response=json_response,
235
+ stateless_http=stateless_http,
236
+ warn_on_duplicate_resources=warn_on_duplicate_resources,
237
+ warn_on_duplicate_tools=warn_on_duplicate_tools,
238
+ )
239
+ else:
240
+ raise ValueError(f"Unsupported transport: {transport}")
241
+
242
+ def _launch_server(server_config):
243
+ """Launch the MCP server with the given configuration."""
244
+ launch_mcp_servers(
245
+ servers=[server_config],
246
+ check_interval=check_interval,
247
+ auto_restart=auto_restart,
248
+ )
249
+
250
+ def decorator(f: Callable) -> Callable:
251
+ """Decorator for single function."""
252
+ func_name = single_func_name or name or f.__name__
253
+ func_instructions = single_func_description or instructions or f.__doc__
254
+
255
+ # Create server configuration and launch
256
+ server_config = _create_server_config([f], func_name, func_instructions)
257
+ _launch_server(server_config)
258
+
259
+ return f
260
+
261
+ def handle_multiple_functions(funcs: List[Callable]) -> List[Callable]:
262
+ """Handle multiple functions."""
263
+ server_name = name or "MCPServer"
264
+ server_instructions = instructions or f"MCP server with {len(funcs)} tools"
265
+
266
+ # Create server configuration and launch
267
+ server_config = _create_server_config(funcs, server_name, server_instructions)
268
+ _launch_server(server_config)
269
+
270
+ return funcs
271
+
272
+ # Handle different call patterns
273
+ if fn is None:
274
+ # Called as @serve_mcp(...) - return decorator
275
+ return decorator
276
+ elif callable(fn):
277
+ # Called as @serve_mcp (no parentheses) or serve_mcp(single_func)
278
+ return decorator(fn)
279
+ elif isinstance(fn, list):
280
+ # Called as serve_mcp([func1, func2, ...])
281
+ return handle_multiple_functions(fn)
282
+ else:
283
+ raise TypeError(
284
+ f"Expected callable or list of callables, got {type(fn)}"
285
+ )