bugfix
This commit is contained in:
parent
e04b3a53e8
commit
8064e7f6bb
3
json/build.sh
Executable file
3
json/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
xls2ui -m ../models -o ../wwwroot appbase *.json
|
40
json/jsonhttpapi.json
Normal file
40
json/jsonhttpapi.json
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"tblname":"jsonhttpapi",
|
||||
"params":{
|
||||
"title":"应用api",
|
||||
"description":"应用api管理,配置与外部系统的api应用接口,需要api返回json格式数据",
|
||||
"sortby":"name",
|
||||
"logined_userorgid":"ownerid",
|
||||
"toolbar":{
|
||||
"tools":[
|
||||
{
|
||||
"name":"test",
|
||||
"icon":"test.png",
|
||||
"selected_row": true,
|
||||
"label":"接口测试"
|
||||
}
|
||||
]
|
||||
},
|
||||
"browserfields":{
|
||||
"exclouded":["id", "ownerid"],
|
||||
"alters":{}
|
||||
},
|
||||
"binds":[
|
||||
{
|
||||
"wid":"self",
|
||||
"event":"row_selected",
|
||||
"actiontype":"script",
|
||||
"target":"self",
|
||||
"script":"console.log('test', params);"
|
||||
},
|
||||
{
|
||||
"wid":"self",
|
||||
"event":"test",
|
||||
"actiontype":"script",
|
||||
"target":"self",
|
||||
"script":"console.log('swith event', params);"
|
||||
}
|
||||
],
|
||||
"editexclouded":["id", "ownerid"]
|
||||
}
|
||||
}
|
13
json/upapp.json
Normal file
13
json/upapp.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"tblname":"upapp",
|
||||
"params":{
|
||||
"title":"上位系统",
|
||||
"description":"上位系统",
|
||||
"sortby":"name",
|
||||
"browserfields":{
|
||||
"exclouded":["id"],
|
||||
"alters":{}
|
||||
},
|
||||
"editexclouded":["id"]
|
||||
}
|
||||
}
|
20
json/upapp1.json
Normal file
20
json/upapp1.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"tblname":"upapp",
|
||||
"alias":"upapp1",
|
||||
"params":{
|
||||
"title":"上位系统",
|
||||
"sortby":"name",
|
||||
"noedit":true,
|
||||
"browserfields":{
|
||||
"exclouded":["id"],
|
||||
"alters":{}
|
||||
},
|
||||
"subtables":[
|
||||
{
|
||||
"field":"upappid",
|
||||
"subtable":"upappkey",
|
||||
"title":"应用密码"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
14
json/upappkey.json
Normal file
14
json/upappkey.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"tblname":"upappkey",
|
||||
"params":{
|
||||
"title":"上位系统密码",
|
||||
"description":"上位系统密码",
|
||||
"sortby":"name",
|
||||
"confidential_fields":["akikey", "userpwd" ],
|
||||
"browserfields":{
|
||||
"exclouded":["id"],
|
||||
"alters":{}
|
||||
},
|
||||
"editexclouded":["id"]
|
||||
}
|
||||
}
|
1
uapi/__init__.py
Normal file
1
uapi/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .version import __version__
|
131
uapi/appapi.py
Normal file
131
uapi/appapi.py
Normal file
@ -0,0 +1,131 @@
|
||||
from functools import partial
|
||||
from sqlor.dbpools import DBPools
|
||||
from appPublic.httpclient import JsonHttpAPI
|
||||
from ahserver.globalEnv import password_decode
|
||||
from aiohttp import web
|
||||
|
||||
class AppAPI(JsonHttpAPI):
|
||||
def __init__(self, appid, env={}):
|
||||
self.appid = appid
|
||||
super().__init__(env=env)
|
||||
self.auth_api = None
|
||||
self.auth_ret = None
|
||||
|
||||
async def get_authapi(self, sor):
|
||||
sql = "select * from jsonhttpapi where name = 'auth' and appid=${appid}$"
|
||||
recs = await sor.sqlExe(sql, {'appid': self.appid})
|
||||
if len(recs):
|
||||
return recs[0]
|
||||
return None
|
||||
|
||||
async def get_apiinfo(self, orgids, apiname):
|
||||
db = DBPools()
|
||||
dbname = get_serverenv('get_module_dbname')('uapi')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
sql = """select c.baseurl,
|
||||
c.name as appname,
|
||||
b.*,
|
||||
a.apikey,
|
||||
a.secretkey
|
||||
from upappkey a, jsonhttpapi b, upapp c
|
||||
where
|
||||
a.upappid=b.appid
|
||||
and a.upappid = c.id
|
||||
and b.appid = ${appid}$
|
||||
and b.name = ${apiname}$
|
||||
and a.ownerid = ${orgid}$
|
||||
"""
|
||||
for orgid in orgids:
|
||||
ns = {
|
||||
"orgid": orgid,
|
||||
"apiname": appname,
|
||||
"appid": self.appid
|
||||
}
|
||||
recs = await sor.sqlExe(sql, ns)
|
||||
if len(recs) > 0:
|
||||
rec = recs[0]
|
||||
rec.apikey = password_decode(rec.apikey)
|
||||
if rec.secretkey:
|
||||
rec.secretkey = password_decode(rec.secretkey)
|
||||
if rec.need_auth and self.auth_api is None:
|
||||
self.auth_api = await self.get_authapi(sor)
|
||||
if rec.need_auth and self.auth_api is None:
|
||||
raise Exception(f'{rec.appname} app has not auth api but need')
|
||||
rec.auth_api = self.auth_api
|
||||
rec.apikey_orgid = orgid
|
||||
return recs[0]
|
||||
return None
|
||||
|
||||
def request(self, apiname, ns):
|
||||
orgs = ns.get('orgs')
|
||||
api = await self.get_apiinfo(orgs, apiname)
|
||||
if api is None:
|
||||
raise Exception(f'{self.appid} app has not {apiname} api')
|
||||
ns1 = self.env.copy()
|
||||
ns1['apikey'] = api.apikey
|
||||
ns1['secretkey'] = api.secretkey
|
||||
ns1.update(ns)
|
||||
if api.need_auth:
|
||||
if self.auth_ret is None:
|
||||
auth_url = api.baseurl + self.auth_api.path
|
||||
self.auth_ret = await self.call(auth_url,
|
||||
method=self.auth_api.httpmethod,
|
||||
ns=ns1,
|
||||
headerstmpl=self.auth_api.headers,
|
||||
paramstmpl=self.auth_api.params,
|
||||
datatmpl=self.auth_api.data,
|
||||
resptmpl=self.auth_api.response)
|
||||
if self.auth_ret is None:
|
||||
raise Exception(f'{self.appid} app auth error')
|
||||
ns1.update(self.auth_ret)
|
||||
stream_func = None
|
||||
if api.stream:
|
||||
await self.stream_begin()
|
||||
stream_func = partial(self.stream_func, api, ns1)
|
||||
url = api.baseurl + api.path
|
||||
ret = await self.call(url, method=api.httpmethod, ns=ns1,
|
||||
stream_func = stream_func,
|
||||
headerstmpl=api.headers,
|
||||
paramstmpl=api.params,
|
||||
datatmpl=api.data,
|
||||
resptmpl=api.response)
|
||||
if api.stream:
|
||||
return await self.stream_end()
|
||||
return ret
|
||||
|
||||
async def stream_begin(self):
|
||||
pass
|
||||
|
||||
async def stream_end(self):
|
||||
return None
|
||||
|
||||
async def stream_func(self, api, ns, chunk):
|
||||
if api.chunk_match:
|
||||
chunk = chunk[len(api.chunk_match):]
|
||||
d = chunk
|
||||
if api.streamresponse:
|
||||
d = json.loads(chunk)
|
||||
ns1 = ns.copy()
|
||||
ns1.update(d)
|
||||
d = self.te.renders(api.streamresponse, ns1)
|
||||
return d
|
||||
|
||||
|
||||
class AiohttpAppAPI(AppAPI):
|
||||
async def request(self, request, apiname, ns):
|
||||
self.request = request
|
||||
return await super().request(apiname, ns)
|
||||
|
||||
async def stream_begin(self):
|
||||
self.resp = web.StreamResponse()
|
||||
await self.resp.prepare(request)
|
||||
|
||||
async def stream_end(self):
|
||||
return self.resp
|
||||
|
||||
async def stream_func(self, api, ns, chunk):
|
||||
d = super().stream_func(api, ns, chuck)
|
||||
b = d.encode('utf-8')
|
||||
await self.resp.write(bin)
|
||||
await self.resp.drain()
|
||||
|
8
uapi/init.py
Normal file
8
uapi/init.py
Normal file
@ -0,0 +1,8 @@
|
||||
from ahserver.serverenv import get_serverenv
|
||||
from .appapi import AppAPI, AiohttpAppAPI
|
||||
|
||||
def load_uapi():
|
||||
g = ServerEnv()
|
||||
g.AiohttpAppAPI = AiohttpAppAPI
|
||||
g.AppAPI = AppAPI
|
||||
|
1
uapi/version.py
Normal file
1
uapi/version.py
Normal file
@ -0,0 +1 @@
|
||||
__version__ = '0.0.1'
|
Loading…
Reference in New Issue
Block a user