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.
- hammad/__init__.py +177 -0
- hammad/{performance/imports.py → _internal.py} +7 -1
- hammad/cache/__init__.py +1 -1
- hammad/cli/__init__.py +3 -1
- hammad/cli/_runner.py +265 -0
- hammad/cli/animations.py +1 -1
- hammad/cli/plugins.py +133 -78
- hammad/cli/styles/__init__.py +1 -1
- hammad/cli/styles/utils.py +149 -3
- hammad/data/__init__.py +56 -29
- hammad/data/collections/__init__.py +27 -17
- hammad/data/collections/collection.py +205 -383
- hammad/data/collections/indexes/__init__.py +37 -0
- hammad/data/collections/indexes/qdrant/__init__.py +1 -0
- hammad/data/collections/indexes/qdrant/index.py +735 -0
- hammad/data/collections/indexes/qdrant/settings.py +94 -0
- hammad/data/collections/indexes/qdrant/utils.py +220 -0
- hammad/data/collections/indexes/tantivy/__init__.py +1 -0
- hammad/data/collections/indexes/tantivy/index.py +428 -0
- hammad/data/collections/indexes/tantivy/settings.py +51 -0
- hammad/data/collections/indexes/tantivy/utils.py +200 -0
- hammad/data/configurations/__init__.py +2 -2
- hammad/data/configurations/configuration.py +2 -2
- hammad/data/models/__init__.py +20 -9
- hammad/data/models/extensions/__init__.py +4 -0
- hammad/data/models/{pydantic → extensions/pydantic}/__init__.py +6 -19
- hammad/data/models/{pydantic → extensions/pydantic}/converters.py +143 -16
- hammad/data/models/{base/fields.py → fields.py} +1 -1
- hammad/data/models/{base/model.py → model.py} +1 -1
- hammad/data/models/{base/utils.py → utils.py} +1 -1
- hammad/data/sql/__init__.py +23 -0
- hammad/data/sql/database.py +578 -0
- hammad/data/sql/types.py +141 -0
- hammad/data/types/__init__.py +1 -3
- hammad/data/types/file.py +3 -3
- hammad/data/types/multimodal/__init__.py +2 -2
- hammad/data/types/multimodal/audio.py +2 -2
- hammad/data/types/multimodal/image.py +2 -2
- hammad/formatting/__init__.py +9 -27
- hammad/formatting/json/__init__.py +8 -2
- hammad/formatting/json/converters.py +7 -1
- hammad/formatting/text/__init__.py +1 -1
- hammad/formatting/yaml/__init__.py +1 -1
- hammad/genai/__init__.py +78 -0
- hammad/genai/agents/__init__.py +1 -0
- hammad/genai/agents/types/__init__.py +35 -0
- hammad/genai/agents/types/history.py +277 -0
- hammad/genai/agents/types/tool.py +490 -0
- hammad/genai/embedding_models/__init__.py +41 -0
- hammad/{ai/embeddings/client/litellm_embeddings_client.py → genai/embedding_models/embedding_model.py} +47 -142
- hammad/genai/embedding_models/embedding_model_name.py +77 -0
- hammad/genai/embedding_models/embedding_model_request.py +65 -0
- hammad/{ai/embeddings/types.py → genai/embedding_models/embedding_model_response.py} +3 -3
- hammad/genai/embedding_models/run.py +161 -0
- hammad/genai/language_models/__init__.py +35 -0
- hammad/genai/language_models/_streaming.py +622 -0
- hammad/genai/language_models/_types.py +276 -0
- hammad/genai/language_models/_utils/__init__.py +31 -0
- hammad/genai/language_models/_utils/_completions.py +131 -0
- hammad/genai/language_models/_utils/_messages.py +89 -0
- hammad/genai/language_models/_utils/_requests.py +202 -0
- hammad/genai/language_models/_utils/_structured_outputs.py +124 -0
- hammad/genai/language_models/language_model.py +734 -0
- hammad/genai/language_models/language_model_request.py +135 -0
- hammad/genai/language_models/language_model_response.py +219 -0
- hammad/genai/language_models/language_model_response_chunk.py +53 -0
- hammad/genai/language_models/run.py +530 -0
- hammad/genai/multimodal_models.py +48 -0
- hammad/genai/rerank_models.py +26 -0
- hammad/logging/__init__.py +1 -1
- hammad/logging/decorators.py +1 -1
- hammad/logging/logger.py +2 -2
- hammad/mcp/__init__.py +1 -1
- hammad/mcp/client/__init__.py +35 -0
- hammad/mcp/client/client.py +105 -4
- hammad/mcp/client/client_service.py +10 -3
- hammad/mcp/servers/__init__.py +24 -0
- hammad/{performance/runtime → runtime}/__init__.py +2 -2
- hammad/{performance/runtime → runtime}/decorators.py +1 -1
- hammad/{performance/runtime → runtime}/run.py +1 -1
- hammad/service/__init__.py +1 -1
- hammad/service/create.py +3 -8
- hammad/service/decorators.py +8 -8
- hammad/typing/__init__.py +28 -0
- hammad/web/__init__.py +3 -3
- hammad/web/http/client.py +1 -1
- hammad/web/models.py +53 -21
- hammad/web/search/client.py +99 -52
- hammad/web/utils.py +13 -13
- hammad_python-0.0.16.dist-info/METADATA +191 -0
- hammad_python-0.0.16.dist-info/RECORD +110 -0
- hammad/ai/__init__.py +0 -1
- hammad/ai/_utils.py +0 -142
- hammad/ai/completions/__init__.py +0 -45
- hammad/ai/completions/client.py +0 -684
- hammad/ai/completions/create.py +0 -710
- hammad/ai/completions/settings.py +0 -100
- hammad/ai/completions/types.py +0 -792
- hammad/ai/completions/utils.py +0 -486
- hammad/ai/embeddings/__init__.py +0 -35
- hammad/ai/embeddings/client/__init__.py +0 -1
- hammad/ai/embeddings/client/base_embeddings_client.py +0 -26
- hammad/ai/embeddings/client/fastembed_text_embeddings_client.py +0 -200
- hammad/ai/embeddings/create.py +0 -159
- hammad/data/collections/base_collection.py +0 -58
- hammad/data/collections/searchable_collection.py +0 -556
- hammad/data/collections/vector_collection.py +0 -596
- hammad/data/databases/__init__.py +0 -21
- hammad/data/databases/database.py +0 -902
- hammad/data/models/base/__init__.py +0 -35
- hammad/data/models/pydantic/models/__init__.py +0 -28
- hammad/data/models/pydantic/models/arbitrary_model.py +0 -46
- hammad/data/models/pydantic/models/cacheable_model.py +0 -79
- hammad/data/models/pydantic/models/fast_model.py +0 -318
- hammad/data/models/pydantic/models/function_model.py +0 -176
- hammad/data/models/pydantic/models/subscriptable_model.py +0 -63
- hammad/performance/__init__.py +0 -36
- hammad/py.typed +0 -0
- hammad_python-0.0.14.dist-info/METADATA +0 -70
- hammad_python-0.0.14.dist-info/RECORD +0 -99
- {hammad_python-0.0.14.dist-info → hammad_python-0.0.16.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.14.dist-info → hammad_python-0.0.16.dist-info}/licenses/LICENSE +0 -0
hammad/mcp/client/client.py
CHANGED
@@ -8,7 +8,7 @@ from __future__ import annotations
|
|
8
8
|
import asyncio
|
9
9
|
from dataclasses import dataclass, field
|
10
10
|
from pathlib import Path
|
11
|
-
from typing import Any, Callable, Literal
|
11
|
+
from typing import Any, Callable, Literal, overload
|
12
12
|
import threading
|
13
13
|
import concurrent.futures
|
14
14
|
import inspect
|
@@ -20,9 +20,10 @@ try:
|
|
20
20
|
)
|
21
21
|
from openai.types.shared import FunctionDefinition as Function
|
22
22
|
except ImportError:
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
CallToolResult = Any
|
24
|
+
MCPTool = Any
|
25
|
+
OpenAITool = Any
|
26
|
+
Function = Any
|
26
27
|
|
27
28
|
from .client_service import (
|
28
29
|
MCPClientService,
|
@@ -521,3 +522,103 @@ class MCPClient:
|
|
521
522
|
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
522
523
|
"""Async context manager exit."""
|
523
524
|
await self.async_cleanup()
|
525
|
+
|
526
|
+
|
527
|
+
# -----------------------------------------------------------------------------
|
528
|
+
# Factory Function
|
529
|
+
# -----------------------------------------------------------------------------
|
530
|
+
|
531
|
+
|
532
|
+
@overload
|
533
|
+
def create_mcp_client(
|
534
|
+
type: Literal["stdio"],
|
535
|
+
*,
|
536
|
+
command: str,
|
537
|
+
args: list[str] | None = None,
|
538
|
+
env: dict[str, str] | None = None,
|
539
|
+
cwd: Path | str | None = None,
|
540
|
+
timeout: float = 30.0,
|
541
|
+
) -> MCPClient:
|
542
|
+
"""Create an MCP client with stdio transport."""
|
543
|
+
...
|
544
|
+
|
545
|
+
|
546
|
+
@overload
|
547
|
+
def create_mcp_client(
|
548
|
+
type: Literal["sse"],
|
549
|
+
*,
|
550
|
+
url: str,
|
551
|
+
timeout: float = 30.0,
|
552
|
+
) -> MCPClient:
|
553
|
+
"""Create an MCP client with SSE transport."""
|
554
|
+
...
|
555
|
+
|
556
|
+
|
557
|
+
@overload
|
558
|
+
def create_mcp_client(
|
559
|
+
type: Literal["http"],
|
560
|
+
*,
|
561
|
+
url: str,
|
562
|
+
timeout: float = 30.0,
|
563
|
+
) -> MCPClient:
|
564
|
+
"""Create an MCP client with HTTP transport."""
|
565
|
+
...
|
566
|
+
|
567
|
+
|
568
|
+
def create_mcp_client(
|
569
|
+
type: Literal["stdio", "sse", "http"],
|
570
|
+
*,
|
571
|
+
command: str | None = None,
|
572
|
+
args: list[str] | None = None,
|
573
|
+
env: dict[str, str] | None = None,
|
574
|
+
cwd: Path | str | None = None,
|
575
|
+
url: str | None = None,
|
576
|
+
timeout: float = 30.0,
|
577
|
+
) -> MCPClient:
|
578
|
+
"""Create an MCP client with the specified transport type.
|
579
|
+
|
580
|
+
Args:
|
581
|
+
service_type: The type of transport to use ("stdio", "sse", or "http").
|
582
|
+
command: Command to run for stdio transport.
|
583
|
+
args: Arguments for the command (stdio only).
|
584
|
+
env: Environment variables for the command (stdio only).
|
585
|
+
cwd: Working directory for the command (stdio only).
|
586
|
+
url: URL for SSE or HTTP transport.
|
587
|
+
timeout: Connection timeout in seconds.
|
588
|
+
|
589
|
+
Returns:
|
590
|
+
A configured MCPClient instance.
|
591
|
+
|
592
|
+
Raises:
|
593
|
+
ValueError: If required parameters for the transport type are missing.
|
594
|
+
"""
|
595
|
+
service_type = type
|
596
|
+
|
597
|
+
if service_type == "stdio":
|
598
|
+
if command is None:
|
599
|
+
raise ValueError("command is required for stdio transport")
|
600
|
+
|
601
|
+
service = MCPClientServiceStdio(
|
602
|
+
command=command,
|
603
|
+
args=args or [],
|
604
|
+
env=env or {},
|
605
|
+
cwd=Path(cwd) if cwd else None,
|
606
|
+
)
|
607
|
+
|
608
|
+
elif service_type == "sse":
|
609
|
+
if url is None:
|
610
|
+
raise ValueError("url is required for SSE transport")
|
611
|
+
|
612
|
+
service = MCPClientServiceSse(url=url)
|
613
|
+
|
614
|
+
elif service_type == "http":
|
615
|
+
if url is None:
|
616
|
+
raise ValueError("url is required for HTTP transport")
|
617
|
+
|
618
|
+
service = MCPClientServiceStreamableHttp(url=url)
|
619
|
+
|
620
|
+
else:
|
621
|
+
raise ValueError(f"Unsupported service_type: {service_type}")
|
622
|
+
|
623
|
+
settings = MCPClientSettings(timeout=timeout)
|
624
|
+
return MCPClient(service=service, settings=settings)
|
@@ -22,9 +22,16 @@ try:
|
|
22
22
|
from mcp.shared.message import SessionMessage
|
23
23
|
from mcp.types import CallToolResult, InitializeResult
|
24
24
|
except ImportError:
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
MCPTool = Any
|
26
|
+
ClientSession = Any
|
27
|
+
StdioServerParameters = Any
|
28
|
+
stdio_client = Any
|
29
|
+
sse_client = Any
|
30
|
+
GetSessionIdCallback = Any
|
31
|
+
streamablehttp_client = Any
|
32
|
+
SessionMessage = Any
|
33
|
+
CallToolResult = Any
|
34
|
+
InitializeResult = Any
|
28
35
|
|
29
36
|
import logging
|
30
37
|
|
hammad/mcp/servers/__init__.py
CHANGED
@@ -1 +1,25 @@
|
|
1
1
|
"""hammad.mcp.servers"""
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING
|
4
|
+
from ..._internal import create_getattr_importer
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from .launcher import (
|
8
|
+
launch_mcp_servers,
|
9
|
+
MCPServerStdioSettings,
|
10
|
+
MCPServerSseSettings,
|
11
|
+
MCPServerStreamableHttpSettings,
|
12
|
+
)
|
13
|
+
|
14
|
+
__all__ = (
|
15
|
+
"launch_mcp_servers",
|
16
|
+
"MCPServerStdioSettings",
|
17
|
+
"MCPServerSseSettings",
|
18
|
+
"MCPServerStreamableHttpSettings",
|
19
|
+
)
|
20
|
+
|
21
|
+
__getattr__ = create_getattr_importer(__all__)
|
22
|
+
|
23
|
+
def __dir__() -> list[str]:
|
24
|
+
"""Get the attributes of the servers module."""
|
25
|
+
return list(__all__)
|
hammad/service/__init__.py
CHANGED
@@ -21,7 +21,7 @@ resources within this submodule. This module contains function/decorators for:
|
|
21
21
|
"""
|
22
22
|
|
23
23
|
from typing import TYPE_CHECKING
|
24
|
-
from ..
|
24
|
+
from .._internal import create_getattr_importer
|
25
25
|
|
26
26
|
if TYPE_CHECKING:
|
27
27
|
from .create import (
|
hammad/service/create.py
CHANGED
@@ -24,7 +24,6 @@ try:
|
|
24
24
|
from fastapi import FastAPI, HTTPException
|
25
25
|
from pydantic import BaseModel, create_model
|
26
26
|
from uvicorn import Config, Server
|
27
|
-
import uvloop
|
28
27
|
except ImportError as e:
|
29
28
|
raise ImportError(
|
30
29
|
"Service dependencies not installed. Install with: pip install hammad-python[serve]"
|
@@ -58,7 +57,7 @@ class ServiceConfig:
|
|
58
57
|
timeout_graceful_shutdown: int = 30
|
59
58
|
access_log: bool = True
|
60
59
|
use_colors: bool = True
|
61
|
-
loop: str = "
|
60
|
+
loop: str = "asyncio"
|
62
61
|
|
63
62
|
|
64
63
|
class ServiceManager:
|
@@ -409,10 +408,6 @@ def create_service(
|
|
409
408
|
if not auto_start:
|
410
409
|
return app
|
411
410
|
|
412
|
-
# Set up uvloop if available
|
413
|
-
if hasattr(uvloop, "install"):
|
414
|
-
uvloop.install()
|
415
|
-
|
416
411
|
# Create and configure server
|
417
412
|
config_obj = Config(
|
418
413
|
app=app,
|
@@ -424,7 +419,7 @@ def create_service(
|
|
424
419
|
timeout_keep_alive=timeout_keep_alive,
|
425
420
|
access_log=access_log,
|
426
421
|
use_colors=use_colors,
|
427
|
-
loop="
|
422
|
+
loop="asyncio",
|
428
423
|
)
|
429
424
|
|
430
425
|
server = Server(config_obj)
|
@@ -502,7 +497,7 @@ async def async_create_service(
|
|
502
497
|
timeout_keep_alive=timeout_keep_alive,
|
503
498
|
access_log=access_log,
|
504
499
|
use_colors=use_colors,
|
505
|
-
loop="
|
500
|
+
loop="asyncio",
|
506
501
|
)
|
507
502
|
|
508
503
|
server = Server(config_obj)
|
hammad/service/decorators.py
CHANGED
@@ -124,7 +124,7 @@ def serve(
|
|
124
124
|
|
125
125
|
|
126
126
|
def serve_mcp(
|
127
|
-
|
127
|
+
fn: Optional[Union[Callable, List[Callable]]] = None,
|
128
128
|
*,
|
129
129
|
# MCP Server configuration
|
130
130
|
name: Optional[str] = None,
|
@@ -162,7 +162,7 @@ def serve_mcp(
|
|
162
162
|
4. As a function with multiple functions: serve_mcp([func1, func2])
|
163
163
|
|
164
164
|
Args:
|
165
|
-
|
165
|
+
fn: Function or list of functions to serve
|
166
166
|
name: MCP server name
|
167
167
|
instructions: Server instructions
|
168
168
|
transport: Transport type (stdio, sse, streamable-http)
|
@@ -270,16 +270,16 @@ def serve_mcp(
|
|
270
270
|
return funcs
|
271
271
|
|
272
272
|
# Handle different call patterns
|
273
|
-
if
|
273
|
+
if fn is None:
|
274
274
|
# Called as @serve_mcp(...) - return decorator
|
275
275
|
return decorator
|
276
|
-
elif callable(
|
276
|
+
elif callable(fn):
|
277
277
|
# Called as @serve_mcp (no parentheses) or serve_mcp(single_func)
|
278
|
-
return decorator(
|
279
|
-
elif isinstance(
|
278
|
+
return decorator(fn)
|
279
|
+
elif isinstance(fn, list):
|
280
280
|
# Called as serve_mcp([func1, func2, ...])
|
281
|
-
return handle_multiple_functions(
|
281
|
+
return handle_multiple_functions(fn)
|
282
282
|
else:
|
283
283
|
raise TypeError(
|
284
|
-
f"Expected callable or list of callables, got {type(
|
284
|
+
f"Expected callable or list of callables, got {type(fn)}"
|
285
285
|
)
|
hammad/typing/__init__.py
CHANGED
@@ -6,6 +6,7 @@ core `typing` module, `typing_extensions`, `typing_inspect` and other
|
|
6
6
|
resources."""
|
7
7
|
|
8
8
|
from typing import Any, TYPE_CHECKING
|
9
|
+
import inspect
|
9
10
|
import typing_inspect as inspection
|
10
11
|
|
11
12
|
try:
|
@@ -190,6 +191,7 @@ __all__ = (
|
|
190
191
|
"get_last_origin",
|
191
192
|
"get_generic_bases",
|
192
193
|
"get_typed_dict_keys",
|
194
|
+
"is_function",
|
193
195
|
)
|
194
196
|
|
195
197
|
|
@@ -202,6 +204,32 @@ class TypingError(Exception):
|
|
202
204
|
# ------------------------------------------------------------------------
|
203
205
|
|
204
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
|
+
|
205
233
|
def is_pydantic_basemodel(t: "Any") -> bool:
|
206
234
|
"""Check if an object is a Pydantic BaseModel class or instance using duck typing.
|
207
235
|
|
hammad/web/__init__.py
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
"""hammad.web"""
|
2
2
|
|
3
3
|
from typing import TYPE_CHECKING
|
4
|
-
from ..
|
4
|
+
from .._internal import create_getattr_importer
|
5
5
|
|
6
6
|
if TYPE_CHECKING:
|
7
7
|
from .utils import (
|
8
8
|
run_web_request,
|
9
9
|
read_web_page,
|
10
10
|
read_web_pages,
|
11
|
-
|
11
|
+
web_search,
|
12
12
|
search_news,
|
13
13
|
extract_page_links,
|
14
14
|
)
|
@@ -20,7 +20,7 @@ __all__ = (
|
|
20
20
|
"run_web_request",
|
21
21
|
"read_web_page",
|
22
22
|
"read_web_pages",
|
23
|
-
"
|
23
|
+
"web_search",
|
24
24
|
"search_news",
|
25
25
|
"extract_page_links",
|
26
26
|
"AsyncHttpClient",
|
hammad/web/http/client.py
CHANGED
hammad/web/models.py
CHANGED
@@ -6,7 +6,8 @@ Output models for web search and parsing functionality.
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
from typing import List, Dict, Any, Optional, Union
|
9
|
-
|
9
|
+
|
10
|
+
from pydantic import BaseModel, Field
|
10
11
|
|
11
12
|
|
12
13
|
# -----------------------------------------------------------------------------
|
@@ -14,7 +15,7 @@ from typing_extensions import TypedDict, NotRequired
|
|
14
15
|
# -----------------------------------------------------------------------------
|
15
16
|
|
16
17
|
|
17
|
-
class SearchResult(
|
18
|
+
class SearchResult(BaseModel):
|
18
19
|
"""DuckDuckGo web search result."""
|
19
20
|
|
20
21
|
title: str
|
@@ -27,7 +28,7 @@ class SearchResult(TypedDict):
|
|
27
28
|
"""Description/snippet of the search result."""
|
28
29
|
|
29
30
|
|
30
|
-
class NewsResult(
|
31
|
+
class NewsResult(BaseModel):
|
31
32
|
"""DuckDuckGo news search result."""
|
32
33
|
|
33
34
|
date: str
|
@@ -54,7 +55,7 @@ class NewsResult(TypedDict):
|
|
54
55
|
# -----------------------------------------------------------------------------
|
55
56
|
|
56
57
|
|
57
|
-
class LinkInfo(
|
58
|
+
class LinkInfo(BaseModel):
|
58
59
|
"""Information about a link extracted from a web page."""
|
59
60
|
|
60
61
|
href: str
|
@@ -64,7 +65,7 @@ class LinkInfo(TypedDict):
|
|
64
65
|
"""Text content of the link."""
|
65
66
|
|
66
67
|
|
67
|
-
class ImageInfo(
|
68
|
+
class ImageInfo(BaseModel):
|
68
69
|
"""Information about an image extracted from a web page."""
|
69
70
|
|
70
71
|
src: str
|
@@ -77,7 +78,7 @@ class ImageInfo(TypedDict):
|
|
77
78
|
"""Title attribute of the image."""
|
78
79
|
|
79
80
|
|
80
|
-
class SelectedElement(
|
81
|
+
class SelectedElement(BaseModel):
|
81
82
|
"""Information about a selected element from CSS selector."""
|
82
83
|
|
83
84
|
tag: str
|
@@ -93,7 +94,7 @@ class SelectedElement(TypedDict):
|
|
93
94
|
"""Attributes of the element."""
|
94
95
|
|
95
96
|
|
96
|
-
class WebPageResult(
|
97
|
+
class WebPageResult(BaseModel):
|
97
98
|
"""Result from parsing a single web page."""
|
98
99
|
|
99
100
|
url: str
|
@@ -121,7 +122,7 @@ class WebPageResult(TypedDict):
|
|
121
122
|
"""List of elements matching the CSS selector."""
|
122
123
|
|
123
124
|
|
124
|
-
class WebPageErrorResult(
|
125
|
+
class WebPageErrorResult(BaseModel):
|
125
126
|
"""Result from a failed web page parsing attempt."""
|
126
127
|
|
127
128
|
url: str
|
@@ -130,7 +131,7 @@ class WebPageErrorResult(TypedDict):
|
|
130
131
|
error: str
|
131
132
|
"""Error message describing what went wrong."""
|
132
133
|
|
133
|
-
status_code:
|
134
|
+
status_code: Optional[int]
|
134
135
|
"""Always None for error results."""
|
135
136
|
|
136
137
|
content_type: str
|
@@ -157,7 +158,7 @@ class WebPageErrorResult(TypedDict):
|
|
157
158
|
# -----------------------------------------------------------------------------
|
158
159
|
|
159
160
|
|
160
|
-
class ExtractedLink(
|
161
|
+
class ExtractedLink(BaseModel):
|
161
162
|
"""Information about a link extracted with classification."""
|
162
163
|
|
163
164
|
href: str
|
@@ -181,7 +182,7 @@ class ExtractedLink(TypedDict):
|
|
181
182
|
# -----------------------------------------------------------------------------
|
182
183
|
|
183
184
|
|
184
|
-
class HttpResponse(
|
185
|
+
class HttpResponse(BaseModel):
|
185
186
|
"""HTTP response from web requests."""
|
186
187
|
|
187
188
|
status_code: int
|
@@ -199,10 +200,14 @@ class HttpResponse(TypedDict):
|
|
199
200
|
elapsed: float
|
200
201
|
"""Time elapsed for the request in seconds."""
|
201
202
|
|
202
|
-
|
203
|
+
# NOTE: This is a workaround to avoid the issue with the `json` field
|
204
|
+
# might consider moving to dataclasses
|
205
|
+
json_data: Optional[Dict[str, Any]] = Field(
|
206
|
+
alias="json"
|
207
|
+
)
|
203
208
|
"""Parsed JSON content if Content-Type is JSON."""
|
204
209
|
|
205
|
-
text:
|
210
|
+
text: str
|
206
211
|
"""Text content if response is text-based."""
|
207
212
|
|
208
213
|
|
@@ -211,17 +216,44 @@ class HttpResponse(TypedDict):
|
|
211
216
|
# -----------------------------------------------------------------------------
|
212
217
|
|
213
218
|
|
214
|
-
WebPageResults
|
215
|
-
"""Results from batch web page parsing operations."""
|
219
|
+
class WebPageResults(BaseModel):
|
220
|
+
"""Results from batch web page parsing operations."""
|
221
|
+
|
222
|
+
urls: List[str]
|
223
|
+
"""URLs used for the web page parsing operations."""
|
224
|
+
|
225
|
+
results: List[Union[WebPageResult, WebPageErrorResult]]
|
226
|
+
"""List of results from batch web page parsing operations."""
|
227
|
+
|
228
|
+
|
229
|
+
class SearchResults(BaseModel):
|
230
|
+
"""Results from web search operations."""
|
231
|
+
|
232
|
+
query: str
|
233
|
+
"""Query used for the web search operations."""
|
216
234
|
|
217
|
-
|
218
|
-
"""
|
235
|
+
results: List[SearchResult]
|
236
|
+
"""List of results from web search operations."""
|
219
237
|
|
220
|
-
NewsResults = List[NewsResult]
|
221
|
-
"""Results from news search operations."""
|
222
238
|
|
223
|
-
|
224
|
-
"""Results from
|
239
|
+
class NewsResults(BaseModel):
|
240
|
+
"""Results from news search operations."""
|
241
|
+
|
242
|
+
query: str
|
243
|
+
"""Query used for the news search operations."""
|
244
|
+
|
245
|
+
results: List[NewsResult]
|
246
|
+
"""List of results from news search operations."""
|
247
|
+
|
248
|
+
|
249
|
+
class ExtractedLinks(BaseModel):
|
250
|
+
"""Results from link extraction operations."""
|
251
|
+
|
252
|
+
url: str
|
253
|
+
"""URL used for the link extraction operations."""
|
254
|
+
|
255
|
+
results: List[ExtractedLink]
|
256
|
+
"""List of results from link extraction operations."""
|
225
257
|
|
226
258
|
|
227
259
|
__all__ = (
|