remove gitignore

This commit is contained in:
Ubuntu
2025-09-11 13:29:12 +00:00
parent 45bcf4274f
commit 9fdfed9655
11605 changed files with 6174940 additions and 127 deletions

View File

@@ -0,0 +1,800 @@
import time
from http import HTTPStatus
from typing import List, Union
import dashscope
import requests
from dashscope.api_entities.api_request_factory import _build_api_request
from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
from dashscope.common.api_key import get_default_api_key
from dashscope.common.constants import (DEFAULT_REQUEST_TIMEOUT_SECONDS,
REPEATABLE_STATUS,
REQUEST_TIMEOUT_KEYWORD,
SSE_CONTENT_TYPE, TaskStatus)
from dashscope.common.error import InvalidParameter, InvalidTask, ModelRequired
from dashscope.common.logging import logger
from dashscope.common.utils import (_handle_http_failed_response,
_handle_http_response, default_headers,
join_url)
def _normalization_url(*args):
url = dashscope.base_http_api_url
return join_url(url, *args)
class BaseAioApi():
"""BaseApi, internal use only.
"""
@classmethod
def _validate_params(cls, api_key, model):
if api_key is None:
api_key = get_default_api_key()
if model is None or not model:
raise ModelRequired('Model is required!')
return api_key, model
@classmethod
def aio_call(cls,
model: str,
input: object,
task_group: str,
task: str = None,
function: str = None,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Call service and get result.
Args:
model (str): The requested model, such as gpt3-v2
input (object): The api input data, cannot be None.
task_group (str, optional): The api task group.
task (str, optional): The task name. Defaults to None.
function (str, optional): The function of the task.
Defaults to None.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
api_protocol (str, optional): Api protocol websocket or http.
Defaults to None.
ws_stream_mode (str, optional): websocket stream mode,
[none, in, out, duplex]. Defaults to out.
is_binary_input (bool, optional): Is input data binary.
Defaults to False.
http_method (str, optional): If api protocol is http, specifies
method[GET, POST]. Defaults to POST.
Returns:
DashScopeAPIResponse: The service response.
"""
api_key, model = BaseAioApi._validate_params(api_key, model)
request = _build_api_request(model=model,
input=input,
task_group=task_group,
task=task,
function=function,
api_key=api_key,
**kwargs)
# call request service.
return request.aio_call()
class BaseApi():
"""BaseApi, internal use only.
"""
@classmethod
def _validate_params(cls, api_key, model):
if api_key is None:
api_key = get_default_api_key()
if model is None or not model:
raise ModelRequired('Model is required!')
return api_key, model
@classmethod
def call(cls,
model: str,
input: object,
task_group: str,
task: str = None,
function: str = None,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Call service and get result.
Args:
model (str): The requested model, such as gpt3-v2
input (object): The api input data, cannot be None.
task_group (str, optional): The api task group.
task (str, optional): The task name. Defaults to None.
function (str, optional): The function of the task.
Defaults to None.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
api_protocol (str, optional): Api protocol websocket or http.
Defaults to None.
ws_stream_mode (str, optional): websocket stream mode,
[none, in, out, duplex]. Defaults to out.
is_binary_input (bool, optional): Is input data binary.
Defaults to False.
http_method (str, optional): If api protocol is http, specifies
method[GET, POST]. Defaults to POST.
Returns:
DashScopeAPIResponse: The service response.
"""
api_key, model = BaseApi._validate_params(api_key, model)
request = _build_api_request(model=model,
input=input,
task_group=task_group,
task=task,
function=function,
api_key=api_key,
**kwargs)
# call request service.
return request.call()
class AsyncTaskGetMixin():
@classmethod
def _get(cls, task_id: str, api_key: str = None) -> DashScopeAPIResponse:
status_url = _normalization_url('tasks', task_id)
with requests.Session() as session:
logger.debug('Starting request: %s' % status_url)
response = session.get(status_url,
headers={
**default_headers(api_key),
},
timeout=DEFAULT_REQUEST_TIMEOUT_SECONDS)
logger.debug('Starting processing response: %s' % status_url)
return _handle_http_response(response)
class BaseAsyncApi(AsyncTaskGetMixin):
"""BaseAsyncApi,for async task, internal use only.
"""
@classmethod
def _validate_params(cls, api_key, model):
if api_key is None:
api_key = get_default_api_key()
if model is None or not model:
raise ModelRequired('Model is required!')
return api_key, model
@classmethod
def call(cls, *args, api_key: None, **kwargs) -> DashScopeAPIResponse:
"""Call service and get result.
"""
task_response = cls.async_call(*args, api_key=api_key, **kwargs)
response = cls.wait(task_response, api_key=api_key)
return response
@classmethod
def _get_task_id(cls, task):
if isinstance(task, str):
task_id = task
elif isinstance(task, DashScopeAPIResponse):
if task.status_code == HTTPStatus.OK:
task_id = task.output['task_id']
else:
raise InvalidTask('Invalid task, task create failed: %s' %
task)
else:
raise InvalidParameter('Task invalid!')
if task_id is None or task_id == '':
raise InvalidParameter('Task id required!')
return task_id
@classmethod
def cancel(
cls,
task: Union[str, DashScopeAPIResponse],
api_key: str = None,
) -> DashScopeAPIResponse:
"""Cancel PENDING task.
Args:
task (Union[str, DashScopeAPIResponse]): The task_id, or
async_call response.
api_key (str, optional): The api-key. Defaults to None.
Returns:
DashScopeAPIResponse: The cancel result.
"""
task_id = cls._get_task_id(task)
url = _normalization_url('tasks', task_id, 'cancel')
with requests.Session() as session:
response = session.post(url,
headers={
**default_headers(api_key),
})
return _handle_http_response(response)
@classmethod
def list(cls,
start_time: str = None,
end_time: str = None,
model_name: str = None,
api_key_id: str = None,
region: str = None,
status: str = None,
page_no: int = 1,
page_size: int = 10,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""List async tasks.
Args:
start_time (str, optional): The tasks start time,
for example: 20230420000000. Defaults to None.
end_time (str, optional): The tasks end time,
for example: 20230420000000. Defaults to None.
model_name (str, optional): The tasks model name.
Defaults to None.
api_key_id (str, optional): The tasks api-key-id.
Defaults to None.
region (str, optional): The service region,
for example: cn-beijing. Defaults to None.
status (str, optional): The status of tasks[PENDING,
RUNNING, SUCCEEDED, FAILED, CANCELED]. Defaults to None.
page_no (int, optional): The page number. Defaults to 1.
page_size (int, optional): The page size. Defaults to 10.
api_key (str, optional): The user api-key. Defaults to None.
Returns:
DashScopeAPIResponse: The response data.
"""
url = _normalization_url('tasks')
params = {'page_no': page_no, 'page_size': page_size}
if start_time is not None:
params['start_time'] = start_time
if end_time is not None:
params['end_time'] = end_time
if model_name is not None:
params['model_name'] = model_name
if api_key_id is not None:
params['api_key_id'] = api_key_id
if region is not None:
params['region'] = region
if status is not None:
params['status'] = status
with requests.Session() as session:
response = session.get(url,
params=params,
headers={
**default_headers(api_key),
})
if response.status_code == HTTPStatus.OK:
json_content = response.json()
request_id = ''
if 'request_id' in json_content:
request_id = json_content['request_id']
json_content.pop('request_id')
return DashScopeAPIResponse(request_id=request_id,
status_code=response.status_code,
code=None,
output=json_content,
usage=None,
message='')
else:
return _handle_http_failed_response(response)
@classmethod
def fetch(
cls,
task: Union[str, DashScopeAPIResponse],
api_key: str = None,
) -> DashScopeAPIResponse:
"""Query async task status.
Args:
task (Union[str, DashScopeAPIResponse]): The task_id, or
async_call response.
api_key (str, optional): The api_key. Defaults to None.
Returns:
DashScopeAPIResponse: The async task information.
"""
task_id = cls._get_task_id(task)
return cls._get(task_id, api_key)
@classmethod
def wait(cls,
task: Union[str, DashScopeAPIResponse],
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Wait for async task completion and return task result.
Args:
task (Union[str, DashScopeAPIResponse]): The task_id, or
async_call response.
api_key (str, optional): The api_key. Defaults to None.
Returns:
DashScopeAPIResponse: The async task information.
"""
task_id = cls._get_task_id(task)
wait_seconds = 1
max_wait_seconds = 5
increment_steps = 3
step = 0
while True:
step += 1
# we start by querying once every second, and double
# the query interval after every 3(increment_steps)
# intervals, until we hit the max waiting interval
# of 5(seconds
# TODO: investigate if we can use long-poll
# (server side return immediately when ready)
if wait_seconds < max_wait_seconds and step % increment_steps == 0:
wait_seconds = min(wait_seconds * 2, max_wait_seconds)
rsp = cls._get(task_id, api_key)
if rsp.status_code == HTTPStatus.OK:
if rsp.output is None:
return rsp
task_status = rsp.output['task_status']
if task_status in [
TaskStatus.FAILED, TaskStatus.CANCELED,
TaskStatus.SUCCEEDED, TaskStatus.UNKNOWN
]:
return rsp
else:
logger.info('The task %s is %s' % (task_id, task_status))
time.sleep(wait_seconds)
elif rsp.status_code in REPEATABLE_STATUS:
logger.warn(
('Get task: %s temporary failure, \
status_code: %s, code: %s message: %s, will try again.'
) % (task_id, rsp.status_code, rsp.code, rsp.message))
time.sleep(wait_seconds)
else:
return rsp
@classmethod
def async_call(cls,
model: str,
input: object,
task_group: str,
task: str = None,
function: str = None,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Call async service return async task information.
Args:
model (str): The requested model, such as gpt3-v2
input (object): The api input data, cannot be None.
task_group (str, optional): The api task group.
task (str, optional): The task name. Defaults to None.
function (str, optional): The function of the task.
Defaults to None.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The async task information,
which contains the task id, you can use the task id
to query the task status.
"""
is_stream = kwargs.pop('stream', None) # async api not support stream.
if is_stream:
logger.warn('async_call do not support stream argument')
api_key, model = BaseApi._validate_params(api_key, model)
request = _build_api_request(model=model,
input=input,
task_group=task_group,
task=task,
function=function,
api_key=api_key,
async_request=True,
query=False,
**kwargs)
return request.call()
def _get(url, params={}, api_key=None, **kwargs) -> DashScopeAPIResponse:
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.get(url,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
params=params,
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class ListMixin():
@classmethod
def list(cls,
page_no=1,
page_size=10,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""list objects
Args:
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
page_no (int, optional): Page number. Defaults to 1.
page_size (int, optional): Items per page. Defaults to 10.
Returns:
DashScopeAPIResponse: The object list in output.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower())
params = {'page_no': page_no, 'page_size': page_size}
return _get(url, params=params, api_key=api_key, **kwargs)
class LogMixin():
@classmethod
def logs(cls,
job_id: str,
offset=1,
line=1000,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Get log of the job.
Args:
job_id (str): The job id(used for fine-tune)
offset (int, optional): start log line. Defaults to 1.
line (int, optional): total line return. Defaults to 1000.
api_key (str, optional): The api key. Defaults to None.
Returns:
DashScopeAPIResponse: The response
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
job_id, 'logs')
params = {'offset': offset, 'line': line}
return _get(url, params=params, api_key=api_key, **kwargs)
class GetMixin():
@classmethod
def get(cls,
target,
api_key: str = None,
params: dict = {},
**kwargs) -> DashScopeAPIResponse:
"""Get object information.
Args:
target (str): The target to get, such as model_id.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The object information in output.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target)
return _get(url, api_key=api_key, params=params, **kwargs)
class GetStatusMixin():
@classmethod
def get(cls,
target,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Get object information.
Args:
target (str): The target to get, such as model_id.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The object information in output.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target)
return _get(url, api_key, **kwargs)
class DeleteMixin():
@classmethod
def delete(cls,
target: str,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Delete object.
Args:
target (str): The object to delete, .
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The delete result.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target)
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.delete(url,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class CreateMixin():
@classmethod
def call(cls,
data: object,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Create a object
Args:
data (object): The create request json body.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The created object in output.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower())
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.post(url,
json=data,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class UpdateMixin():
@classmethod
def update(cls,
target: str,
json: object,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Async update a object
Args:
target (str): The target to update.
json (object): The create request json body.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The updated object information in output.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target)
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.patch(url,
json=json,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class PutMixin():
@classmethod
def put(cls,
target: str,
json: object,
extra_path: str = None,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Async update a object
Args:
target (str): The target to update.
json (object): The create request json body.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The updated object information in output.
"""
if extra_path is None:
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target)
else:
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target, extra_path)
print(url)
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.put(url,
json=json,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class FileUploadMixin():
@classmethod
def upload(cls,
files: list,
descriptions: List[str] = None,
params: dict = None,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Upload files
Args:
files (list): List of (name, opened file, file_name).
descriptions (list[str]): The file description messages.
params (dict): The parameters
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The uploaded file information in the output.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower())
js = None
if descriptions:
js = {'descriptions': descriptions}
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.post(url,
data=js,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
files=files,
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class CancelMixin():
@classmethod
def cancel(cls,
target: str,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Cancel a job.
Args:
target (str): The request params, key/value map.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The cancel result.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target, 'cancel')
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.post(url,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
return _handle_http_response(response)
class StreamEventMixin():
@classmethod
def _handle_stream(cls, response: requests.Response):
# TODO define done message.
is_error = False
status_code = HTTPStatus.INTERNAL_SERVER_ERROR
for line in response.iter_lines():
if line:
line = line.decode('utf8')
line = line.rstrip('\n').rstrip('\r')
if line.startswith('event:error'):
is_error = True
elif line.startswith('status:'):
status_code = line[len('status:'):]
status_code = int(status_code.strip())
elif line.startswith('data:'):
line = line[len('data:'):]
yield (is_error, status_code, line)
if is_error:
break
else:
continue # ignore heartbeat...
@classmethod
def _handle_response(cls, response: requests.Response):
request_id = ''
if (response.status_code == HTTPStatus.OK
and SSE_CONTENT_TYPE in response.headers.get(
'content-type', '')):
for is_error, status_code, data in cls._handle_stream(response):
if is_error:
yield DashScopeAPIResponse(request_id=request_id,
status_code=status_code,
output=None,
code='',
message='') # noqa E501
else:
yield DashScopeAPIResponse(request_id=request_id,
status_code=HTTPStatus.OK,
output=data,
usage=None)
elif response.status_code == HTTPStatus.OK:
json_content = response.json()
request_id = ''
if 'request_id' in json_content:
request_id = json_content['request_id']
yield DashScopeAPIResponse(request_id=request_id,
status_code=HTTPStatus.OK,
output=json_content,
usage=None)
else:
_handle_http_failed_response(response)
@classmethod
def stream_events(cls,
target,
api_key: str = None,
**kwargs) -> DashScopeAPIResponse:
"""Get job log.
Args:
target (str): The target to get, such as model_id.
api_key (str, optional): The api api_key, if not present,
will get by default rule(TODO: api key doc). Defaults to None.
Returns:
DashScopeAPIResponse: The target outputs.
"""
url = join_url(dashscope.base_http_api_url, cls.SUB_PATH.lower(),
target, 'stream')
timeout = kwargs.pop(REQUEST_TIMEOUT_KEYWORD,
DEFAULT_REQUEST_TIMEOUT_SECONDS)
with requests.Session() as session:
logger.debug('Starting request: %s' % url)
response = session.get(url,
headers={
**default_headers(api_key),
**kwargs.pop('headers', {})
},
stream=True,
timeout=timeout)
logger.debug('Starting processing response: %s' % url)
for rsp in cls._handle_response(response):
yield rsp