-
Notifications
You must be signed in to change notification settings - Fork 38
1.0.0 #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
1.0.0 #43
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
c77043d
initial structure
h3xxit 784d620
Core update should be finished
h3xxit dac8b59
Move openapi converter and update imports
h3xxit db48615
Http protocol implementation
h3xxit e21d93f
Finish up tests for http
h3xxit 68732ab
Add text and cli communication protocols
h3xxit d092f51
Move files for gql
h3xxit 23ac4b1
Update MCP communication protocol
h3xxit be3abf7
Move udp and tcp tests
h3xxit a6b864a
all tests pass
h3xxit 5deafee
Merge branch 'dev' into 1.0-draft
h3xxit 6bc47ab
Update pyproject.toml
h3xxit 86ecf1e
Fix issues
h3xxit 2de03d8
Update Readme to 1.0.0
h3xxit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| [build-system] | ||
| requires = ["setuptools>=61.0"] | ||
| build-backend = "setuptools.build_meta" | ||
|
|
||
| [project] | ||
| name = "utcp" | ||
| version = "1.0.0" | ||
| authors = [ | ||
| { name = "UTCP Contributors" }, | ||
| ] | ||
| description = "Universal Tool Calling Protocol (UTCP) client library for Python" | ||
| readme = "README.md" | ||
| requires-python = ">=3.10" | ||
| dependencies = [ | ||
| "pydantic>=2.0", | ||
| "python-dotenv>=1.0", | ||
| "tomli>=2.0", | ||
| ] | ||
| classifiers = [ | ||
| "Development Status :: 4 - Beta", | ||
| "Intended Audience :: Developers", | ||
| "Programming Language :: Python :: 3", | ||
| "Operating System :: OS Independent", | ||
| ] | ||
| license = "MPL-2.0" | ||
|
|
||
| [project.optional-dependencies] | ||
| dev = [ | ||
| "build", | ||
| "pytest", | ||
| "pytest-asyncio", | ||
| "pytest-cov", | ||
| "coverage", | ||
| "twine", | ||
| ] | ||
|
|
||
| [project.urls] | ||
| Homepage = "https://utcp.io" | ||
| Source = "https://github.com/universal-tool-calling-protocol/python-utcp" | ||
| Issues = "https://github.com/universal-tool-calling-protocol/python-utcp/issues" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import logging | ||
| import sys | ||
|
|
||
| logger = logging.getLogger("utcp") | ||
|
|
||
| if not logger.handlers: # Only add default handler if user didn't configure logging | ||
| handler = logging.StreamHandler(sys.stderr) | ||
| handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d - %(message)s")) | ||
| logger.addHandler(handler) | ||
| logger.setLevel(logging.INFO) |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| """Authentication schemes for UTCP providers. | ||
|
|
||
| This module defines the authentication models supported by UTCP providers, | ||
| including API key authentication, basic authentication, and OAuth2. | ||
| """ | ||
|
|
||
| from abc import ABC | ||
| from pydantic import BaseModel | ||
| from utcp.interfaces.serializer import Serializer | ||
| from utcp.exceptions import UtcpSerializerValidationError | ||
| import traceback | ||
|
|
||
| class Auth(BaseModel, ABC): | ||
| """Authentication details for a provider. | ||
|
|
||
| Attributes: | ||
| auth_type: The authentication type identifier. | ||
| """ | ||
| auth_type: str | ||
|
|
||
| class AuthSerializer(Serializer[Auth]): | ||
| auth_serializers: dict[str, Serializer[Auth]] = {} | ||
|
|
||
| def to_dict(self, obj: Auth) -> dict: | ||
| return AuthSerializer.auth_serializers[obj.auth_type].to_dict(obj) | ||
|
|
||
| def validate_dict(self, obj: dict) -> Auth: | ||
| try: | ||
| return AuthSerializer.auth_serializers[obj["auth_type"]].validate_dict(obj) | ||
| except KeyError: | ||
| raise ValueError(f"Invalid auth type: {obj['auth_type']}") | ||
h3xxit marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| except Exception as e: | ||
| raise UtcpSerializerValidationError("Invalid Auth: " + traceback.format_exc()) from e | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| from utcp.data.auth_implementations.api_key_auth import ApiKeyAuth, ApiKeyAuthSerializer | ||
| from utcp.data.auth_implementations.basic_auth import BasicAuth, BasicAuthSerializer | ||
| from utcp.data.auth_implementations.oauth2_auth import OAuth2Auth, OAuth2AuthSerializer | ||
|
|
||
| __all__ = [ | ||
| "ApiKeyAuth", | ||
| "BasicAuth", | ||
| "OAuth2Auth", | ||
| "ApiKeyAuthSerializer", | ||
| "BasicAuthSerializer", | ||
| "OAuth2AuthSerializer" | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| from utcp.data.auth import Auth | ||
| from utcp.interfaces.serializer import Serializer | ||
| from pydantic import Field, ValidationError | ||
| from typing import Literal | ||
| from utcp.exceptions import UtcpSerializerValidationError | ||
|
|
||
| class ApiKeyAuth(Auth): | ||
| """Authentication using an API key. | ||
|
|
||
| The key can be provided directly or sourced from an environment variable. | ||
| Supports placement in headers, query parameters, or cookies. | ||
|
|
||
| Attributes: | ||
| auth_type: The authentication type identifier, always "api_key". | ||
| api_key: The API key for authentication. Values starting with '$' or formatted as '${}' are | ||
| treated as an injected variable from environment or configuration. | ||
| var_name: The name of the header, query parameter, or cookie that | ||
| contains the API key. | ||
| location: Where to include the API key (header, query parameter, or cookie). | ||
| """ | ||
|
|
||
| auth_type: Literal["api_key"] = "api_key" | ||
| api_key: str = Field(..., description="The API key for authentication. Values starting with '$' or formatted as '${}' are treated as an injected variable from environment or configuration. This is the recommended way to provide API keys.") | ||
| var_name: str = Field( | ||
| "X-Api-Key", description="The name of the header, query parameter, cookie or other container for the API key." | ||
| ) | ||
| location: Literal["header", "query", "cookie"] = Field( | ||
| "header", description="Where to include the API key (header, query parameter, or cookie)." | ||
| ) | ||
|
|
||
|
|
||
| class ApiKeyAuthSerializer(Serializer[ApiKeyAuth]): | ||
| def to_dict(self, obj: ApiKeyAuth) -> dict: | ||
| return obj.model_dump() | ||
|
|
||
| def validate_dict(self, obj: dict) -> ApiKeyAuth: | ||
| try: | ||
| return ApiKeyAuth.model_validate(obj) | ||
| except ValidationError as e: | ||
| raise UtcpSerializerValidationError(f"Invalid ApiKeyAuth: {e}") from e | ||
| except Exception as e: | ||
| raise UtcpSerializerValidationError("An unexpected error occurred during ApiKeyAuth validation.") from e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| from utcp.data.auth import Auth | ||
| from utcp.interfaces.serializer import Serializer | ||
| from pydantic import Field, ValidationError | ||
| from typing import Literal | ||
| from utcp.exceptions import UtcpSerializerValidationError | ||
|
|
||
| class BasicAuth(Auth): | ||
| """Authentication using HTTP Basic Authentication. | ||
|
|
||
| Uses the standard HTTP Basic Authentication scheme with username and password | ||
| encoded in the Authorization header. | ||
|
|
||
| Attributes: | ||
| auth_type: The authentication type identifier, always "basic". | ||
| username: The username for basic authentication. Recommended to use injected variables. | ||
| password: The password for basic authentication. Recommended to use injected variables. | ||
| """ | ||
|
|
||
| auth_type: Literal["basic"] = "basic" | ||
| username: str = Field(..., description="The username for basic authentication.") | ||
| password: str = Field(..., description="The password for basic authentication.") | ||
|
|
||
|
|
||
| class BasicAuthSerializer(Serializer[BasicAuth]): | ||
| def to_dict(self, obj: BasicAuth) -> dict: | ||
| return obj.model_dump() | ||
|
|
||
| def validate_dict(self, obj: dict) -> BasicAuth: | ||
| try: | ||
| return BasicAuth.model_validate(obj) | ||
| except ValidationError as e: | ||
| raise UtcpSerializerValidationError(f"Invalid BasicAuth: {e}") from e | ||
| except Exception as e: | ||
| raise UtcpSerializerValidationError("An unexpected error occurred during BasicAuth validation.") from e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| from utcp.data.auth import Auth | ||
| from utcp.interfaces.serializer import Serializer | ||
| from utcp.exceptions import UtcpSerializerValidationError | ||
| from pydantic import Field, ValidationError | ||
| from typing import Literal, Optional | ||
|
|
||
|
|
||
| class OAuth2Auth(Auth): | ||
| """Authentication using OAuth2 client credentials flow. | ||
|
|
||
| Implements the OAuth2 client credentials grant type for machine-to-machine | ||
| authentication. The client automatically handles token acquisition and refresh. | ||
|
|
||
| Attributes: | ||
| auth_type: The authentication type identifier, always "oauth2". | ||
| token_url: The URL endpoint to fetch the OAuth2 access token from. Recommended to use injected variables. | ||
| client_id: The OAuth2 client identifier. Recommended to use injected variables. | ||
| client_secret: The OAuth2 client secret. Recommended to use injected variables. | ||
| scope: Optional scope parameter to limit the access token's permissions. | ||
| """ | ||
|
|
||
| auth_type: Literal["oauth2"] = "oauth2" | ||
| token_url: str = Field(..., description="The URL to fetch the OAuth2 token from.") | ||
| client_id: str = Field(..., description="The OAuth2 client ID.") | ||
| client_secret: str = Field(..., description="The OAuth2 client secret.") | ||
| scope: Optional[str] = Field(None, description="The OAuth2 scope.") | ||
|
|
||
|
|
||
| class OAuth2AuthSerializer(Serializer[OAuth2Auth]): | ||
| def to_dict(self, obj: OAuth2Auth) -> dict: | ||
| return obj.model_dump() | ||
|
|
||
| def validate_dict(self, obj: dict) -> OAuth2Auth: | ||
| try: | ||
| return OAuth2Auth.model_validate(obj) | ||
| except ValidationError as e: | ||
| raise UtcpSerializerValidationError(f"Invalid OAuth2Auth: {e}") from e | ||
| except Exception as e: | ||
| raise UtcpSerializerValidationError("An unexpected error occurred during OAuth2Auth validation.") from e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| """Provider configurations for UTCP tool providers. | ||
|
|
||
| This module defines the provider models and configurations for all supported | ||
| transport protocols in UTCP. Each provider type encapsulates the necessary | ||
| configuration to connect to and interact with tools through different | ||
| communication channels. | ||
|
|
||
| Supported provider types: | ||
| - HTTP: RESTful HTTP/HTTPS APIs | ||
| - SSE: Server-Sent Events for streaming | ||
| - HTTP Stream: HTTP Chunked Transfer Encoding | ||
| - CLI: Command Line Interface tools | ||
| - WebSocket: Bidirectional WebSocket connections (WIP) | ||
| - gRPC: Google Remote Procedure Call (WIP) | ||
| - GraphQL: GraphQL query language | ||
| - TCP: Raw TCP socket connections | ||
| - UDP: User Datagram Protocol | ||
| - WebRTC: Web Real-Time Communication (WIP) | ||
| - MCP: Model Context Protocol | ||
| - Text: Text file-based providers | ||
| """ | ||
|
|
||
| from typing import List, Optional, Union | ||
| from pydantic import BaseModel, field_serializer, field_validator, Field | ||
| import uuid | ||
| from utcp.interfaces.serializer import Serializer | ||
| from utcp.exceptions import UtcpSerializerValidationError | ||
| import traceback | ||
| from utcp.data.auth import Auth, AuthSerializer | ||
|
|
||
| class CallTemplate(BaseModel): | ||
| """Base class for all UTCP tool providers. | ||
|
|
||
| This is the abstract base class that all specific call template implementations | ||
| inherit from. It provides the common fields that every provider must have. | ||
|
|
||
| Attributes: | ||
| name: Unique identifier for the provider. Defaults to a random UUID hex string. | ||
| Should be unique across all providers and recommended to be set to a human-readable name. | ||
| Can only contain letters, numbers and underscores. All special characters must be replaced with underscores. | ||
| call_template_type: The transport protocol type used by this provider. | ||
| """ | ||
|
|
||
| name: str = Field(default_factory=lambda: uuid.uuid4().hex) | ||
| call_template_type: str | ||
| auth: Optional[Auth] = None | ||
|
|
||
| @field_serializer("auth") | ||
| def serialize_auth(self, auth: Optional[Auth]): | ||
| if auth is None: | ||
| return None | ||
| return AuthSerializer().to_dict(auth) | ||
|
|
||
| @field_validator("auth", mode="before") | ||
| @classmethod | ||
| def validate_auth(cls, v: Optional[Union[Auth, dict]]): | ||
| if v is None: | ||
| return None | ||
| if isinstance(v, Auth): | ||
| return v | ||
| return AuthSerializer().validate_dict(v) | ||
|
|
||
| class CallTemplateSerializer(Serializer[CallTemplate]): | ||
| call_template_serializers: dict[str, Serializer[CallTemplate]] = {} | ||
|
|
||
| def to_dict(self, obj: CallTemplate) -> dict: | ||
| return CallTemplateSerializer.call_template_serializers[obj.call_template_type].to_dict(obj) | ||
|
|
||
| def validate_dict(self, obj: dict) -> CallTemplate: | ||
| try: | ||
| return CallTemplateSerializer.call_template_serializers[obj["call_template_type"]].validate_dict(obj) | ||
| except KeyError: | ||
| raise ValueError(f"Invalid call template type: {obj['call_template_type']}") | ||
| except Exception as e: | ||
| raise UtcpSerializerValidationError("Invalid CallTemplate: " + traceback.format_exc()) from e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| from utcp.data.call_template import CallTemplate | ||
| from utcp.data.utcp_manual import UtcpManual | ||
| from pydantic import BaseModel, Field | ||
| from typing import List | ||
|
|
||
| class RegisterManualResult(BaseModel): | ||
| manual_call_template: CallTemplate | ||
| manual: UtcpManual | ||
| success: bool | ||
| errors: List[str] = Field(default_factory=list) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.