utcp-socket 1.0.2__tar.gz

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.
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: utcp-socket
3
+ Version: 1.0.2
4
+ Summary: UTCP communication protocol plugin for TCP and UDP protocols. (Work in progress)
5
+ Author: UTCP Contributors
6
+ License-Expression: MPL-2.0
7
+ Project-URL: Homepage, https://utcp.io
8
+ Project-URL: Source, https://github.com/universal-tool-calling-protocol/python-utcp
9
+ Project-URL: Issues, https://github.com/universal-tool-calling-protocol/python-utcp/issues
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: pydantic>=2.0
17
+ Requires-Dist: utcp>=1.0
18
+ Provides-Extra: dev
19
+ Requires-Dist: build; extra == "dev"
20
+ Requires-Dist: pytest; extra == "dev"
21
+ Requires-Dist: pytest-asyncio; extra == "dev"
22
+ Requires-Dist: pytest-cov; extra == "dev"
23
+ Requires-Dist: coverage; extra == "dev"
24
+ Requires-Dist: twine; extra == "dev"
25
+
26
+ # UTCP Socket Plugin (UDP/TCP)
27
+
28
+ This plugin adds UDP and TCP communication protocols to UTCP 1.0.
29
+
30
+ ## Running Tests
31
+
32
+ Prerequisites:
33
+ - Python 3.10+
34
+ - `pip`
35
+ - (Optional) a virtual environment
36
+
37
+ 1) Install core and the socket plugin in editable mode with dev extras:
38
+
39
+ ```bash
40
+ pip install -e "./core[dev]"
41
+ pip install -e ./plugins/communication_protocols/socket[dev]
42
+ ```
43
+
44
+ 2) Run the socket plugin tests:
45
+
46
+ ```bash
47
+ python -m pytest plugins/communication_protocols/socket/tests -v
48
+ ```
49
+
50
+ 3) Run a single test or filter by keyword:
51
+
52
+ ```bash
53
+ # One file
54
+ python -m pytest plugins/communication_protocols/socket/tests/test_tcp_communication_protocol.py -v
55
+
56
+ # Filter by keyword (e.g., delimiter framing)
57
+ python -m pytest plugins/communication_protocols/socket/tests -k delimiter -q
58
+ ```
59
+
60
+ 4) Optional end-to-end sanity check (mock UDP/TCP servers):
61
+
62
+ ```bash
63
+ python scripts/socket_sanity.py
64
+ ```
65
+
66
+ Notes:
67
+ - On Windows, your firewall may prompt the first time tests open UDP/TCP sockets; allow access or run as admin if needed.
68
+ - Tests use `pytest-asyncio`. The dev extras installed above provide required dependencies.
69
+ - Streaming is single-chunk by design, consistent with HTTP/Text transports. Multi-chunk streaming can be added later behind provider configuration.
@@ -0,0 +1,44 @@
1
+ # UTCP Socket Plugin (UDP/TCP)
2
+
3
+ This plugin adds UDP and TCP communication protocols to UTCP 1.0.
4
+
5
+ ## Running Tests
6
+
7
+ Prerequisites:
8
+ - Python 3.10+
9
+ - `pip`
10
+ - (Optional) a virtual environment
11
+
12
+ 1) Install core and the socket plugin in editable mode with dev extras:
13
+
14
+ ```bash
15
+ pip install -e "./core[dev]"
16
+ pip install -e ./plugins/communication_protocols/socket[dev]
17
+ ```
18
+
19
+ 2) Run the socket plugin tests:
20
+
21
+ ```bash
22
+ python -m pytest plugins/communication_protocols/socket/tests -v
23
+ ```
24
+
25
+ 3) Run a single test or filter by keyword:
26
+
27
+ ```bash
28
+ # One file
29
+ python -m pytest plugins/communication_protocols/socket/tests/test_tcp_communication_protocol.py -v
30
+
31
+ # Filter by keyword (e.g., delimiter framing)
32
+ python -m pytest plugins/communication_protocols/socket/tests -k delimiter -q
33
+ ```
34
+
35
+ 4) Optional end-to-end sanity check (mock UDP/TCP servers):
36
+
37
+ ```bash
38
+ python scripts/socket_sanity.py
39
+ ```
40
+
41
+ Notes:
42
+ - On Windows, your firewall may prompt the first time tests open UDP/TCP sockets; allow access or run as admin if needed.
43
+ - Tests use `pytest-asyncio`. The dev extras installed above provide required dependencies.
44
+ - Streaming is single-chunk by design, consistent with HTTP/Text transports. Multi-chunk streaming can be added later behind provider configuration.
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "utcp-socket"
7
+ version = "1.0.2"
8
+ authors = [
9
+ { name = "UTCP Contributors" },
10
+ ]
11
+ description = "UTCP communication protocol plugin for TCP and UDP protocols. (Work in progress)"
12
+ readme = "README.md"
13
+ requires-python = ">=3.10"
14
+ dependencies = [
15
+ "pydantic>=2.0",
16
+ "utcp>=1.0"
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 4 - Beta",
20
+ "Intended Audience :: Developers",
21
+ "Programming Language :: Python :: 3",
22
+ "Operating System :: OS Independent",
23
+ ]
24
+ license = "MPL-2.0"
25
+
26
+ [project.optional-dependencies]
27
+ dev = [
28
+ "build",
29
+ "pytest",
30
+ "pytest-asyncio",
31
+ "pytest-cov",
32
+ "coverage",
33
+ "twine",
34
+ ]
35
+
36
+ [project.urls]
37
+ Homepage = "https://utcp.io"
38
+ Source = "https://github.com/universal-tool-calling-protocol/python-utcp"
39
+ Issues = "https://github.com/universal-tool-calling-protocol/python-utcp/issues"
40
+
41
+ [project.entry-points."utcp.plugins"]
42
+ socket = "utcp_socket:register"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,18 @@
1
+ from utcp.plugins.discovery import register_communication_protocol, register_call_template
2
+ from utcp_socket.tcp_communication_protocol import TCPTransport
3
+ from utcp_socket.udp_communication_protocol import UDPTransport
4
+ from utcp_socket.tcp_call_template import TCPProviderSerializer
5
+ from utcp_socket.udp_call_template import UDPProviderSerializer
6
+
7
+
8
+ def register() -> None:
9
+ # Register communication protocols
10
+ register_communication_protocol("tcp", TCPTransport())
11
+ register_communication_protocol("udp", UDPTransport())
12
+
13
+ # Register call templates and their serializers
14
+ register_call_template("tcp", TCPProviderSerializer())
15
+ register_call_template("udp", UDPProviderSerializer())
16
+
17
+
18
+ __all__ = ["register"]
@@ -0,0 +1,99 @@
1
+ from utcp.data.call_template import CallTemplate
2
+ from typing import Optional, Literal
3
+ from pydantic import Field
4
+ from utcp.interfaces.serializer import Serializer
5
+ from utcp.exceptions import UtcpSerializerValidationError
6
+ import traceback
7
+
8
+ class TCPProvider(CallTemplate):
9
+ """Provider configuration for raw TCP socket tools.
10
+
11
+ Enables direct communication with TCP servers using custom protocols.
12
+ Supports flexible request formatting, response decoding, and multiple
13
+ framing strategies for message boundaries.
14
+
15
+ Request Data Handling:
16
+ - 'json' format: Arguments formatted as JSON object
17
+ - 'text' format: Template-based with UTCP_ARG_argname_UTCP_ARG placeholders
18
+
19
+ Response Data Handling:
20
+ - If response_byte_format is None: Returns raw bytes
21
+ - If response_byte_format is encoding string: Decodes bytes to text
22
+
23
+ TCP Stream Framing Options:
24
+ 1. Length-prefix: Set framing_strategy='length_prefix' + length_prefix_bytes
25
+ 2. Delimiter-based: Set framing_strategy='delimiter' + message_delimiter
26
+ 3. Fixed-length: Set framing_strategy='fixed_length' + fixed_message_length
27
+ 4. Stream-based: Set framing_strategy='stream' (reads until connection closes)
28
+
29
+ Attributes:
30
+ call_template_type: Always "tcp" for TCP providers.
31
+ host: The hostname or IP address of the TCP server.
32
+ port: The port number of the TCP server.
33
+ request_data_format: Format for request data ('json' or 'text').
34
+ request_data_template: Template string for 'text' format with placeholders.
35
+ response_byte_format: Encoding for response decoding (None for raw bytes).
36
+ framing_strategy: Method for detecting message boundaries.
37
+ length_prefix_bytes: Number of bytes for length prefix (1, 2, 4, or 8).
38
+ length_prefix_endian: Byte order for length prefix ('big' or 'little').
39
+ message_delimiter: Delimiter string for message boundaries.
40
+ fixed_message_length: Fixed length in bytes for each message.
41
+ max_response_size: Maximum bytes to read for stream-based framing.
42
+ timeout: Connection timeout in milliseconds.
43
+ auth: Always None - TCP providers don't support authentication.
44
+ """
45
+
46
+ call_template_type: Literal["tcp"] = "tcp"
47
+ host: str
48
+ port: int
49
+ request_data_format: Literal["json", "text"] = "json"
50
+ request_data_template: Optional[str] = None
51
+ response_byte_format: Optional[str] = Field(default="utf-8", description="Encoding to decode response bytes. If None, returns raw bytes.")
52
+ # TCP Framing Strategy
53
+ framing_strategy: Literal["length_prefix", "delimiter", "fixed_length", "stream"] = Field(
54
+ default="stream",
55
+ description="Strategy for framing TCP messages"
56
+ )
57
+ # Length-prefix framing options
58
+ length_prefix_bytes: Literal[1, 2, 4, 8] = Field(
59
+ default=4,
60
+ description="Number of bytes for length prefix (1, 2, 4, or 8). Used with 'length_prefix' framing."
61
+ )
62
+ length_prefix_endian: Literal["big", "little"] = Field(
63
+ default="big",
64
+ description="Byte order for length prefix. Used with 'length_prefix' framing."
65
+ )
66
+ # Delimiter-based framing options
67
+ message_delimiter: str = Field(
68
+ default='\x00',
69
+ description="Delimiter to detect end of TCP response (e.g., '\n', '\r\n', '\x00'). Used with 'delimiter' framing."
70
+ )
71
+ interpret_escape_sequences: bool = Field(
72
+ default=True,
73
+ description="If True, interpret Python-style escape sequences in message_delimiter (e.g., '\\n', '\\r\\n', '\\x00'). If False, use the delimiter literally as provided."
74
+ )
75
+ # Fixed-length framing options
76
+ fixed_message_length: Optional[int] = Field(
77
+ default=None,
78
+ description="Fixed length of each message in bytes. Used with 'fixed_length' framing."
79
+ )
80
+ # Stream-based options
81
+ max_response_size: int = Field(
82
+ default=65536,
83
+ description="Maximum bytes to read from TCP stream. Used with 'stream' framing."
84
+ )
85
+ timeout: int = 30000
86
+ auth: None = None
87
+
88
+
89
+ class TCPProviderSerializer(Serializer[TCPProvider]):
90
+ def to_dict(self, obj: TCPProvider) -> dict:
91
+ return obj.model_dump()
92
+
93
+ def validate_dict(self, data: dict) -> TCPProvider:
94
+ try:
95
+ return TCPProvider.model_validate(data)
96
+ except Exception as e:
97
+ raise UtcpSerializerValidationError(
98
+ f"Invalid TCPProvider: {e}\n{traceback.format_exc()}"
99
+ )