From 54109828b6588b55fbe551e0d58d7f7bb1b43d4f Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 8 Jul 2025 18:55:21 +0800 Subject: [PATCH] bugfix --- json/uapi.json | 13 +++ json/uapiset.json | 9 +- json/upapp.json | 14 ++- json/upappapis.json | 2 +- json/upappkey.json | 3 +- models/uapi.xlsx | Bin 17324 -> 17325 bytes models/upapp.xlsx | Bin 16787 -> 16788 bytes setup.py | 52 ---------- uapi/__init__.py | 1 - uapi/appapi.py | 244 +++++++++++++++++++++++++++++--------------- uapi/init.py | 5 +- uapi/version.py | 1 - 12 files changed, 201 insertions(+), 143 deletions(-) create mode 100644 json/uapi.json delete mode 100755 setup.py delete mode 100644 uapi/version.py diff --git a/json/uapi.json b/json/uapi.json new file mode 100644 index 0000000..9641754 --- /dev/null +++ b/json/uapi.json @@ -0,0 +1,13 @@ +{ + "tblname":"uapi", + "params":{ + "title":"API", + "description":"API定义", + "sortby":"name", + "browserfields":{ + "exclouded":["id"], + "alters":{} + }, + "editexclouded":["id", "usid"] + } +} diff --git a/json/uapiset.json b/json/uapiset.json index 37f80de..00ded72 100644 --- a/json/uapiset.json +++ b/json/uapiset.json @@ -8,6 +8,13 @@ "exclouded":["id"], "alters":{} }, - "editexclouded":["id"] + "editexclouded":["id"], + "subtables":[ + { + "field":"uapiid", + "subtable": "uapi", + "title": "API" + } + ] } } diff --git a/json/upapp.json b/json/upapp.json index 6df732c..839383f 100644 --- a/json/upapp.json +++ b/json/upapp.json @@ -8,6 +8,18 @@ "exclouded":["id"], "alters":{} }, - "editexclouded":["id"] + "editexclouded":["id"], + "subtables":[ + { + "field":"upappid", + "subtable": "upappapis", + "title": "API集" + }, + { + "field":"upappid", + "subtable": "upappkey", + "title": "APIKEY" + } + ] } } diff --git a/json/upappapis.json b/json/upappapis.json index 456919f..7e21308 100644 --- a/json/upappapis.json +++ b/json/upappapis.json @@ -8,6 +8,6 @@ "exclouded":["id"], "alters":{} }, - "editexclouded":["id"] + "editexclouded":["id", "upappid"] } } diff --git a/json/upappkey.json b/json/upappkey.json index 1397974..3990028 100644 --- a/json/upappkey.json +++ b/json/upappkey.json @@ -2,6 +2,7 @@ "tblname":"upappkey", "params":{ "title":"上位系统密码", + "logined_userorgid":"ownerid", "description":"上位系统密码", "sortby":"name", "confidential_fields":["akikey", "userpwd" ], @@ -9,6 +10,6 @@ "exclouded":["id"], "alters":{} }, - "editexclouded":["id"] + "editexclouded":["id", "upappid", "ownerid"] } } diff --git a/models/uapi.xlsx b/models/uapi.xlsx index 16f4296e0e5380af71407f777f745ac491e71563..8ec69c03f28722e2fc2b5012846ba7ed06060ae0 100644 GIT binary patch delta 2259 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 WogkXv9vf?D6&Pq^4trz$xAYgGWDsxw delta 2303 zcmZ8jcQD+G6Tj1*8l2OK-XrdG&Iu=a^bkEl^b;gRcaM`hJ>jeTq9tnL^qej@Nd)<+ z(GsUTB+82(qVqiSo5{>?|JeD=>}Pg%_OrXQRd{eE9$f1}N4=ah#ytbL(@A4k5{(G; zhV=$ysNZR5C0{_SHTJpRP9fnuYEqOXXRXlJ!WGuRH`uZt5Ea}$(9%$53Agyr+aB;t zH|b_crET}h*#jSZuVoHYYQE?te9GcUHU4g=qhDO4Gwn7StX1fm;q9cyRUuleX2Drh zLS1?7Nq+*a-0_~Zk&$Jl1p)IY71=`R2OiZnRqKA*k?1oiRehss5uPq@GRno|BCWg|TKx2yU8V~AV(s6p zshq+Z=yi>3Sj^PZ=CU_}IkSlA|9WH3VvAD1B{?MV(> zzFp=w_`7}j-Fc_8Ke7=R$F%f$$C3=0=|BOsrX$S3Q&Bxln!X78;~!RsBvZYVo+W$x z03H!+p9jNjEu}s048Rw(t3NN!s%XVtL98kPYtTBd|f1U*1tCl@ZP6cTlg_q`^ZQ(Q({uX4@2 zc3T}7o6>wE%$~~?HZMqJ-R5x>=h0ezN5GCi(ONC2hCj%2)ci*Ywoc?HM9tW#xQ@5u ze#Wa|ezMof-CKV3Aw2Ekd8NTt>l$G7DT(k`W~3}I;yvrtaDCpja}lmz*{1b#2^%l; zJTtQMZGWCB%VVe7Ou`}WfR_6H@h#Qy?Uqzvfr{9jvY3pH*kZG!rvgj*ZXwk)TU2x@ z#@_2u2)F(O9>oyKQ54o++D&P{xxrz{p5ZNKjoG_<0hR|FaMu}%dma^ck6=XKoASli z>xA1?JMih5ldMBXq4zee>7zDsQw*$C_oh(hZVfU6BI_|k{%GqgS$PaiX%>`7GE4Ri zORVeo>^O-NOHPtm?Ks23M&j*Md#hvoUmrwe6>Vp-cXr`6<4iEs zwHqN{zdC10oe~Sg4`I1WU7~i?vBAopu;yP52R6G0pfg=#;Ygu;zm$MF=DgiG& zXRN}zDwTBu`%z)n@_PCq{tSqSr&+~E^|~?J{Q^%^di#4sx2JsE>XMu=w^;sOBfXm_ zQD-pwyV=(ax-e0v2@E^Vv%kxxn@OYa^JFRJgMVt}E>-SZNS468z?Nxr@u%1`!z16g ztR5k5F^wyplMENyJwfnQ2wx$@b}SQnf>2*wXO)JTsS%hZU~VF(#_~hEkwS7v#(<)vGapnFn)DdiCY7v-QhJ4{43-a9ZF^=!*I&Q3PW= zKR^5T3j(9kRVfV%vD>c2@4X=-r_-Em5mXHX%CqO)f}edv7YvdUB_O;OYw!r8$4HpK zPYvUpT^yukyDLY?Qtk#V(K-Gx%g%PESeTqP!r=3{!R#KS9xK`=jZAeIW9P_s4o})} z*R6C&>jZ&7=jWF$?hg4uu@9>bP`2y!ZmiQI~I}D%cv^qV;S>F zMb^;~z>fI*6e($hiA$o3rl17%{>J|)sZ?3%QM4jr8W!z>Ai;$g z9I?n?53LN?^X zsnndogZlAOhJycEKBR5rxRr?EMK;yIN!prJnzr&|&655^e2;6&&VPo(3^;^R7{arM zby2g^Bi@~_wysGse()ZEZNWBT_{65k?M!2f#$%5SLh z{l1$Z5Z6WPf14vC0B2(dAX;)1rOcPm_5$*=T|ge78^r>|ak4P{rbh#VT3Qr1{!3;J zKQ$n&ElrUt1k?y|0BCJ#umX^+txgdu4P;4+0S6bcIGIbT8j79o_vZh95kYd7Bn(Op ud<4{>w7|;17D|NoawNbYkT(Sg#QM923nU6$*UIop$E2`7I&H4q>vDy`aN(IRbAwDse$a=-~z4W_oq zhpPVfU6Vj)vWKokiH*6}hjZ^eTwh#ma)DM%X)cQxyJrqYtVm?ai)D=OZYRAVM%vIK zr9u`g##^TG)#cYO7i+1W=2AW(04Q{fGh@n#5S?T!r}|8mtN_bGs+<~FswL5-Vl;o% z8Dl0F#B-dG*TD4XpNZtq0f|i?yFE18cu=|~K z5iQGKG`E!!7zwJ)x0D-}#&`frxn_q40Y<7SZz?Xp>bj0M#N@J-^Gv}4YJV*ZQw23_ zBntyl+f)CntZM90CPBpLH+!zQV({&NgdiLkX%f-7o>7ybN{JYgI}P!XZTB|VNLra}Ur-AjV;`z_V){upjm34Mil+w}FV6nz+4*Q_Y_B$8+q&*KTkAvV z?GkMsc#+C=j6DZB6h_--9SlNPu50T9e@{&Y9DslO>^tMj3@CekFocIRF?_{t=^T<_ zWAH4|7{4Jn-VvO@)w9DJf~3Q+?wP=}o>5WjTvs`CuPtpN*004mw z000;OlTbh!f1HzDZ<{a_hVLisKUls`z?9Mkg;Y_es=b+}bsyJ`IRq;A~`z7e4hR+nnhfUr1ShQ!mu>5u#;f} zPpIU5e<88!k(HcaSMP*nBP=YJ&9|~F=%2X1CfKvk#FLnX=FRn&F6O1g9S&I$3spgv zEPtHQXff~V=ZA#7dow1Uubx4H@PHnSlHbPYXTihPu^TMv@%?isNY&4VB3>D@3AiT| z#^~!hOz`Ex%N^W9{)^3y22Q>|x00960 zv#Bs`2n8B{uo_ge8#yKce^E=rFcgK~1^+|Idz)m#PD9s$%AOnwZYaKmJ1hgGc$?mhSFV0wSL4i*qNqZ*j6m3GV3}Y`g&~TqchmK-pT*E^gf882eF1CCPctl8! z8wgzTz;Opm?TLsENGVQ8`|0W)AO(gR8qmRGno<1Y4d5F8=R&WXIU5!BHg-D1J!eZX zh$r{XtCO*9+pHb;F=Bp--xp7>ebrRy?p6X&SxCWz10IYkw{2VCv$?xn&3#zJGgk`a z{k~i%;fyy`NS>=oP69$bNc8zZ-`F~C74F&G^hXT&3*>~mj!j`ACmF&7k*I6)AzvOCxT z1?VT>Iop$uJyHT%43khm6_fZqF9KK(lTbhvlRiE#0?-nZP(T%vgg!3;HIuYHKmt7- zlTbhvlW-jclMp{D0cMjsKS2RclYKur0(~iyn<*ue-aje=e=3tuKoyf8KouL9vC}&- z1pokn4gdfc0000000000000000C|&7Kt%!Ila)X~0UVRoKqDI(f3O-<0RRAL0ssIJ n00000000000000001A^7K|TVNJCm?GDU*Fc5C*wC00000N$oT| delta 1775 zcmV>2|i?vkGb19z@02DgLnK5NVh)yz=Q+*~&R)A$8RZa~o)spB^F`9qs zj4_i7;=680a>@(5Lx|LSFyvyv6E=}am9xU^Kok?y0DYbDQa5OM@*cRHs^_Y75}B6( zG3SDtZ4HW1oPb3{zr9_O$y@vS6Hva)blL`wd zfB6o1{!Leqb*OE+|0t(6t-YrrQIYrb;tqnrV9*;o*Eho(=X?@eIYW04Is^AM@UG4$ zoMM_#0I9b?~x4u#RSS@#DaEZ4R5f03sq0}k%F-#+`s_%Z{^e$XGnLz)=AVs~^7 z$*?i_mS~LM5S;7?-ooYB;SE93VOaM}U|P?psCBNZ9J<#Qy0dMlb<#oDk$s7prk;(l z>%QPjq|hB(Z|GmGw}0%tqJpP&Q|;{Nb$0ZQcfgSWC&K|AdPfT%{KFZ}myUPPCGqYb zduL3P9bfzXHerUfcANAhR3tNn>{RC?2>O1FMw-KF^cRz0Ar!M{3?Cv1jZH0FEd>Ao zfRm6eE`N+^N}DL8np#!u%`~n1xOU7TSg|p)osVwXfA28?5-HLa6@h&)yw74}_V!gkj54NqDewW1tQP zhyyJG`uCM;d`~m-5}Xlky=g|$ng$U|rB!%sp_CXodtTMniKWK6_k1EG**iQ_ysr8* z?fO|JqolLmmSK!!cJO>&{*+CbkOS$w{);et!W?W>+`uC$eV-+MJ+RUv?CPDcY=Fhj z<$q=yRpj(f(j6n5c^r~a!sBpq{H2R|p>T&|Rm4G=(@%W%G^K1YZ~Nzmf}KB!Nf65y z&>#a~4o=B$Yt4%kaqIXEHuZ4-IX0y3R$~({tzAdlGYS*T>sw6BD`ZexxCf1|KX8Ql zU#*oGqY*YZIgNW)k8R_Babzhx+*|!q6@Q_^wCJUPQfzcME>4HFuXgtYYE=b%a}twC ztC5H!F)IF`*q36TQ{0_h2h7GinF+ zx#=W0_mas)_BeJ(TUZP_=`Dum6|we}1vyjh@~a}CAV@*UL7M&6;kSZY%<=YL1D#SPDO%oW*ez;~%dBQ`xRVVo54jK)(+ z$VZpsYQGCQJk+N&{}K~VoP}gwkO?JsG)+guGa&DCUw@AL8<;dem^<^f0MaCPy&G}lTknwlORA98;wmZTrC9v0Dukv z02lxO00000000000001clTbiK0p63AKtKT+lh;5a1zV37-BpwSKotQ9lNCWe0+c(G Ru{$Y~enAihxI6#=005wOF~tA? diff --git a/setup.py b/setup.py deleted file mode 100755 index 939784a..0000000 --- a/setup.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- - -from uapi.version import __version__ -try: - from setuptools import setup -except ImportError: - from distutils.core import setup -required = [] -with open('requirements.txt', 'r') as f: - ls = f.read() - required = ls.split('\n') - -with open('uapi/version.py', 'r') as f: - x = f.read() - y = x[x.index("'")+1:] - z = y[:y.index("'")] - version = z -with open("README.md", "r") as fh: - long_description = fh.read() - -name = "uapi" -description = "uapi" -author = "yumoqing" -email = "yumoqing@gmail.com" - -package_data = {} - -setup( - name="uapi", - version=version, - - # uncomment the following lines if you fill them out in release.py - description=description, - author=author, - author_email=email, - platforms='any', - install_requires=required , - packages=[ - "uapi" - ], - package_data=package_data, - keywords = [ - ], - url="https://github.com/yumoqing/uapi", - long_description=long_description, - long_description_content_type="text/markdown", - classifiers = [ - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'License :: OSI Approved :: MIT License', - ], -) diff --git a/uapi/__init__.py b/uapi/__init__.py index 58f3ace..e69de29 100644 --- a/uapi/__init__.py +++ b/uapi/__init__.py @@ -1 +0,0 @@ -from .version import __version__ diff --git a/uapi/appapi.py b/uapi/appapi.py index a342375..5d97f12 100644 --- a/uapi/appapi.py +++ b/uapi/appapi.py @@ -1,17 +1,174 @@ +import json + +from traceback import format_exc from functools import partial from sqlor.dbpools import DBPools -from appPublic.httpclient import JsonHttpAPI -from appPublic.log import debug, exception, +from appPublic.streamhttpclient import StreamHttpClient, liner +from appPublic.log import debug, exception, error from ahserver.globalEnv import password_decode -from aiohttp import web -class AppAPI(JsonHttpAPI): +def get_dbname(): + f = get_serverenv('get_module_dbname') + dbname = f('uapi') + return dbname + +class UAPI(StreamHttpClient): def __init__(self, appid, env={}): self.appid = appid - super().__init__(env=env) + super().__init__() + self.te = MyTemplateEngine([], env=env) + self.env = env self.auth_api = None self.auth_ret = None + async def tmplrender(self, tmplstr, params={}): + if tmplstr is None: + return None + ns = self.env.copy() + ns.update(params) + te = MyTemplateEngine([], env=self.env) + return te.renders(headerstmpl, ns) + + async def make_call(self, request, upapiid, callerid, + params={}, + stream=False, + env={}): + self.env.update(env) + db = DBPools() + dbname = get_dbname() + uapi = None + auth_uapi = None + async with db.sqlorContext(dbname) as sor: + upapi = await self.get_upappapis(upapiid) + kinfo = await self.get_orgapikey(sor, upapi.upappid, callerid) + self.env.update(kinfo) + auth_uapi = None + if kinfo.auth_apiid: + auth_upapi = await self.get_upappapis(kinfo.auth_apiid) + auth_uapi = await self.get_uapi(sor, kinfo.auth_upapi.uapiid) + uapi = await self.get_uapi(sor, upapi.uapiid) + if auth_uapi: + await self.do_auth(auth_uapi) + if stream: + return await self.do_stream_call(self, request, uapi, params=params) + else: + return await self.do_call(self, request, uapi, params=params) + + async def do_auth(self, auth_uapi): + b = await self.do_call(auth_uapi) + d = json.loads(b.encode('utf-8')) + self.env.update(d) + return + + async def do_call(self, request, api, params={}): + url = self.env.get('baseurl') + api.path + method = auth_uapi.httpmethod + header = self.rendertmpl(api.headers, params=params) + header = json.loads(headers) + body = self.rendertmpl(api.body, params=params) + _params = self.rendertmpl(api.params, params=params) + if _params: + _params = json.loads(_params) + b = await self.request(method, url, + headers=headers, + body=body, + params=_params) + + d = json.loads(b.encode('utf-8')) + if api.response: + return self.rendertmpl(api.response, params=d) + return d + + async def do_stream_call(self, request, api, params={}): + self.resp = web.StreamResponse() + await self.resp.prepare(request) + url = self.env.get('baseurl') + api.path + method = auth_uapi.httpmethod + header = self.rendertmpl(api.headers, params=params) + header = json.loads(headers) + body = self.rendertmpl(api.body, params=params) + if body: + bdy = json.loads(body) + bdy['stream'] = True + body = bdy.dumps(bdy, ensure_ascii=False) + _params = self.rendertmpl(api.params, params=params) + if _params: + _params = json.loads(_params) + hc = StreamHttpClient() + gen = hc(method, url, + headers=headers, + body=body, + params=_params) + self.chunk_match = self.api.chunk_match or '' + async for line in liner(gen): + self.streamline_handle(line) + return self.resp + + async def streamline_handle(self, line, resptmpl): + cnt = len(self.chunk_match) + line = line[cnt:] + try: + dic = json.loads(line) + if resptmpl: + jstr = self.rendertmpl(resptmpl, dic) + '\n' + else: + jstr = json.dumps(self.resp_json, ensure_ascii=False) + '\n' + bin = jstr.encode('utf-8') + await self.resp.write(bin) + await self.resp.drain() + except Exception as e: + exception(f'{line=}\n{e=},{format_exc()}') + return + + async def get_upappapis(self, sor, upapiid): + recs = await sor.R('upappapis', {'id': upapiid}) + if len(recs) < 1: + e = Exception(f'{upapiid} not found in table(upappapis)') + exception(f'{e}\n{format_exc()}') + raise e + return recs[0] + + async def get_uapi(self, sor, uapiid): + recs = await sor.R('uapi', {'id': uapiid}) + if len(recs) < 1: + e = Exception(f'{uapiid} not found in table(uapi)') + exception(f'{e}\n{format_exc()}') + raise e + return recs[0] + + async def get_orgapikey(self, sor, upappid, callerid): + """ + argumemts: + upappid: upappid which will make call to + orgid: owner organization or user which as the caller of the call + return: + None: this orgid has not gotton apikey from upapp + dict if apikey and upapp infos + """ + sql = """select +a.myappid, +a.apisetid, +a.auth_apiid, +a.baseurl, +b.*, +from upapp a, upappkey b +where a.id = b.upappid + and a.id = ${appid}$ + and b.ownerid = ${orgid}$""" + recs = await sor.sqlExe(sql, {'appid':upappid, 'orgid': callerid}) + if len(recs) < 1: + e = Exception(f'{appid=}, {callerid=} has not apikey') + exception(f'{e}, {format_exc()}') + raise e + r = recs[0] + return { + 'apikey':r.apikey, + 'secretkey':r.secretkey, + 'apisetid': r.apisetid, + 'auth_apiid': r.auth.apiid, + 'myappid': r.myappid + } + async def get_authapi(self, sor): sql = "select * from jsonhttpapi where name = 'auth' and appid=${appid}$" recs = await sor.sqlExe(sql, {'appid': self.appid}) @@ -59,80 +216,3 @@ where return recs[0] return None - async def request(self, apiname, ns): - orgs = ns.get('orgs') - api = await self.get_apiinfo(orgs, apiname) - if api is None: - e = Exception(f'{self.appid} app has not {apiname} api') - exception(f'{e=}, {format_exc()}') - raise e - 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: - e = Exception(f'{self.appid} app auth error') - exception(f'{e=}, {format_exc()}') - raise e - 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() - diff --git a/uapi/init.py b/uapi/init.py index 0c585c4..cb41627 100644 --- a/uapi/init.py +++ b/uapi/init.py @@ -1,8 +1,7 @@ from ahserver.serverenv import ServerEnv -from .appapi import AppAPI, AiohttpAppAPI +from .appapi import UAPI def load_uapi(): g = ServerEnv() - g.AiohttpAppAPI = AiohttpAppAPI - g.AppAPI = AppAPI + g.UAPI = UAPI diff --git a/uapi/version.py b/uapi/version.py deleted file mode 100644 index b8023d8..0000000 --- a/uapi/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = '0.0.1'