chore: 添加虚拟环境到仓库
- 添加 backend_service/venv 虚拟环境 - 包含所有Python依赖包 - 注意:虚拟环境约393MB,包含12655个文件
This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import queue
|
||||
import threading
|
||||
from dataclasses import dataclass
|
||||
from http import HTTPStatus
|
||||
from typing import Dict
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import aiohttp
|
||||
import requests
|
||||
|
||||
from dashscope.api_entities.dashscope_response import DashScopeAPIResponse
|
||||
from dashscope.common.api_key import get_default_api_key
|
||||
from dashscope.common.constants import SSE_CONTENT_TYPE
|
||||
from dashscope.common.logging import logger
|
||||
from dashscope.version import __version__
|
||||
|
||||
|
||||
def is_validate_fine_tune_file(file_path):
|
||||
with open(file_path, encoding='utf-8') as f:
|
||||
for line in f:
|
||||
try:
|
||||
json.loads(line)
|
||||
except json.decoder.JSONDecodeError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _get_task_group_and_task(module_name):
|
||||
"""Get task_group and task name.
|
||||
get task_group and task name based on api file __name__
|
||||
|
||||
Args:
|
||||
module_name (str): The api file __name__
|
||||
|
||||
Returns:
|
||||
(str, str): task_group and task
|
||||
"""
|
||||
pkg, task = module_name.rsplit('.', 1)
|
||||
task = task.replace('_', '-')
|
||||
_, task_group = pkg.rsplit('.', 1)
|
||||
return task_group, task
|
||||
|
||||
|
||||
def is_path(path: str):
|
||||
"""Check the input path is valid local path.
|
||||
|
||||
Args:
|
||||
path_or_url (str): The path.
|
||||
|
||||
Returns:
|
||||
bool: If path return True, otherwise False.
|
||||
"""
|
||||
url_parsed = urlparse(path)
|
||||
if url_parsed.scheme in ('file', ''):
|
||||
return os.path.exists(url_parsed.path)
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def is_url(url: str):
|
||||
"""Check the input url is valid url.
|
||||
|
||||
Args:
|
||||
url (str): The url
|
||||
|
||||
Returns:
|
||||
bool: If is url return True, otherwise False.
|
||||
"""
|
||||
url_parsed = urlparse(url)
|
||||
if url_parsed.scheme in ('http', 'https', 'oss'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def iter_over_async(ait):
|
||||
loop = asyncio.get_event_loop_policy().new_event_loop()
|
||||
ait = ait.__aiter__()
|
||||
|
||||
async def get_next():
|
||||
try:
|
||||
obj = await ait.__anext__()
|
||||
return False, obj
|
||||
except StopAsyncIteration:
|
||||
return True, None
|
||||
|
||||
def iter_thread(loop, message_queue):
|
||||
while True:
|
||||
try:
|
||||
done, obj = loop.run_until_complete(get_next())
|
||||
if done:
|
||||
message_queue.put((True, None, None))
|
||||
break
|
||||
message_queue.put((False, None, obj))
|
||||
except BaseException as e: # noqa E722
|
||||
logger.exception(e)
|
||||
message_queue.put((True, e, None))
|
||||
break
|
||||
|
||||
message_queue = queue.Queue()
|
||||
x = threading.Thread(target=iter_thread,
|
||||
args=(loop, message_queue),
|
||||
name='iter_async_thread')
|
||||
x.start()
|
||||
while True:
|
||||
finished, error, obj = message_queue.get()
|
||||
if finished:
|
||||
if error is not None:
|
||||
yield DashScopeAPIResponse(
|
||||
-1,
|
||||
'',
|
||||
'Unknown',
|
||||
message='Error type: %s, message: %s' %
|
||||
(type(error), error))
|
||||
break
|
||||
else:
|
||||
yield obj
|
||||
|
||||
|
||||
def async_to_sync(async_generator):
|
||||
for message in iter_over_async(async_generator):
|
||||
yield message
|
||||
|
||||
|
||||
def get_user_agent():
|
||||
ua = 'dashscope/%s; python/%s; platform/%s; processor/%s' % (
|
||||
__version__,
|
||||
platform.python_version(),
|
||||
platform.platform(),
|
||||
platform.processor(),
|
||||
)
|
||||
return ua
|
||||
|
||||
|
||||
def default_headers(api_key: str = None) -> Dict[str, str]:
|
||||
ua = 'dashscope/%s; python/%s; platform/%s; processor/%s' % (
|
||||
__version__,
|
||||
platform.python_version(),
|
||||
platform.platform(),
|
||||
platform.processor(),
|
||||
)
|
||||
headers = {'user-agent': ua}
|
||||
if api_key is None:
|
||||
api_key = get_default_api_key()
|
||||
headers['Authorization'] = 'Bearer %s' % api_key
|
||||
headers['Accept'] = 'application/json'
|
||||
return headers
|
||||
|
||||
|
||||
def join_url(base_url, *args):
|
||||
if not base_url.endswith('/'):
|
||||
base_url = base_url + '/'
|
||||
url = base_url
|
||||
for arg in args:
|
||||
if arg is not None:
|
||||
url += arg + '/'
|
||||
return url[:-1]
|
||||
|
||||
|
||||
async def _handle_aiohttp_response(response: aiohttp.ClientResponse):
|
||||
request_id = ''
|
||||
if response.status == HTTPStatus.OK:
|
||||
json_content = await response.json()
|
||||
if 'request_id' in json_content:
|
||||
request_id = json_content['request_id']
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=HTTPStatus.OK,
|
||||
output=json_content)
|
||||
else:
|
||||
if 'application/json' in response.content_type:
|
||||
error = await response.json()
|
||||
msg = ''
|
||||
if 'message' in error:
|
||||
msg = error['message']
|
||||
if 'request_id' in error:
|
||||
request_id = error['request_id']
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=response.status,
|
||||
output=None,
|
||||
code=error['code'],
|
||||
message=msg)
|
||||
else:
|
||||
msg = await response.read()
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=response.status,
|
||||
output=None,
|
||||
code='Unknown',
|
||||
message=msg)
|
||||
|
||||
|
||||
@dataclass
|
||||
class SSEEvent:
|
||||
id: str
|
||||
eventType: str
|
||||
data: str
|
||||
|
||||
def __init__(self, id: str, type: str, data: str):
|
||||
self.id = id
|
||||
self.eventType = type
|
||||
self.data = data
|
||||
|
||||
|
||||
def _handle_stream(response: requests.Response):
|
||||
# TODO define done message.
|
||||
is_error = False
|
||||
status_code = HTTPStatus.BAD_REQUEST
|
||||
event = SSEEvent(None, None, None)
|
||||
eventType = None
|
||||
for line in response.iter_lines():
|
||||
if line:
|
||||
line = line.decode('utf8')
|
||||
line = line.rstrip('\n').rstrip('\r')
|
||||
if line.startswith('id:'):
|
||||
id = line[len('id:'):]
|
||||
event.id = id.strip()
|
||||
elif line.startswith('event:'):
|
||||
eventType = line[len('event:'):]
|
||||
event.eventType = eventType.strip()
|
||||
if eventType == '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:'):]
|
||||
event.data = line.strip()
|
||||
if eventType is not None and eventType == 'done':
|
||||
continue
|
||||
yield (is_error, status_code, event)
|
||||
if is_error:
|
||||
break
|
||||
else:
|
||||
continue # ignore heartbeat...
|
||||
|
||||
|
||||
def _handle_error_message(error, status_code, flattened_output):
|
||||
code = None
|
||||
msg = ''
|
||||
request_id = ''
|
||||
if flattened_output:
|
||||
error['status_code'] = status_code
|
||||
return error
|
||||
if 'message' in error:
|
||||
msg = error['message']
|
||||
if 'msg' in error:
|
||||
msg = error['msg']
|
||||
if 'code' in error:
|
||||
code = error['code']
|
||||
if 'request_id' in error:
|
||||
request_id = error['request_id']
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=status_code,
|
||||
code=code,
|
||||
message=msg)
|
||||
|
||||
|
||||
def _handle_http_failed_response(
|
||||
response: requests.Response,
|
||||
flattened_output: bool = False) -> DashScopeAPIResponse:
|
||||
request_id = ''
|
||||
if 'application/json' in response.headers.get('content-type', ''):
|
||||
error = response.json()
|
||||
return _handle_error_message(error, response.status_code,
|
||||
flattened_output)
|
||||
elif SSE_CONTENT_TYPE in response.headers.get('content-type', ''):
|
||||
msgs = response.content.decode('utf-8').split('\n')
|
||||
for msg in msgs:
|
||||
if msg.startswith('data:'):
|
||||
error = json.loads(msg.replace('data:', '').strip())
|
||||
return _handle_error_message(error, response.status_code,
|
||||
flattened_output)
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=response.status_code,
|
||||
code='Unknown',
|
||||
message=msgs)
|
||||
else:
|
||||
msg = response.content.decode('utf-8')
|
||||
if flattened_output:
|
||||
return {'status_code': response.status_code, 'message': msg}
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=response.status_code,
|
||||
code='Unknown',
|
||||
message=msg)
|
||||
|
||||
|
||||
async def _handle_aio_stream(response):
|
||||
# TODO define done message.
|
||||
is_error = False
|
||||
status_code = HTTPStatus.BAD_REQUEST
|
||||
async for line in response.content:
|
||||
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...
|
||||
|
||||
|
||||
async def _handle_aiohttp_failed_response(
|
||||
response: requests.Response,
|
||||
flattened_output: bool = False) -> DashScopeAPIResponse:
|
||||
request_id = ''
|
||||
if 'application/json' in response.content_type:
|
||||
error = await response.json()
|
||||
return _handle_error_message(error, response.status, flattened_output)
|
||||
elif SSE_CONTENT_TYPE in response.content_type:
|
||||
async for _, _, data in _handle_aio_stream(response):
|
||||
error = json.loads(data)
|
||||
return _handle_error_message(error, response.status, flattened_output)
|
||||
else:
|
||||
msg = response.content.decode('utf-8')
|
||||
if flattened_output:
|
||||
return {'status_code': response.status, 'message': msg}
|
||||
return DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=response.status,
|
||||
code='Unknown',
|
||||
message=msg)
|
||||
|
||||
|
||||
def _handle_http_response(response: requests.Response,
|
||||
flattened_output: bool = False):
|
||||
response = _handle_http_stream_response(response, flattened_output)
|
||||
_, output = next(response)
|
||||
try:
|
||||
next(response)
|
||||
except StopIteration:
|
||||
pass
|
||||
return output
|
||||
|
||||
|
||||
def _handle_http_stream_response(response: requests.Response,
|
||||
flattened_output: bool = False):
|
||||
request_id = ''
|
||||
if (response.status_code == HTTPStatus.OK
|
||||
and SSE_CONTENT_TYPE in response.headers.get('content-type', '')):
|
||||
for is_error, status_code, event in _handle_stream(response):
|
||||
if not is_error:
|
||||
try:
|
||||
output = None
|
||||
usage = None
|
||||
msg = json.loads(event.data)
|
||||
if flattened_output:
|
||||
msg['status_code'] = response.status_code
|
||||
yield event.eventType, msg
|
||||
else:
|
||||
logger.debug('Stream message: %s' % msg)
|
||||
if not is_error:
|
||||
if 'output' in msg:
|
||||
output = msg['output']
|
||||
if 'usage' in msg:
|
||||
usage = msg['usage']
|
||||
if 'request_id' in msg:
|
||||
request_id = msg['request_id']
|
||||
yield event.eventType, DashScopeAPIResponse(
|
||||
request_id=request_id,
|
||||
status_code=HTTPStatus.OK,
|
||||
output=output,
|
||||
usage=usage)
|
||||
except json.JSONDecodeError as e:
|
||||
if flattened_output:
|
||||
yield event.eventType, {
|
||||
'status_code': response.status_code,
|
||||
'message': e.message
|
||||
}
|
||||
else:
|
||||
yield event.eventType, DashScopeAPIResponse(
|
||||
request_id=request_id,
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
output=None,
|
||||
code='Unknown',
|
||||
message=event.data)
|
||||
continue
|
||||
else:
|
||||
if flattened_output:
|
||||
yield event.eventType, {
|
||||
'status_code': status_code,
|
||||
'message': event.data
|
||||
}
|
||||
else:
|
||||
msg = json.loads(event.eventType)
|
||||
yield event.eventType, DashScopeAPIResponse(
|
||||
request_id=request_id,
|
||||
status_code=status_code,
|
||||
output=None,
|
||||
code=msg['code']
|
||||
if 'code' in msg else None, # noqa E501
|
||||
message=msg['message']
|
||||
if 'message' in msg else None) # noqa E501
|
||||
elif response.status_code == HTTPStatus.OK or response.status_code == HTTPStatus.CREATED:
|
||||
json_content = response.json()
|
||||
if flattened_output:
|
||||
json_content['status_code'] = response.status_code
|
||||
yield None, json_content
|
||||
else:
|
||||
output = None
|
||||
usage = None
|
||||
code = None
|
||||
msg = ''
|
||||
if 'data' in json_content:
|
||||
output = json_content['data']
|
||||
if 'code' in json_content:
|
||||
code = json_content['code']
|
||||
if 'message' in json_content:
|
||||
msg = json_content['message']
|
||||
if 'output' in json_content:
|
||||
output = json_content['output']
|
||||
if 'usage' in json_content:
|
||||
usage = json_content['usage']
|
||||
if 'request_id' in json_content:
|
||||
request_id = json_content['request_id']
|
||||
json_content.pop('request_id', None)
|
||||
|
||||
if 'data' not in json_content and 'output' not in json_content:
|
||||
output = json_content
|
||||
|
||||
yield None, DashScopeAPIResponse(request_id=request_id,
|
||||
status_code=response.status_code,
|
||||
code=code,
|
||||
output=output,
|
||||
usage=usage,
|
||||
message=msg)
|
||||
else:
|
||||
yield None, _handle_http_failed_response(response, flattened_output)
|
||||
Reference in New Issue
Block a user