第一次提交
Build-Deploy-Actions Details

This commit is contained in:
jlhu4 2023-09-14 17:31:11 +08:00
commit 934df06072
29 changed files with 408 additions and 0 deletions

View File

@ -0,0 +1,47 @@
name: Build
run-name: ${{ github.actor }} is upgrade release 🚀
on: [push]
env:
REPOSITORY: ${{ github.repository }}
COMMIT_ID: ${{ github.sha }}
jobs:
Build-Deploy-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
-
name: Setup Git LFS
run: |
git lfs install
git lfs fetch
git lfs checkout
- name: List files in the repository
run: |
ls ${{ github.workspace }}
-
name: Docker Image Info
id: image-info
run: |
echo "::set-output name=image_name::$(echo $REPOSITORY | tr '[:upper:]' '[:lower:]')"
echo "::set-output name=image_tag::${COMMIT_ID:0:10}"
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
registry: artifacts.iflytek.com
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build and push
run: |
docker version
docker buildx build -t artifacts.iflytek.com/docker-private/atp/${{ steps.image-info.outputs.image_name }}:${{ steps.image-info.outputs.image_tag }} . --file ${{ github.workspace }}/Dockerfile --load
docker push artifacts.iflytek.com/docker-private/atp/${{ steps.image-info.outputs.image_name }}:${{ steps.image-info.outputs.image_tag }}
docker rmi artifacts.iflytek.com/docker-private/atp/${{ steps.image-info.outputs.image_name }}:${{ steps.image-info.outputs.image_tag }}
- run: echo "🍏 This job's status is ${{ job.status }}."

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
venv
.idea

24
Dockerfile Normal file
View File

@ -0,0 +1,24 @@
# please visit https://github.com/xfyun/aiges/releases to get stable and suitable iamges.
FROM iflyopensource/aiges-gpu:11.2-1.17-3.9.13-ubuntu1804-v3.3.2
RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list
RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN --mount=target=/root/packages.txt,source=packages.txt apt-get update && xargs -r -a /root/packages.txt apt-get install -y && rm -rf /var/lib/apt/lists/*
WORKDIR /home/user/app
RUN useradd -m -u 1000 user
RUN chown -R 1000.1000 /home/user
RUN pip config set global.index-url https://pypi.mirrors.ustc.edu.cn/simple/
RUN pip install --no-cache-dir pip==22.3.1
RUN --mount=target=requirements.txt,source=requirements.txt pip install --no-cache-dir -r requirements.txt
COPY --chown=1000 ./ /home/user/app
CMD ["python3", "app.py"]

39
README.md Normal file
View File

@ -0,0 +1,39 @@
## 运行环境
python3.8
### APPID keysecret 申请
https://in.iflyaicloud.com/console/home
## 项目目录介绍
### requirements.txt
项目依赖包管理文件<br>
首次下载此项目后执行`pip3 install -r requirements.txt`即下载安装依赖包
### app.py
程序的执行入口
### resource目录
此目录提供平台内置的请求文件以及后续保存程序执行响应文件
### sample目录
程序核心执行逻辑步骤
#### exception.py
自定义异常
#### ne_utils.py
工具文件
- 读取问题获取文件内容
- 清空目录
- 生成鉴权的url
- 解析url获取对应的host、path、schema
#### aipaas_client.py
核心程序执行
- 数据准备 prepare_req_data
- 执行 execute
- 处理响应数据 deal_response

Binary file not shown.

Binary file not shown.

39
app.py Normal file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env python3
# -*-coding:utf-8 -*-
import gradio as gr
import random
import os
import sys
import importlib
from sample.aipass_client import execute
def generate_text(message):
svcID = 's6fb9d652'
data_md = importlib.import_module(svcID)
data_md.request_data['header']['app_id'] = data_md.APPId
queryMsg_path = data_md.request_data['payload']['text']['text']
print("queryMsg_path ", queryMsg_path)
with open(queryMsg_path, 'w+') as f:
f.write(message)
return execute(data_md.request_url, data_md.request_data, "POST", data_md.APPId, data_md.APIKey, data_md.APISecret)
def respond(message, chat_history):
msg = generate_text(message=message)
chat_history.append([message, msg])
return "", chat_history
with gr.Blocks() as demo:
with gr.Column(min_width=800):
chatbot = gr.Chatbot()
with gr.Row():
message = gr.Textbox(min_width=730)
clear = gr.ClearButton([message, chatbot])
message.submit(respond, [message, chatbot], [message, chatbot])
demo.queue().launch( server_name="0.0.0.0")

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
jsonpath_rw==1.4.0
requests==2.26.0

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

View File

@ -0,0 +1 @@
{"category":"cam.ch_en","pages":[{"angle":0,"exception":0,"height":167,"lines":[{"angle":0,"conf":0.9243740439414978,"content":"11.(","coord":[{"x":75,"y":6},{"x":123,"y":6},{"x":123,"y":26},{"x":75,"y":26}],"exception":0,"id":1,"words":[{"conf":1,"content":"11.(","coord":[{"x":74,"y":6},{"x":121,"y":6},{"x":121,"y":26},{"x":74,"y":26}]}]},{"angle":0,"conf":0.9904987812042236,"content":")模:应用较早,施工简单,能保证几何尺寸(包括复杂断面),外观","coord":[{"x":213,"y":6},{"x":722,"y":6},{"x":722,"y":29},{"x":213,"y":29}],"exception":0,"id":0,"words":[{"conf":1,"content":")模:应用较早,施工简单,能保证几何尺寸(包括复杂断面),外观","coord":[{"x":213,"y":5},{"x":721,"y":6},{"x":721,"y":30},{"x":213,"y":30}]}]},{"angle":0,"conf":0.9946697950363159,"content":"整洁。但模板高空翻转,操作危险,沿海地区不宜用此法。","coord":[{"x":41,"y":27},{"x":457,"y":27},{"x":457,"y":50},{"x":41,"y":50}],"exception":0,"id":2,"words":[{"conf":1,"content":"整洁。但模板高空翻转,操作危险,沿海地区不宜用此法。","coord":[{"x":41,"y":27},{"x":456,"y":27},{"x":456,"y":51},{"x":41,"y":51}]}]},{"angle":0,"conf":0.9443647861480713,"content":"12.(","coord":[{"x":75,"y":61},{"x":122,"y":61},{"x":122,"y":81},{"x":75,"y":81}],"exception":0,"id":3,"words":[{"conf":1,"content":"12.(","coord":[{"x":75,"y":61},{"x":121,"y":61},{"x":121,"y":82},{"x":75,"y":82}]}]},{"angle":0,"conf":0.9936317205429077,"content":")模:施工速度快,劳动强度小,但技术要求高,施工控制复杂,外观","coord":[{"x":214,"y":61},{"x":722,"y":61},{"x":722,"y":84},{"x":214,"y":84}],"exception":0,"id":4,"words":[{"conf":1,"content":")模:施工速度快,劳动强度小,但技术要求高,施工控制复杂,外观","coord":[{"x":214,"y":61},{"x":721,"y":61},{"x":721,"y":85},{"x":214,"y":85}]}]},{"angle":0,"conf":0.9947617650032043,"content":"质量较差,且易污染。一般倾斜度较大,预留孔道及埋件多的索塔不宜用此法。","coord":[{"x":41,"y":83},{"x":600,"y":83},{"x":600,"y":106},{"x":41,"y":106}],"exception":0,"id":5,"words":[{"conf":1,"content":"质量较差,且易污染。一般倾斜度较大,预留孔道及埋件多的索塔不宜用此法。","coord":[{"x":41,"y":83},{"x":599,"y":83},{"x":599,"y":107},{"x":41,"y":107}]}]},{"angle":0,"conf":0.931337296962738,"content":"13.(","coord":[{"x":75,"y":117},{"x":120,"y":117},{"x":120,"y":137},{"x":75,"y":137}],"exception":0,"id":6,"words":[{"conf":1,"content":"13.(","coord":[{"x":75,"y":117},{"x":119,"y":117},{"x":119,"y":138},{"x":75,"y":138}]}]},{"angle":0,"conf":0.9884185791015625,"content":")模:兼有滑模和翻模的优势,适用斜拉桥一般索塔的施工。施工安全,","coord":[{"x":214,"y":116},{"x":721,"y":116},{"x":721,"y":139},{"x":214,"y":139}],"exception":0,"id":7,"words":[{"conf":1,"content":")模:兼有滑模和翻模的优势,适用斜拉桥一般索塔的施工。施工安全,","coord":[{"x":214,"y":116},{"x":720,"y":116},{"x":720,"y":140},{"x":214,"y":140}]}]},{"angle":0,"conf":0.9953885078430176,"content":"质量可靠,修补方便。国内外大多采用此法。","coord":[{"x":42,"y":139},{"x":361,"y":139},{"x":361,"y":160},{"x":42,"y":160}],"exception":0,"id":8,"words":[{"conf":1,"content":"质量可靠,修补方便。国内外大多采用此法。","coord":[{"x":42,"y":139},{"x":360,"y":139},{"x":360,"y":161},{"x":42,"y":161}]}]}],"width":777}],"protocol":"2.0","version":"4.0.0.1048"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

View File

@ -0,0 +1 @@
你是谁

Binary file not shown.

47
s6fb9d652.py Normal file
View File

@ -0,0 +1,47 @@
import os
APPId = os.environ.get("APPId")
APIKey = os.environ.get("APIKey")
APISecret = os.environ.get("APISecret")
# 请求数据
request_data = {
"header": {
"app_id": "123456",
"uid": "39769795890",
"did": "SR082321940000200",
"imei": "8664020318693660",
"imsi": "4600264952729100",
"mac": "6c:92:bf:65:c6:14",
"net_type": "wifi",
"net_isp": "CMCC",
"status": 3,
"res_id": ""
},
"parameter": {
"s6fb9d652": {
"result": {
"encoding": "utf8",
"compress": "raw",
"format": "plain"
}
}
},
"payload": {
"text": {
"encoding": "utf8",
"compress": "raw",
"format": "plain",
"status": 3,
"text": "./resource/input/text/queryMsg.txt"
}
}
}
# 请求地址
request_url = "https://cbm.cn-huabei-1.xf-yun.com/v1/private/s6fb9d652"
# 用于快速定位响应值

37
sample/APP.py Normal file
View File

@ -0,0 +1,37 @@
import gradio as gr
import random
import os
import sys
import importlib
from sample.aipass_client import execute
def generate_text(message):
svcID = 's6fb9d652'
data_md = importlib.import_module(svcID)
data_md.request_data['header']['app_id'] = data_md.APPId
queryMsg_path = data_md.request_data['payload']['text']['text']
print("queryMsg_path ", queryMsg_path)
with open(queryMsg_path, 'w+') as f:
f.write(message)
return execute(data_md.request_url, data_md.request_data, "POST", data_md.APPId, data_md.APIKey, data_md.APISecret)
def respond(message, chat_history):
msg = generate_text(message=message)
chat_history.append([message, msg])
return "", chat_history
def main ():
with gr.Blocks() as demo:
with gr.Column(min_width=800):
chatbot = gr.Chatbot()
with gr.Row():
message = gr.Textbox(min_width=730)
clear = gr.ClearButton([message, chatbot])
message.submit(respond, [message, chatbot], [message, chatbot])
demo.queue().launch( server_name="0.0.0.0")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

95
sample/aipass_client.py Normal file
View File

@ -0,0 +1,95 @@
import base64
import copy
import json
import pprint
import requests
import jsonpath_rw
from sample import ne_utils
from urllib import parse
response_path_list = ['$..payload.result', ]
media_type_list = ["text", "audio", "image", "video"]
# 准备请求数据
def prepare_req_data(request_data):
new_request_data = copy.deepcopy(request_data)
media_path2name = {}
for media_type in media_type_list:
media_expr = jsonpath_rw.parse("$..payload.*.{}".format(media_type))
media_match = media_expr.find(new_request_data)
if len(media_match) > 0:
for media in media_match:
media_path2name[str(media.full_path)] = media.value
for media_path, media_name in media_path2name.items():
payload_path_list = media_path.split(".")
f_data = ne_utils.get_file_bytes(media_name)
new_request_data['header']['status'] = 3
new_request_data['payload'][payload_path_list[1]][payload_path_list[2]] = base64.b64encode(f_data).decode()
new_request_data['payload'][payload_path_list[1]]['status'] = 3
return new_request_data
# 执行http请求
def execute(request_url, request_data, method, app_id, api_key, api_secret):
# 清除文件
print("calling %s"%request_url)
ne_utils.del_file('./resource/output')
# 获取请求url
auth_request_url = ne_utils.build_auth_request_url(request_url, method, api_key, api_secret)
url_result = parse.urlparse(request_url)
headers = {'content-type': "application/json", 'host': url_result.hostname, 'app_id': app_id}
# 准备待发送的数据
new_request_data = prepare_req_data(request_data)
# print("请求数据:{}\n".format(new_request_data))
response = requests.post(auth_request_url, data=json.dumps(new_request_data), headers=headers)
new_respnse = deal_response(response)
return new_respnse
# 处理响应数据
def deal_response(response):
temp_result = json.loads(response.content.decode())
# print("响应数据:{}\n".format(temp_result))
header = temp_result.get('header')
if header is None:
return
code = header.get('code')
if header is None or code != 0:
print("获取结果失败请根据code查证问题原因")
return
print("sid:{}".format(header.get('sid')))
# 打印Base64解码后数据并生成文件
if response_path_list is None or len(response_path_list) == 0:
return
for response_path in response_path_list:
response_expr = jsonpath_rw.parse(response_path)
response_match = response_expr.find(temp_result)
if len(response_match) > 0:
for response_item in response_match:
if response_item.value is None:
continue
encoding = response_item.value.get('encoding')
if encoding is None or len(encoding) == 0:
continue
for media_type in media_type_list:
media_value = response_item.value.get(media_type)
if media_value is None or len(media_value) == 0:
continue
real_data = base64.b64decode(media_value)
# print(real_data.decode('utf-8'))
return real_data.decode('utf-8')
# pprint.pprint(json.loads(real_data))
# response_path_split_list = response_path.split('.')
# write_file_path = "./resource/output/{}.{}".\
# format(response_path_split_list[len(response_path_split_list)-1], encoding)
# with open(write_file_path, "ab") as file:
# file.write(real_data)

8
sample/exception.py Normal file
View File

@ -0,0 +1,8 @@
class AssembleHeaderException(Exception):
def __init__(self, msg):
self.message = msg
class FileNotFoundException(Exception):
def __init__(self, msg):
self.message = msg

66
sample/ne_utils.py Normal file
View File

@ -0,0 +1,66 @@
import base64
import hashlib
import hmac
import os
import shutil
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time
from sample.exception import FileNotFoundException, AssembleHeaderException
from urllib import parse
def get_file_bytes(fd):
"""
根据文件路径一般相对获取二进制数据
:param fd: 文件路径
:return: 二进制数据不存在时为 None供后续判断
"""
if os.path.exists(fd):
with open(fd, "rb") as f:
wav_maker = f.read(4)
if b'RIFF' == wav_maker:
f.seek(44, 0)
else:
f.seek(0, 0)
f_data = f.read()
f.close()
else:
raise FileNotFoundException("{}:文件不存在".format(fd))
return f_data
def del_file(filepath):
"""
删除某一目录下的所有文件或文件夹
:param filepath: 路径
:return:
"""
del_list = os.listdir(filepath)
for f in del_list:
file_path = os.path.join(filepath, f)
if os.path.isfile(file_path):
os.remove(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
# 生成鉴权的url
def build_auth_request_url(request_url, method="POST", api_key="", api_secret=""):
url_result = parse.urlparse(request_url)
date = format_date_time(mktime(datetime.now().timetuple()))
signature_origin = "host: {}\ndate: {}\n{} {} HTTP/1.1".format(url_result.hostname, date, method, url_result.path)
signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'),
digestmod=hashlib.sha256).digest()
signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
api_key, "hmac-sha256", "host date request-line", signature_sha)
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
values = {
"host": url_result.hostname,
"date": date,
"authorization": authorization
}
return request_url + "?" + urlencode(values)