Skip to content

Commit 499fc33

Browse files
author
kevin
committed
feat: make API parameters explicit for better IDE support
1 parent 179910b commit 499fc33

10 files changed

Lines changed: 995 additions & 86 deletions

dashscope/api_entities/aio_session.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
import aiohttp
1717
import certifi
1818

19+
from dashscope.common.constants import (
20+
DEFAULT_CONNECTION_POOL_IDLE_TIMEOUT_SECONDS,
21+
)
1922
from dashscope.common.logging import logger
2023

2124
_shared_ssl_context: Optional[ssl.SSLContext] = None
@@ -38,7 +41,8 @@ async def get_shared_aio_session() -> aiohttp.ClientSession:
3841
3942
The session is lazily created on first use and reused for all
4043
subsequent calls on the same event loop. Connection pooling (keep-alive)
41-
is handled by the underlying TCPConnector.
44+
is handled by the underlying TCPConnector with idle timeout configured
45+
to close stale connections.
4246
"""
4347
loop = asyncio.get_running_loop()
4448

@@ -47,7 +51,10 @@ async def get_shared_aio_session() -> aiohttp.ClientSession:
4751
if session is not None and not session.closed:
4852
return session
4953

50-
connector = aiohttp.TCPConnector(ssl=get_ssl_context())
54+
connector = aiohttp.TCPConnector(
55+
ssl=get_ssl_context(),
56+
keepalive_timeout=DEFAULT_CONNECTION_POOL_IDLE_TIMEOUT_SECONDS,
57+
)
5158
session = aiohttp.ClientSession(connector=connector, trust_env=True)
5259

5360
_aio_sessions[loop] = session

dashscope/api_entities/api_request_factory.py

Lines changed: 102 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
# -*- coding: utf-8 -*-
22
# Copyright (c) Alibaba, Inc. and its affiliates.
3+
from typing import Any, Dict, Union
34
from urllib.parse import urlencode
45

6+
import aiohttp
7+
import requests
8+
59
import dashscope
610
from dashscope.api_entities.api_request_data import ApiRequestData
11+
from dashscope.api_entities.encryption import Encryption
712
from dashscope.api_entities.http_request import HttpRequest
813
from dashscope.api_entities.websocket_request import WebSocketRequest
914
from dashscope.common.constants import (
@@ -15,7 +20,6 @@
1520
from dashscope.common.error import InputDataRequired, UnsupportedApiProtocol
1621
from dashscope.common.logging import logger
1722
from dashscope.protocol.websocket import WebsocketStreamingMode
18-
from dashscope.api_entities.encryption import Encryption
1923

2024

2125
def _get_protocol_params(kwargs):
@@ -70,35 +74,111 @@ def _get_protocol_params(kwargs):
7074

7175

7276
def _build_api_request( # pylint: disable=too-many-branches
77+
# pylint: disable=too-many-arguments,too-many-locals
7378
model: str,
7479
input: object, # pylint: disable=redefined-builtin
7580
task_group: str,
7681
task: str,
7782
function: str,
7883
api_key: str,
79-
is_service=True,
84+
is_service: bool = True,
85+
# Protocol and connection configuration
86+
api_protocol: ApiProtocol = ApiProtocol.HTTPS,
87+
http_method: HTTPMethod = HTTPMethod.POST,
88+
stream: bool = False,
89+
async_request: bool = False,
90+
request_timeout: int = None,
91+
# WebSocket specific
92+
ws_stream_mode: WebsocketStreamingMode = WebsocketStreamingMode.OUT,
93+
is_binary_input: bool = False,
94+
# HTTP specific
95+
query: bool = False,
96+
headers: Dict[str, str] = None,
97+
form: Dict = None,
98+
resources: Dict = None,
99+
base_address: str = None,
100+
flattened_output: bool = False,
101+
extra_url_parameters: Dict[str, Any] = None,
102+
user_agent: str = "",
103+
session: Union[requests.Session, aiohttp.ClientSession] = None,
104+
task_id: str = None,
105+
enable_encryption: bool = False,
106+
pre_task_id: str = None,
107+
# Additional parameters for API request data
80108
**kwargs,
81109
):
82-
(
83-
api_protocol,
84-
ws_stream_mode,
85-
is_binary_input,
86-
http_method,
87-
stream,
88-
async_request,
89-
query,
90-
headers,
91-
request_timeout,
92-
form,
93-
resources,
94-
base_address,
95-
flattened_output,
96-
extra_url_parameters,
97-
user_agent,
98-
session,
99-
) = _get_protocol_params(kwargs)
100-
task_id = kwargs.pop("task_id", None)
101-
enable_encryption = kwargs.pop("enable_encryption", False)
110+
# pylint: disable=too-many-statements
111+
"""Build API request object.
112+
113+
Args:
114+
model (str): The model name.
115+
input (object): The input data for the request.
116+
task_group (str): The task group for the API path.
117+
task (str): The task name for the API path.
118+
function (str): The function name for the API path.
119+
api_key (str): The API key for authentication.
120+
is_service (bool, optional): Whether this is a service call.
121+
Defaults to True.
122+
api_protocol (ApiProtocol, optional): The protocol to use
123+
(HTTP, HTTPS, WEBSOCKET). Defaults to ApiProtocol.HTTPS.
124+
http_method (HTTPMethod, optional): The HTTP method (GET, POST).
125+
Defaults to HTTPMethod.POST.
126+
stream (bool, optional): Enable streaming output.
127+
Defaults to False.
128+
async_request (bool, optional): Enable async request.
129+
Defaults to False.
130+
request_timeout (int, optional): Request timeout in seconds.
131+
Defaults to None.
132+
ws_stream_mode (WebsocketStreamingMode, optional): WebSocket
133+
streaming mode. Defaults to WebsocketStreamingMode.OUT.
134+
is_binary_input (bool, optional): Whether input is binary data.
135+
Defaults to False.
136+
query (bool, optional): Whether this is a query request.
137+
Defaults to False.
138+
headers (Dict[str, str], optional): Additional HTTP headers.
139+
Defaults to None.
140+
form (Dict, optional): Form data for multipart requests.
141+
Defaults to None.
142+
resources (Dict, optional): Resource data. Defaults to None.
143+
base_address (str, optional): Custom base URL for the API.
144+
Defaults to None.
145+
flattened_output (bool, optional): Whether to flatten output.
146+
Defaults to False.
147+
extra_url_parameters (Dict[str, Any], optional): Extra URL query
148+
parameters. Defaults to None.
149+
user_agent (str, optional): Custom user agent string.
150+
Defaults to "".
151+
session (Union[requests.Session, aiohttp.ClientSession], optional):
152+
Custom session for connection reuse. Defaults to None.
153+
task_id (str, optional): Task ID for the request.
154+
Defaults to None.
155+
enable_encryption (bool, optional): Enable request encryption.
156+
Defaults to False.
157+
pre_task_id (str, optional): Previous task ID for WebSocket.
158+
Defaults to None.
159+
**kwargs: Additional parameters passed to the API request data.
160+
161+
Returns:
162+
HttpRequest or WebSocketRequest: The constructed request object.
163+
164+
Raises:
165+
InputDataRequired: If input data is missing or invalid.
166+
UnsupportedApiProtocol: If the API protocol is not supported.
167+
"""
168+
# Handle stream mode for WebSocket
169+
if not stream and ws_stream_mode == WebsocketStreamingMode.OUT:
170+
ws_stream_mode = WebsocketStreamingMode.NONE
171+
172+
# Handle user_agent from headers
173+
if headers and "user-agent" in headers:
174+
header_ua = headers.pop("user-agent")
175+
if user_agent:
176+
user_agent = (
177+
f"{header_ua}; {user_agent}" if header_ua else user_agent
178+
)
179+
else:
180+
user_agent = header_ua
181+
102182
encryption = None
103183

104184
if api_protocol in [ApiProtocol.HTTP, ApiProtocol.HTTPS]:
@@ -146,7 +226,6 @@ def _build_api_request( # pylint: disable=too-many-branches
146226
websocket_url = base_address
147227
else:
148228
websocket_url = dashscope.base_websocket_api_url
149-
pre_task_id = kwargs.pop("pre_task_id", None)
150229
request = WebSocketRequest(
151230
url=websocket_url,
152231
api_key=api_key,

0 commit comments

Comments
 (0)