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