api-第三方
This commit is contained in:
parent
25681c16a4
commit
8dc8e13019
1
Pipfile
1
Pipfile
@ -63,6 +63,7 @@ uvicorn = "==0.34.0"
|
||||
uvloop = "==0.21.0"
|
||||
watchfiles = "==1.0.4"
|
||||
websockets = "==14.1"
|
||||
requests = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
||||
1407
Pipfile.lock
generated
Normal file
1407
Pipfile.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
302
aaa.txt
Normal file
302
aaa.txt
Normal file
@ -0,0 +1,302 @@
|
||||
企业软件著作权查询:
|
||||
接口地址 : https://openapi.chinaz.net/v1/1036/copyrightsoftware
|
||||
返回格式 : JSON
|
||||
请求方式 : POST
|
||||
请求参数:
|
||||
名称
|
||||
类型
|
||||
必填
|
||||
说明
|
||||
sign string 是 填写由"634xz年月日"生成的32位md5加密值("年月日"指调用api的日期)。 举例:如果是2021年5月6日调用api,则对634xz20210506进行md5加密,得到的32位加密值就是sign
|
||||
entName string 是 企业名称
|
||||
pageNo string 是 页码,值从1开始(表示第1页)
|
||||
range string 是 每页条数,取值介于在1到300之间(含1和300)
|
||||
APIKey string 是 申请接口时获取的APIKey值
|
||||
ChinazVer string 是 接口版本号,取值:2.0
|
||||
返回参数说明:
|
||||
名称
|
||||
类型
|
||||
说明
|
||||
rc string 状态码
|
||||
msg string 状态信息
|
||||
data object 数据对象
|
||||
data.total string 总数量
|
||||
data.totalPage string 总页数
|
||||
data.dataList object 软件著作权列表
|
||||
data.dataList[].SNAME string 软件全称
|
||||
data.dataList[].SHORTNAME string 软件简称
|
||||
data.dataList[].ENTNAME string 著作权人
|
||||
data.dataList[].SNUM string 登记号
|
||||
data.dataList[].REGDATE string 首次发表日期
|
||||
data.dataList[].ANNDATE string 登记批准日期
|
||||
data.dataList[].ANNTYPE string 分类号名称
|
||||
data.dataList[].TYPENUM string 分类号编号
|
||||
data.dataList[].VNUM string 版本号
|
||||
data.dataList[].cdate string 完成日期
|
||||
正确的返回示例:
|
||||
|
||||
{
|
||||
"orderNo":"202308281517124830015",
|
||||
"data":{
|
||||
"total":12,
|
||||
"totalPage":25,
|
||||
"dataList":[
|
||||
{
|
||||
"cdate":"2023-08-30",
|
||||
"ANNDATE":"2023-11-29",
|
||||
"SNUM":"2023SR1531019",
|
||||
"SHORTNAME":"ModelMate",
|
||||
"REGDATE":"2023-11-29",
|
||||
"SNAME":"AI模型使能平台",
|
||||
"VNUM":"24.0",
|
||||
"ENTNAME":"****有限公司",
|
||||
"ANNTYPE":"****",
|
||||
"TYPENUM":"438951"
|
||||
}
|
||||
]
|
||||
},
|
||||
"rc":"0000",
|
||||
"msg":"查询成功"
|
||||
}
|
||||
|
||||
错误的返回示例:
|
||||
{
|
||||
"rc":"1002",
|
||||
"msg":"sign校验失败"
|
||||
}
|
||||
|
||||
|
||||
企业专利信息
|
||||
|
||||
接口地址 : https://openapi.chinaz.net/v1/1036/patent
|
||||
返回格式 : JSON
|
||||
请求方式 : POST
|
||||
请求参数:
|
||||
名称
|
||||
类型
|
||||
必填
|
||||
说明
|
||||
sign string 是 填写由"634xz年月日"生成的32位md5加密值("年月日"指调用api的日期)。 举例:如果是2021年5月6日调用api,则对634xz20210506进行md5加密,得到的32位加密值就是sign
|
||||
searchKey string 是 查询关键词(企业名称、企业统代、企业注册号)
|
||||
searchType string 否 查询关键字类型;默认为0:支持的所有类型;1:企业名称;2:统一社会信用代码;3:注册号;
|
||||
pageNo string 是 页码,值从1开始(表示第1页)
|
||||
range string 是 每页条数,取值介于在1到300之间(含1和300)
|
||||
APIKey string 是 申请接口时获取的APIKey值
|
||||
ChinazVer string 是 接口版本号,取值:2.0
|
||||
返回参数说明:
|
||||
名称
|
||||
类型
|
||||
说明
|
||||
rc string 状态码
|
||||
msg string 状态信息
|
||||
data object 数据列表
|
||||
data.total string 总数量
|
||||
data.totalPage string 总页数
|
||||
data.dataList string 专利信息列表
|
||||
data.dataList[].patentflls string 专利法律状态信息列表
|
||||
data.dataList[].patentflls[].flzt string 法律状态
|
||||
data.dataList[].patentflls[].flztxq string 法律状态详情
|
||||
data.dataList[].patentflls[].flztggrq string 法律状态公告日期
|
||||
data.dataList[].SQH string 专利申请号
|
||||
data.dataList[].PATNAME string 专利标题
|
||||
data.dataList[].SQR string 申请/专利权人
|
||||
data.dataList[].SQRQ string 申请日期
|
||||
data.dataList[].GKGGH string 公开/公告号
|
||||
data.dataList[].FMR string 发明/设计人
|
||||
data.dataList[].GKGGR string 公开/公告日
|
||||
data.dataList[].FCFL string 范畴分类
|
||||
data.dataList[].FLH string 分类号
|
||||
data.dataList[].PTYPE string 专利分类
|
||||
data.dataList[].DLR string 代理人
|
||||
data.dataList[].DZ string 地址
|
||||
data.dataList[].FASQ string 分案申请
|
||||
data.dataList[].GJGB string 国际公布
|
||||
data.dataList[].GJSQ string 国际申请
|
||||
data.dataList[].GSDM string 国省代码
|
||||
data.dataList[].JRGJRQ string 进入国家日期
|
||||
data.dataList[].YXQ string 优先权
|
||||
data.dataList[].YZWX string 引证文献
|
||||
data.dataList[].ZFLH string 主分类号
|
||||
data.dataList[].ZLDLJG string 专利代理机构
|
||||
data.dataList[].ZQX string 主权项
|
||||
data.dataList[].ZY string 摘要
|
||||
data.dataList[].IPC string 专利行业分类
|
||||
data.dataList[].PID string 专利ID
|
||||
data.dataList[].PIC string 代表图片
|
||||
data.dataList[].SQGKGGH string 授权公告号
|
||||
data.dataList[].SQGKGGR string 授权公开日期
|
||||
data.dataList[].ENTNAME string 申请企业
|
||||
data.dataList[].ZFLNAME string 主分类名称
|
||||
|
||||
|
||||
|
||||
司法综合数据查询
|
||||
接口地址 : https://openapi.chinaz.net/v1/1036/judgementdetailv4
|
||||
返回格式 : JSON
|
||||
请求方式 : POST
|
||||
调用说明 : 司法数据综合查询接口数据非实时,可能存在部分数据延迟。该数据仅供参考,不作为判定具体结果使用。
|
||||
请求参数:
|
||||
名称
|
||||
类型
|
||||
必填
|
||||
说明
|
||||
sign string 是 填写由"634xz年月日"生成的32位md5加密值("年月日"指调用api的日期)。 举例:如果是2021年5月6日调用api,则对634xz20210506进行md5加密,得到的32位加密值就是sign
|
||||
q string 否 名称,选填,列表检索时(即查详情,也即id不填时)必填
|
||||
idCardNo string 否 身份证号,选填,一般查个人时填写查询会更加精确
|
||||
datatype string 否 查询数据类型,多个以',' 分割,共有zxgg(被执行人)、sxgg(失信被执行人)、ktgg(开庭公告)、fygg(法院公告)、cpws(裁判文书)、splc(审判流程)六种数据类型,如果列表检索时,该字段默认为六种数据类型都填
|
||||
id string 否 详情id,该id从检索结果中获取,请配合查询数据类型使用。如查询某条被执行人详情时,datatype必须填'zxgg'
|
||||
pageNo string 否 页码,列表检索时输入的字段,默认为1
|
||||
APIKey string 是 申请接口时获取的APIKey值
|
||||
ChinazVer string 是 接口版本号,取值:1.0
|
||||
返回参数说明:
|
||||
名称
|
||||
类型
|
||||
说明
|
||||
rc string 状态码
|
||||
msg string 状态信息
|
||||
orderNo string 订单号
|
||||
data string 返回查询结果
|
||||
count string 检索出每种数据类型的总量统计
|
||||
count[].bzxrCount string 被执行人总量
|
||||
count[].sxrCount string 失信被执行人总量
|
||||
count[].ktggCount string 开庭公告总量
|
||||
count[].fyggCount string 法院公告数量
|
||||
count[].cpwsCount string 裁判文书数量
|
||||
count[].splcCount string 审判流程数量
|
||||
list string 检索出每种数据类型数据列表
|
||||
list[].bzxrList string 被执行人列表
|
||||
bzxrList[].id string 被执行人ID
|
||||
bzxrList[].entityName string 主体名称
|
||||
bzxrList[].entityId string 主体代码
|
||||
bzxrList[].courtName string 法院
|
||||
bzxrList[].caseCode string 案号
|
||||
bzxrList[].regDate string 立案时间
|
||||
bzxrList[].relateType string 数据类别
|
||||
list[].sxrList string 失信被执行人列表
|
||||
sxrList[].id string 失信被执行人ID
|
||||
sxrList[].entityName string 主体名称
|
||||
sxrList[].entityId string 主体代码
|
||||
sxrList[].courtName string 法院
|
||||
sxrList[].caseCode string 案号
|
||||
sxrList[].regDate string 立案时间
|
||||
sxrList[].relateType string 数据类别
|
||||
list[].ktggList string 开庭公告列表
|
||||
ktggList[].id string 开庭公告ID
|
||||
ktggList[].content string 开庭公告文书内容
|
||||
list[].fyggList string 法院公告列表
|
||||
fyggList[].id string 法院公告ID
|
||||
fyggList[].content string 法院公告文书内容
|
||||
list[].cpwsList string 裁判文书列表
|
||||
cpwsList[].id string 裁判文书ID
|
||||
cpwsList[].title string 标题
|
||||
cpwsList[].caseCode string 案号
|
||||
cpwsList[].court string 法院
|
||||
cpwsList[].standPoint string 查询主体立场
|
||||
cpwsList[].judgeDate string 裁判日期
|
||||
cpwsList[].content string 文书缩略内容
|
||||
cpwsList[].resultMatch string 个人查询匹配度,个人查询时有值,企业查询返回是空值
|
||||
list[].splcList string 审判流程列表
|
||||
splcList[].id string 审判流程ID
|
||||
splcList[].litigant string 当事人
|
||||
splcList[].courtName string 法院
|
||||
splcList[].caseCode string 案号
|
||||
entityName string 主体名称
|
||||
entityId string 主体代码
|
||||
courtName string 法院
|
||||
caseState string 案件状态
|
||||
caseCode string 案号
|
||||
execMoney string 执行标的
|
||||
regDate string 立案时间
|
||||
gistId string 依据文号
|
||||
entityName string 主体名称
|
||||
entityId string 主体代码
|
||||
caseCode string 案号
|
||||
age string 年龄
|
||||
sex string 性别
|
||||
bussinessEntity string 法定代表人或者负责人姓名
|
||||
courtName string 法院
|
||||
areaName string 省份
|
||||
partyTypeName string 类型
|
||||
gistId string 执行依据文号
|
||||
regDate string 立案时间
|
||||
gistUnit string 做出执行依据单位
|
||||
duty string 生效法律文书确定的义务
|
||||
performance string 被执行人的履行情况
|
||||
performedPart string 已履行
|
||||
unPerformPart string 未履行
|
||||
disruptTypeName string 失信类型
|
||||
publishDate string 发布日期
|
||||
status string 下架状态:已下架,未下架
|
||||
ktggId string 开庭公告ID
|
||||
areaName string 地区名称
|
||||
court string 审理法院
|
||||
caseNo string 案号
|
||||
content string 公告内容
|
||||
openTime string 开庭时间
|
||||
litigant string 当事人,多个以顿号分开
|
||||
plaintiff string 原告,多个以顿号分开
|
||||
defendant string 被告,多个以顿号分开
|
||||
caseCause string 案由
|
||||
type string 公告类型
|
||||
announcer string 公告人
|
||||
litigant string 当事人
|
||||
content string 公告内容
|
||||
publishDate string 公告时间
|
||||
baseInfo string 案件详情
|
||||
baseInfo.caseCode string 案号
|
||||
baseInfo.judgeDate string 裁判日期
|
||||
baseInfo.title string 标题
|
||||
baseInfo.publishDate string 发布日期
|
||||
baseInfo.caseType string 案件类型
|
||||
baseInfo.docType string 文书类型
|
||||
baseInfo.caseCause string 案由
|
||||
baseInfo.court string 法院
|
||||
baseInfo.province string 省份
|
||||
baseInfo.program string 审判程序
|
||||
baseInfo.clauseContent string 审判依据
|
||||
baseInfo.resultContent string 审判结果
|
||||
baseInfo.content string 文书缩略内容
|
||||
baseInfo.id string 裁判文书ID
|
||||
roleList[] string 角色详情
|
||||
roleList[].roleName string 角色
|
||||
roleList[].standpoint string 立场
|
||||
roleList[].entityName string 名称
|
||||
roleList[].birthday string 生日
|
||||
roleList[].gender string 性别
|
||||
roleList[].nativePlace string 籍贯
|
||||
roleList[].address string 地址
|
||||
roleList[].workUnit string 工作单位
|
||||
roleList[].nation string 民族
|
||||
roleList[].organizationCode string 组织机构代码
|
||||
roleList[].socialCreditCode string 统一社会信用代码
|
||||
roleList[].idcard string 身份证
|
||||
roleList[].jobTitle string 职位
|
||||
judgeResultList[] string 判决结果
|
||||
judgeResultList[].price string 涉案金额
|
||||
judgeResultList[].realPrice string 实际金额
|
||||
judgeResultList[].fromRole string 负担角色
|
||||
judgeResultList[].way string 处置方式
|
||||
judgeResultList[].toRole string 受让角色
|
||||
judgeResultList[].priceType string 金额类型
|
||||
judgeResultList[].priceUnit string 金额单位
|
||||
judgeResultList[].currency string 币种
|
||||
relationCaseList[] string 案件关联
|
||||
relationCaseList[].caseCode string 案号
|
||||
relationCaseList[].court string 法院
|
||||
relationCaseList[].realationCaseCode string 关联案号
|
||||
relationCaseList[].relationCaseId string 关联文书ID
|
||||
areaName string 区域名称
|
||||
litigant string 当事人
|
||||
accuser string 原告
|
||||
defender string 被告
|
||||
others string 其他
|
||||
courtName string 法院
|
||||
caseCode string 案号
|
||||
caseStat string 案件状态
|
||||
openTime string 立案时间
|
||||
trialTime string 开庭时间
|
||||
closeTime string 结案时间
|
||||
program string 审判程序
|
||||
reason string 案由
|
||||
caseType string 案件类型
|
||||
target string 诉讼标的
|
||||
@ -12,6 +12,7 @@ from .industry.industry import router as industry_router
|
||||
from .menus import menus_router
|
||||
from .policy.policy import router as policy_router
|
||||
from .roles import roles_router
|
||||
from .third_party_api import third_party_api_router
|
||||
from .users import users_router
|
||||
|
||||
v1_router = APIRouter()
|
||||
@ -27,3 +28,4 @@ v1_router.include_router(esg_router, prefix="/esg", dependencies=[DependPermissi
|
||||
v1_router.include_router(index_router, prefix="/index", dependencies=[DependPermission])
|
||||
v1_router.include_router(industry_router, prefix="/industry", dependencies=[DependPermission])
|
||||
v1_router.include_router(policy_router, prefix="/policy", dependencies=[DependPermission])
|
||||
v1_router.include_router(third_party_api_router, prefix="/third_party_api", dependencies=[DependPermission])
|
||||
|
||||
3
app/api/v1/third_party_api/__init__.py
Normal file
3
app/api/v1/third_party_api/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .third_party_api import router as third_party_api_router
|
||||
|
||||
__all__ = ["third_party_api_router"]
|
||||
93
app/api/v1/third_party_api/third_party_api.py
Normal file
93
app/api/v1/third_party_api/third_party_api.py
Normal file
@ -0,0 +1,93 @@
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Query, Body, HTTPException
|
||||
|
||||
from app.controllers.third_party_api import third_party_api_controller
|
||||
from app.schemas.base import Success, Fail
|
||||
from app.schemas.third_party_api import (
|
||||
BaseAPIRequest,
|
||||
ChinazAPIRequest,
|
||||
XiaohongshuNoteRequest,
|
||||
APIResponse,
|
||||
APIProviderInfo,
|
||||
APIEndpointInfo,
|
||||
APIListResponse
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(tags=["内置接口"])
|
||||
|
||||
# 站长之家API端点
|
||||
|
||||
@router.post("/chinaz/copyright_software", summary="企业软件著作权查询")
|
||||
async def query_copyright_software(request: ChinazAPIRequest):
|
||||
"""查询企业软件著作权信息"""
|
||||
try:
|
||||
result = await third_party_api_controller.query_copyright_software(
|
||||
company_name=request.company_name,
|
||||
chinaz_ver=request.chinaz_ver
|
||||
)
|
||||
|
||||
if result.success:
|
||||
return Success(data=result.data, message=result.message)
|
||||
else:
|
||||
return Fail(message=result.message)
|
||||
except Exception as e:
|
||||
logger.error(f"查询企业软件著作权失败: {e}")
|
||||
return Fail(message=f"查询企业软件著作权失败: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/chinaz/patent_info", summary="企业专利信息查询")
|
||||
async def query_patent_info(request: ChinazAPIRequest):
|
||||
"""查询企业专利信息"""
|
||||
try:
|
||||
result = await third_party_api_controller.query_patent_info(
|
||||
company_name=request.company_name,
|
||||
chinaz_ver=request.chinaz_ver
|
||||
)
|
||||
|
||||
if result.success:
|
||||
return Success(data=result.data, message=result.message)
|
||||
else:
|
||||
return Fail(message=result.message)
|
||||
except Exception as e:
|
||||
logger.error(f"查询企业专利信息失败: {e}")
|
||||
return Fail(message=f"查询企业专利信息失败: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/chinaz/judicial_data", summary="司法综合数据查询")
|
||||
async def query_judicial_data(request: ChinazAPIRequest):
|
||||
"""查询司法综合数据"""
|
||||
try:
|
||||
result = await third_party_api_controller.query_judicial_data(
|
||||
company_name=request.company_name,
|
||||
chinaz_ver=request.chinaz_ver
|
||||
)
|
||||
|
||||
if result.success:
|
||||
return Success(data=result.data, message=result.message)
|
||||
else:
|
||||
return Fail(message=result.message)
|
||||
except Exception as e:
|
||||
logger.error(f"查询司法综合数据失败: {e}")
|
||||
return Fail(message=f"查询司法综合数据失败: {str(e)}")
|
||||
|
||||
|
||||
# 小红书API端点
|
||||
@router.post("/xiaohongshu/note", summary="获取小红书笔记详情")
|
||||
async def get_xiaohongshu_note(request: XiaohongshuNoteRequest):
|
||||
"""获取小红书笔记详情"""
|
||||
try:
|
||||
result = await third_party_api_controller.get_xiaohongshu_note(
|
||||
note_id=request.note_id
|
||||
)
|
||||
|
||||
if result.success:
|
||||
return Success(data=result.data, message=result.message)
|
||||
else:
|
||||
return Fail(message=result.message)
|
||||
except Exception as e:
|
||||
logger.error(f"获取小红书笔记失败: {e}")
|
||||
return Fail(message=f"获取小红书笔记失败: {str(e)}")
|
||||
106
app/controllers/third_party_api.py
Normal file
106
app/controllers/third_party_api.py
Normal file
@ -0,0 +1,106 @@
|
||||
import logging
|
||||
from typing import Dict, Any, List, Optional
|
||||
|
||||
from app.utils.universal_api_manager import universal_api
|
||||
from app.schemas.third_party_api import (
|
||||
APIProviderInfo,
|
||||
APIEndpointInfo,
|
||||
APIResponse
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ThirdPartyAPIController:
|
||||
"""第三方API控制器"""
|
||||
|
||||
def __init__(self):
|
||||
self.api_manager = universal_api
|
||||
|
||||
async def make_api_request(
|
||||
self,
|
||||
provider: str,
|
||||
endpoint: str,
|
||||
params: Dict[str, Any] = None,
|
||||
timeout: int = 30
|
||||
) -> APIResponse:
|
||||
"""通用API请求方法"""
|
||||
try:
|
||||
result = self.api_manager.make_request(
|
||||
provider=provider,
|
||||
endpoint=endpoint,
|
||||
params=params or {},
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
return APIResponse(
|
||||
success=True,
|
||||
data=result,
|
||||
message="请求成功",
|
||||
provider=provider,
|
||||
endpoint=endpoint
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"API请求失败: {e}")
|
||||
return APIResponse(
|
||||
success=False,
|
||||
data={},
|
||||
message=f"请求失败: {str(e)}",
|
||||
provider=provider,
|
||||
endpoint=endpoint
|
||||
)
|
||||
|
||||
# 站长之家API便捷方法
|
||||
async def query_copyright_software(self, company_name: str, chinaz_ver: str = "1") -> APIResponse:
|
||||
"""查询企业软件著作权"""
|
||||
return await self.make_api_request(
|
||||
provider="chinaz",
|
||||
endpoint="copyright_software",
|
||||
params={
|
||||
"entName": company_name,
|
||||
"pageNo": 1,
|
||||
"range": 100,
|
||||
"ChinazVer": chinaz_ver
|
||||
}
|
||||
)
|
||||
|
||||
async def query_patent_info(self, company_name: str, chinaz_ver: str = "1") -> APIResponse:
|
||||
"""查询企业专利信息"""
|
||||
return await self.make_api_request(
|
||||
provider="chinaz",
|
||||
endpoint="patent",
|
||||
params={
|
||||
"searchKey": company_name,
|
||||
"pageNo": 1,
|
||||
"range": 100,
|
||||
"searchType": "0",
|
||||
"ChinazVer": chinaz_ver
|
||||
}
|
||||
)
|
||||
|
||||
async def query_judicial_data(self, company_name: str, chinaz_ver: str = "1") -> APIResponse:
|
||||
"""查询司法综合数据"""
|
||||
return await self.make_api_request(
|
||||
provider="chinaz",
|
||||
endpoint="judgement",
|
||||
params={
|
||||
"q": company_name,
|
||||
"pageNo": 1,
|
||||
"ChinazVer": chinaz_ver
|
||||
}
|
||||
)
|
||||
|
||||
# 小红书API便捷方法
|
||||
async def get_xiaohongshu_note(self, note_id: str) -> APIResponse:
|
||||
"""获取小红书笔记详情"""
|
||||
params = {"noteId": note_id}
|
||||
|
||||
return await self.make_api_request(
|
||||
provider="justoneapi",
|
||||
endpoint="xiaohongshu_note_detail",
|
||||
params=params
|
||||
)
|
||||
|
||||
|
||||
# 创建全局控制器实例
|
||||
third_party_api_controller = ThirdPartyAPIController()
|
||||
@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from tortoise import fields, models
|
||||
|
||||
@ -9,7 +10,7 @@ from app.settings import settings
|
||||
class BaseModel(models.Model):
|
||||
id = fields.BigIntField(pk=True, index=True)
|
||||
|
||||
async def to_dict(self, m2m: bool = False, exclude_fields: list[str] | None = None):
|
||||
async def to_dict(self, m2m: bool = False, exclude_fields: Optional[List[str]] = None):
|
||||
if exclude_fields is None:
|
||||
exclude_fields = []
|
||||
|
||||
|
||||
@ -1,4 +1,11 @@
|
||||
from enum import Enum, StrEnum
|
||||
import sys
|
||||
from enum import Enum
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
from enum import StrEnum
|
||||
else:
|
||||
class StrEnum(str, Enum):
|
||||
pass
|
||||
|
||||
|
||||
class EnumBase(Enum):
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
from enum import StrEnum
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
from enum import StrEnum
|
||||
else:
|
||||
from enum import Enum
|
||||
class StrEnum(str, Enum):
|
||||
pass
|
||||
|
||||
|
||||
class MenuType(StrEnum):
|
||||
CATALOG = "catalog" # 目录
|
||||
|
||||
55
app/schemas/third_party_api.py
Normal file
55
app/schemas/third_party_api.py
Normal file
@ -0,0 +1,55 @@
|
||||
from typing import Dict, Any, Optional, List
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class BaseAPIRequest(BaseModel):
|
||||
"""基础API请求模型"""
|
||||
provider: str = Field(..., description="API提供商", example="chinaz")
|
||||
endpoint: str = Field(..., description="端点名称", example="icp_info")
|
||||
params: Dict[str, Any] = Field(default_factory=dict, description="请求参数")
|
||||
timeout: Optional[int] = Field(30, description="超时时间(秒)")
|
||||
|
||||
|
||||
class ChinazAPIRequest(BaseModel):
|
||||
"""站长之家API请求模型"""
|
||||
company_name: str = Field(..., description="公司名称", example="百度在线网络技术(北京)有限公司")
|
||||
chinaz_ver: Optional[str] = Field("1", description="API版本", example="1")
|
||||
timeout: Optional[int] = Field(30, description="超时时间(秒)")
|
||||
|
||||
|
||||
class XiaohongshuNoteRequest(BaseModel):
|
||||
"""小红书笔记详情请求"""
|
||||
note_id: str = Field(..., description="笔记ID", example="68d2c71d000000000e00e9ea")
|
||||
|
||||
|
||||
class APIResponse(BaseModel):
|
||||
"""API响应模型"""
|
||||
success: bool = Field(..., description="请求是否成功")
|
||||
data: Dict[str, Any] = Field(..., description="响应数据")
|
||||
message: Optional[str] = Field(None, description="响应消息")
|
||||
provider: Optional[str] = Field(None, description="API提供商")
|
||||
endpoint: Optional[str] = Field(None, description="端点名称")
|
||||
|
||||
|
||||
class APIProviderInfo(BaseModel):
|
||||
"""API提供商信息"""
|
||||
name: str = Field(..., description="提供商名称")
|
||||
base_url: str = Field(..., description="基础URL")
|
||||
description: Optional[str] = Field(None, description="描述")
|
||||
endpoints: List[str] = Field(default_factory=list, description="可用端点")
|
||||
|
||||
|
||||
class APIEndpointInfo(BaseModel):
|
||||
"""API端点信息"""
|
||||
name: str = Field(..., description="端点名称")
|
||||
path: str = Field(..., description="请求路径")
|
||||
method: str = Field(..., description="HTTP方法")
|
||||
description: Optional[str] = Field(None, description="描述")
|
||||
required_params: List[str] = Field(default_factory=list, description="必需参数")
|
||||
optional_params: List[str] = Field(default_factory=list, description="可选参数")
|
||||
|
||||
|
||||
class APIListResponse(BaseModel):
|
||||
"""API列表响应"""
|
||||
providers: List[APIProviderInfo] = Field(..., description="API提供商列表")
|
||||
total_providers: int = Field(..., description="提供商总数")
|
||||
259
app/utils/api_config.py
Normal file
259
app/utils/api_config.py
Normal file
@ -0,0 +1,259 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
第三方API配置管理
|
||||
支持从配置文件或环境变量加载API配置信息
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from typing import Dict, Any, Optional
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class APIConfig:
|
||||
"""API配置管理器"""
|
||||
|
||||
def __init__(self, config_file: str = None):
|
||||
"""
|
||||
初始化配置管理器
|
||||
|
||||
Args:
|
||||
config_file: 配置文件路径
|
||||
"""
|
||||
self.config_file = config_file or os.path.join(os.path.dirname(__file__), 'api_config.json')
|
||||
self.config = self._load_config()
|
||||
|
||||
def _load_config(self) -> Dict[str, Any]:
|
||||
"""加载配置"""
|
||||
# 默认配置
|
||||
default_config = {
|
||||
"chinaz": {
|
||||
"api_key": os.getenv("CHINAZ_API_KEY", "YOUR_API_KEY"),
|
||||
"base_url": "https://openapi.chinaz.net",
|
||||
"endpoints": {
|
||||
"copyright_software": {
|
||||
"path": "/v1/1036/copyrightsoftware",
|
||||
"method": "POST",
|
||||
"description": "企业软件著作权查询",
|
||||
"required_params": ["entName", "pageNo", "range", "APIKey", "ChinazVer"],
|
||||
"optional_params": ["sign"]
|
||||
},
|
||||
"patent": {
|
||||
"path": "/v1/1036/patent",
|
||||
"method": "POST",
|
||||
"description": "企业专利信息查询",
|
||||
"required_params": ["searchKey", "pageNo", "range", "APIKey", "ChinazVer"],
|
||||
"optional_params": ["sign", "searchType"]
|
||||
},
|
||||
"judgement": {
|
||||
"path": "/v1/1036/judgementdetailv4",
|
||||
"method": "POST",
|
||||
"description": "司法综合数据查询",
|
||||
"required_params": ["APIKey", "ChinazVer"],
|
||||
"optional_params": ["sign", "q", "idCardNo", "datatype", "id", "pageNo"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"justoneapi": {
|
||||
"api_key": os.getenv("JUSTONEAPI_TOKEN", "YNSbIjdU"),
|
||||
"base_url": "https://api.justoneapi.com",
|
||||
"timeout": 30,
|
||||
"retries": 3,
|
||||
"endpoints": {
|
||||
"xiaohongshu_note_detail": {
|
||||
"path": "/api/xiaohongshu/get-note-detail/v7",
|
||||
"method": "GET",
|
||||
"description": "小红书笔记详情查询",
|
||||
"required_params": ["noteId"],
|
||||
"optional_params": ["token"]
|
||||
},
|
||||
"xiaohongshu_user_info": {
|
||||
"path": "/api/xiaohongshu/get-user-info/v7",
|
||||
"method": "GET",
|
||||
"description": "小红书用户信息查询",
|
||||
"required_params": ["userId"],
|
||||
"optional_params": ["token"]
|
||||
},
|
||||
"xiaohongshu_search_notes": {
|
||||
"path": "/api/xiaohongshu/search-notes/v7",
|
||||
"method": "GET",
|
||||
"description": "小红书笔记搜索",
|
||||
"required_params": ["keyword"],
|
||||
"optional_params": ["page", "size", "token"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"other_apis": {
|
||||
# 可以添加其他第三方API配置
|
||||
"example_api": {
|
||||
"api_key": os.getenv("EXAMPLE_API_KEY", ""),
|
||||
"base_url": "https://api.example.com",
|
||||
"endpoints": {}
|
||||
}
|
||||
},
|
||||
"common_settings": {
|
||||
"timeout": 60,
|
||||
"retries": 3,
|
||||
"sign_prefix": "634xz"
|
||||
}
|
||||
}
|
||||
|
||||
# 尝试从文件加载配置
|
||||
if os.path.exists(self.config_file):
|
||||
try:
|
||||
with open(self.config_file, 'r', encoding='utf-8') as f:
|
||||
file_config = json.load(f)
|
||||
# 合并配置
|
||||
self._merge_config(default_config, file_config)
|
||||
except Exception as e:
|
||||
print(f"加载配置文件失败: {e}")
|
||||
|
||||
return default_config
|
||||
|
||||
def _merge_config(self, default: Dict[str, Any], custom: Dict[str, Any]) -> None:
|
||||
"""递归合并配置"""
|
||||
for key, value in custom.items():
|
||||
if key in default and isinstance(default[key], dict) and isinstance(value, dict):
|
||||
self._merge_config(default[key], value)
|
||||
else:
|
||||
default[key] = value
|
||||
|
||||
def get_api_config(self, provider: str) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
获取指定提供商的API配置
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
|
||||
Returns:
|
||||
Optional[Dict[str, Any]]: API配置信息
|
||||
"""
|
||||
return self.config.get(provider)
|
||||
|
||||
def get_endpoint_config(self, provider: str, endpoint: str) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
获取指定端点的配置
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
endpoint: 端点名称
|
||||
|
||||
Returns:
|
||||
Optional[Dict[str, Any]]: 端点配置信息
|
||||
"""
|
||||
api_config = self.get_api_config(provider)
|
||||
if api_config and 'endpoints' in api_config:
|
||||
return api_config['endpoints'].get(endpoint)
|
||||
return None
|
||||
|
||||
def get_api_key(self, provider: str) -> Optional[str]:
|
||||
"""
|
||||
获取API密钥
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
|
||||
Returns:
|
||||
Optional[str]: API密钥
|
||||
"""
|
||||
api_config = self.get_api_config(provider)
|
||||
return api_config.get('api_key') if api_config else None
|
||||
|
||||
def get_base_url(self, provider: str) -> Optional[str]:
|
||||
"""
|
||||
获取基础URL
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
|
||||
Returns:
|
||||
Optional[str]: 基础URL
|
||||
"""
|
||||
api_config = self.get_api_config(provider)
|
||||
return api_config.get('base_url') if api_config else None
|
||||
|
||||
def set_api_key(self, provider: str, api_key: str) -> None:
|
||||
"""
|
||||
设置API密钥
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
api_key: API密钥
|
||||
"""
|
||||
if provider not in self.config:
|
||||
self.config[provider] = {}
|
||||
self.config[provider]['api_key'] = api_key
|
||||
|
||||
def add_endpoint(self,
|
||||
provider: str,
|
||||
endpoint_name: str,
|
||||
path: str,
|
||||
method: str = 'POST',
|
||||
description: str = '',
|
||||
required_params: list = None,
|
||||
optional_params: list = None) -> None:
|
||||
"""
|
||||
添加新的API端点
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
endpoint_name: 端点名称
|
||||
path: API路径
|
||||
method: HTTP方法
|
||||
description: 描述信息
|
||||
required_params: 必需参数列表
|
||||
optional_params: 可选参数列表
|
||||
"""
|
||||
if provider not in self.config:
|
||||
self.config[provider] = {'endpoints': {}}
|
||||
|
||||
if 'endpoints' not in self.config[provider]:
|
||||
self.config[provider]['endpoints'] = {}
|
||||
|
||||
self.config[provider]['endpoints'][endpoint_name] = {
|
||||
'path': path,
|
||||
'method': method.upper(),
|
||||
'description': description,
|
||||
'required_params': required_params or [],
|
||||
'optional_params': optional_params or []
|
||||
}
|
||||
|
||||
def save_config(self) -> None:
|
||||
"""保存配置到文件"""
|
||||
try:
|
||||
# 创建目录(如果不存在)
|
||||
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
||||
|
||||
with open(self.config_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(self.config, f, indent=2, ensure_ascii=False)
|
||||
print(f"配置已保存到: {self.config_file}")
|
||||
except Exception as e:
|
||||
print(f"保存配置失败: {e}")
|
||||
|
||||
def get_common_settings(self) -> Dict[str, Any]:
|
||||
"""获取通用设置"""
|
||||
return self.config.get('common_settings', {})
|
||||
|
||||
def list_providers(self) -> list:
|
||||
"""列出所有API提供商"""
|
||||
return [key for key in self.config.keys() if key != 'common_settings']
|
||||
|
||||
def list_endpoints(self, provider: str) -> list:
|
||||
"""
|
||||
列出指定提供商的所有端点
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
|
||||
Returns:
|
||||
list: 端点名称列表
|
||||
"""
|
||||
api_config = self.get_api_config(provider)
|
||||
if api_config and 'endpoints' in api_config:
|
||||
return list(api_config['endpoints'].keys())
|
||||
return []
|
||||
|
||||
|
||||
# 创建全局配置实例
|
||||
api_config = APIConfig()
|
||||
312
app/utils/universal_api_manager.py
Normal file
312
app/utils/universal_api_manager.py
Normal file
@ -0,0 +1,312 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
通用第三方API管理器
|
||||
支持多种不同类型的第三方API,包括需要签名和不需要签名的API
|
||||
"""
|
||||
|
||||
import os
|
||||
import hashlib
|
||||
import requests
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, Optional, Union
|
||||
import json
|
||||
import time
|
||||
import urllib.parse
|
||||
from .api_config import api_config
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UniversalAPIManager:
|
||||
"""通用第三方API管理器"""
|
||||
|
||||
def __init__(self):
|
||||
"""初始化API管理器"""
|
||||
self.config = api_config
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update({
|
||||
'User-Agent': 'Universal-API-Manager/1.0',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
})
|
||||
|
||||
def _get_provider_config(self, provider: str) -> Dict[str, Any]:
|
||||
"""获取API提供商配置"""
|
||||
config = self.config.get_api_config(provider)
|
||||
if not config:
|
||||
raise ValueError(f"未找到API提供商配置: {provider}")
|
||||
return config
|
||||
|
||||
def _get_endpoint_config(self, provider: str, endpoint: str) -> Dict[str, Any]:
|
||||
"""获取端点配置"""
|
||||
endpoint_config = self.config.get_endpoint_config(provider, endpoint)
|
||||
if not endpoint_config:
|
||||
raise ValueError(f"未找到端点配置: {provider}.{endpoint}")
|
||||
return endpoint_config
|
||||
|
||||
def _generate_chinaz_sign(self, date: datetime = None) -> str:
|
||||
"""
|
||||
生成站长之家API签名
|
||||
|
||||
Args:
|
||||
date: 指定日期,默认为当前日期
|
||||
|
||||
Returns:
|
||||
str: 32位MD5签名
|
||||
"""
|
||||
if date is None:
|
||||
date = datetime.now()
|
||||
|
||||
# 格式化日期为YYYYMMDD
|
||||
date_str = date.strftime("%Y%m%d")
|
||||
|
||||
# 构建签名字符串
|
||||
sign_str = f"634xz{date_str}"
|
||||
|
||||
# 生成MD5哈希
|
||||
md5_hash = hashlib.md5(sign_str.encode('utf-8')).hexdigest()
|
||||
|
||||
return md5_hash
|
||||
|
||||
def _build_url(self, provider: str, endpoint: str, params: Dict[str, Any]) -> str:
|
||||
"""
|
||||
构建完整的API请求URL
|
||||
|
||||
Args:
|
||||
provider: API提供商
|
||||
endpoint: 端点名称
|
||||
params: 请求参数
|
||||
|
||||
Returns:
|
||||
str: 完整的URL
|
||||
"""
|
||||
provider_config = self._get_provider_config(provider)
|
||||
endpoint_config = self._get_endpoint_config(provider, endpoint)
|
||||
|
||||
base_url = provider_config['base_url']
|
||||
path = endpoint_config['path']
|
||||
method = endpoint_config['method']
|
||||
|
||||
# 构建完整URL
|
||||
full_url = f"{base_url}{path}"
|
||||
|
||||
# 处理参数
|
||||
if method.upper() == 'GET' and params:
|
||||
# 对于GET请求,将参数添加到URL中
|
||||
query_string = urllib.parse.urlencode(params)
|
||||
full_url = f"{full_url}?{query_string}"
|
||||
|
||||
return full_url
|
||||
|
||||
def _validate_params(self, provider: str, endpoint: str, params: Dict[str, Any]) -> None:
|
||||
"""
|
||||
验证请求参数
|
||||
|
||||
Args:
|
||||
provider: API提供商
|
||||
endpoint: 端点名称
|
||||
params: 请求参数
|
||||
|
||||
Raises:
|
||||
ValueError: 缺少必需参数时抛出异常
|
||||
"""
|
||||
endpoint_config = self._get_endpoint_config(provider, endpoint)
|
||||
required_params = endpoint_config.get('required_params', [])
|
||||
|
||||
missing_params = []
|
||||
for param in required_params:
|
||||
if param not in params or params[param] is None:
|
||||
missing_params.append(param)
|
||||
|
||||
if missing_params:
|
||||
raise ValueError(f"缺少必需参数: {', '.join(missing_params)}")
|
||||
|
||||
def _prepare_params(self, provider: str, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
准备请求参数,根据不同的API类型添加必要的参数
|
||||
|
||||
Args:
|
||||
provider: API提供商
|
||||
endpoint: 端点名称
|
||||
params: 原始参数
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: 处理后的参数
|
||||
"""
|
||||
provider_config = self._get_provider_config(provider)
|
||||
prepared_params = params.copy()
|
||||
|
||||
# 根据不同的API提供商添加特定参数
|
||||
if provider == 'chinaz':
|
||||
# 站长之家API需要签名
|
||||
if 'sign' not in prepared_params:
|
||||
prepared_params['sign'] = self._generate_chinaz_sign()
|
||||
|
||||
elif provider == 'justoneapi':
|
||||
# JustOneAPI需要token参数
|
||||
if 'token' not in prepared_params or not prepared_params['token']:
|
||||
api_key = provider_config.get('api_key')
|
||||
if api_key:
|
||||
prepared_params['token'] = api_key
|
||||
|
||||
return prepared_params
|
||||
|
||||
def make_request(self,
|
||||
provider: str,
|
||||
endpoint: str,
|
||||
params: Dict[str, Any] = None,
|
||||
timeout: int = 60,
|
||||
retries: int = 3) -> Dict[str, Any]:
|
||||
"""
|
||||
发送API请求
|
||||
|
||||
Args:
|
||||
provider: API提供商名称
|
||||
endpoint: 端点名称
|
||||
params: 请求参数
|
||||
timeout: 超时时间(秒)
|
||||
retries: 重试次数
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: API响应数据
|
||||
"""
|
||||
params = params or {}
|
||||
|
||||
# 验证参数
|
||||
self._validate_params(provider, endpoint, params)
|
||||
|
||||
# 准备参数
|
||||
prepared_params = self._prepare_params(provider, endpoint, params)
|
||||
|
||||
# 获取端点配置
|
||||
endpoint_config = self._get_endpoint_config(provider, endpoint)
|
||||
method = endpoint_config['method'].upper()
|
||||
|
||||
# 构建URL
|
||||
url = self._build_url(provider, endpoint, prepared_params)
|
||||
|
||||
logger.info(f"发送{method}请求到: {url}")
|
||||
|
||||
# 发送请求
|
||||
for attempt in range(retries + 1):
|
||||
try:
|
||||
if method == 'GET':
|
||||
response = self.session.get(url, timeout=timeout)
|
||||
elif method == 'POST':
|
||||
response = self.session.post(url, json=prepared_params, timeout=timeout)
|
||||
else:
|
||||
raise ValueError(f"不支持的HTTP方法: {method}")
|
||||
|
||||
# 检查响应状态
|
||||
response.raise_for_status()
|
||||
|
||||
# 解析响应
|
||||
try:
|
||||
result = response.json()
|
||||
except json.JSONDecodeError:
|
||||
result = {'raw_response': response.text}
|
||||
|
||||
logger.info(f"API请求成功: {provider}.{endpoint}")
|
||||
return result
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.warning(f"API请求失败 (尝试 {attempt + 1}/{retries + 1}): {e}")
|
||||
if attempt == retries:
|
||||
logger.error(f"API请求最终失败: {provider}.{endpoint}")
|
||||
return {
|
||||
'error': True,
|
||||
'message': f"API请求失败: {str(e)}",
|
||||
'provider': provider,
|
||||
'endpoint': endpoint
|
||||
}
|
||||
time.sleep(2 ** attempt) # 指数退避
|
||||
|
||||
# 站长之家API的便捷方法
|
||||
def query_copyright_software(self, company_name: str, chinaz_ver: str = "1") -> Dict[str, Any]:
|
||||
"""查询企业软件著作权"""
|
||||
params = {
|
||||
'entName': company_name,
|
||||
'pageNo': '1',
|
||||
'range': '100',
|
||||
'ChinazVer': chinaz_ver
|
||||
}
|
||||
return self.make_request('chinaz', 'copyright_software', params)
|
||||
|
||||
def query_patent_info(self, company_name: str, chinaz_ver: str = "1") -> Dict[str, Any]:
|
||||
"""查询企业专利信息"""
|
||||
params = {
|
||||
'searchKey': company_name,
|
||||
'pageNo': '1',
|
||||
'range': '100',
|
||||
'searchType': '0',
|
||||
'ChinazVer': chinaz_ver
|
||||
}
|
||||
return self.make_request('chinaz', 'patent', params)
|
||||
|
||||
def query_judicial_data(self, company_name: str, chinaz_ver: str = "1") -> Dict[str, Any]:
|
||||
"""查询司法综合数据"""
|
||||
params = {
|
||||
'q': company_name,
|
||||
'pageNo': '1',
|
||||
'ChinazVer': chinaz_ver
|
||||
}
|
||||
return self.make_request('chinaz', 'judgement', params)
|
||||
|
||||
# JustOneAPI的便捷方法
|
||||
def get_xiaohongshu_note_detail(self, note_id: str) -> Dict[str, Any]:
|
||||
"""
|
||||
获取小红书笔记详情
|
||||
|
||||
Args:
|
||||
note_id: 笔记ID
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: 笔记详情数据
|
||||
"""
|
||||
params = {'noteId': note_id}
|
||||
|
||||
return self.make_request('justoneapi', 'xiaohongshu_note_detail', params)
|
||||
|
||||
# 通用方法
|
||||
def list_providers(self) -> list:
|
||||
"""列出所有可用的API提供商"""
|
||||
return self.config.list_providers()
|
||||
|
||||
def list_endpoints(self, provider: str) -> list:
|
||||
"""列出指定提供商的所有端点"""
|
||||
return self.config.list_endpoints(provider)
|
||||
|
||||
def get_endpoint_info(self, provider: str, endpoint: str) -> Dict[str, Any]:
|
||||
"""获取端点详细信息"""
|
||||
return self._get_endpoint_config(provider, endpoint)
|
||||
|
||||
def set_api_key(self, provider: str, api_key: str) -> None:
|
||||
"""设置API密钥"""
|
||||
self.config.set_api_key(provider, api_key)
|
||||
|
||||
def add_endpoint(self,
|
||||
provider: str,
|
||||
endpoint_name: str,
|
||||
path: str,
|
||||
method: str = 'GET',
|
||||
description: str = '',
|
||||
required_params: list = None,
|
||||
optional_params: list = None) -> None:
|
||||
"""添加新的API端点"""
|
||||
self.config.add_endpoint(
|
||||
provider=provider,
|
||||
endpoint_name=endpoint_name,
|
||||
path=path,
|
||||
method=method,
|
||||
description=description,
|
||||
required_params=required_params,
|
||||
optional_params=optional_params
|
||||
)
|
||||
|
||||
|
||||
# 创建全局实例
|
||||
universal_api = UniversalAPIManager()
|
||||
Loading…
x
Reference in New Issue
Block a user