Skip to content
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

Python: OpenAPI plugin updates to promote plugin to preview #9670

Merged
merged 17 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions python/samples/demos/process_with_dapr/fastapi_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ async def start_process(process_id: str):
process_id=process_id,
)
return JSONResponse(content={"processId": process_id}, status_code=200)
except Exception as e:
return JSONResponse(content={"error": str(e)}, status_code=500)
except Exception:
return JSONResponse(content={"error": "Error starting process"}, status_code=500)


if __name__ == "__main__":
Expand Down
5 changes: 2 additions & 3 deletions python/samples/demos/process_with_dapr/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ def start_process(process_id):
)

return jsonify({"processId": process_id}), 200
except Exception as e:
logging.exception("Error starting process")
return jsonify({"error": str(e)}), 500
except Exception:
return jsonify({"error": "Error starting process"}), 500


# Run application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@
from enum import Enum

from pydantic import HttpUrl
from typing_extensions import deprecated

from semantic_kernel.kernel_pydantic import KernelBaseModel


@deprecated("The `OpenAIAuthenticationType` class is deprecated; use the `OpenAPI` plugin instead.", category=None)
class OpenAIAuthenticationType(str, Enum):
"""OpenAI authentication types."""

OAuth = "oauth"
NoneType = "none"


@deprecated("The `OpenAIAuthenticationType` class is deprecated; use the `OpenAPI` plugin instead.", category=None)
class OpenAIAuthorizationType(str, Enum):
"""OpenAI authorization types."""

Bearer = "Bearer"
Basic = "Basic"


@deprecated("The `OpenAIAuthenticationConfig` class is deprecated; use the `OpenAPI` plugin instead.", category=None)
class OpenAIAuthenticationConfig(KernelBaseModel):
"""OpenAI authentication configuration."""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,47 @@


from collections.abc import Awaitable, Callable
from typing import Any
from typing import TYPE_CHECKING, Any
from urllib.parse import urlparse

from semantic_kernel.connectors.openapi_plugin.openapi_function_execution_parameters import (
OpenAPIFunctionExecutionParameters,
)
import httpx
from pydantic import Field
from typing_extensions import deprecated

from semantic_kernel.kernel_pydantic import KernelBaseModel

if TYPE_CHECKING:
from semantic_kernel.connectors.openapi_plugin import (
OperationSelectionPredicateContext,
)

OpenAIAuthCallbackType = Callable[..., Awaitable[Any]]


class OpenAIFunctionExecutionParameters(OpenAPIFunctionExecutionParameters):
@deprecated(
moonbox3 marked this conversation as resolved.
Show resolved Hide resolved
"The `OpenAIFunctionExecutionParameters` class is deprecated; use the `OpenAPI` plugin instead.", category=None
)
class OpenAIFunctionExecutionParameters(KernelBaseModel):
"""OpenAI function execution parameters."""

auth_callback: OpenAIAuthCallbackType | None = None
http_client: httpx.AsyncClient | None = None
server_url_override: str | None = None
ignore_non_compliant_errors: bool = False
user_agent: str | None = None
enable_dynamic_payload: bool = True
enable_payload_namespacing: bool = False
operations_to_exclude: list[str] = Field(default_factory=list, description="The operationId(s) to exclude")
operation_selection_predicate: Callable[["OperationSelectionPredicateContext"], bool] | None = None

def model_post_init(self, __context: Any) -> None:
"""Post initialization method for the model."""
from semantic_kernel.utils.telemetry.user_agent import HTTP_USER_AGENT

if self.server_url_override:
parsed_url = urlparse(self.server_url_override)
if not parsed_url.scheme or not parsed_url.netloc:
raise ValueError(f"Invalid server_url_override: {self.server_url_override}")

if not self.user_agent:
self.user_agent = HTTP_USER_AGENT
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import logging
from typing import Any

from typing_extensions import deprecated

from semantic_kernel.exceptions.function_exceptions import PluginInitializationError

logger: logging.Logger = logging.getLogger(__name__)


@deprecated("The `OpenAIUtils` class is deprecated; use the `OpenAPI` plugin instead.", category=None)
class OpenAIUtils:
"""Utility functions for OpenAI plugins."""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@
from semantic_kernel.connectors.openapi_plugin.openapi_function_execution_parameters import (
OpenAPIFunctionExecutionParameters,
)
from semantic_kernel.connectors.openapi_plugin.openapi_parser import OpenApiParser
from semantic_kernel.connectors.openapi_plugin.operation_selection_predicate_context import (
OperationSelectionPredicateContext,
)

__all__ = ["OpenAPIFunctionExecutionParameters"]
__all__ = ["OpenAPIFunctionExecutionParameters", "OpenApiParser", "OperationSelectionPredicateContext"]
18 changes: 18 additions & 0 deletions python/semantic_kernel/connectors/openapi_plugin/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) Microsoft. All rights reserved.


from enum import Enum

from semantic_kernel.utils.experimental_decorator import experimental_class


@experimental_class
class OperationExtensions(Enum):
"""The operation extensions."""

METHOD_KEY = "method"
OPERATION_KEY = "operation"
INFO_KEY = "info"
SECURITY_KEY = "security"
SERVER_URLS_KEY = "server-urls"
METADATA_KEY = "operation-extensions"
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@


@experimental_class
class RestApiOperationExpectedResponse:
"""RestApiOperationExpectedResponse."""
class RestApiExpectedResponse:
moonbox3 marked this conversation as resolved.
Show resolved Hide resolved
"""RestApiExpectedResponse."""

def __init__(self, description: str, media_type: str, schema: dict[str, str] | None = None):
"""Initialize the RestApiOperationExpectedResponse."""
"""Initialize the RestApiExpectedResponse."""
self.description = description
self.media_type = media_type
self.schema = schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) Microsoft. All rights reserved.

from dataclasses import dataclass

from semantic_kernel.utils.experimental_decorator import experimental_class


@experimental_class
@dataclass
class RestApiOAuthFlow:
moonbox3 marked this conversation as resolved.
Show resolved Hide resolved
"""Represents the OAuth flow used by the REST API."""

authorization_url: str
token_url: str
scopes: dict[str, str]
refresh_url: str | None = None
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft. All rights reserved.

from dataclasses import dataclass

from semantic_kernel.connectors.openapi_plugin.models.rest_api_oauth_flow import RestApiOAuthFlow
from semantic_kernel.utils.experimental_decorator import experimental_class


@experimental_class
@dataclass
class RestApiOAuthFlows:
moonbox3 marked this conversation as resolved.
Show resolved Hide resolved
"""Represents the OAuth flows used by the REST API."""

implicit: RestApiOAuthFlow | None = None
password: RestApiOAuthFlow | None = None
client_credentials: RestApiOAuthFlow | None = None
authorization_code: RestApiOAuthFlow | None = None
Loading
Loading