add restful support

This commit is contained in:
yumoqing 2019-07-29 10:01:11 +08:00
parent 3290fe1f97
commit 260c38d637
6 changed files with 160 additions and 23 deletions

14
ahserver/error.py Normal file
View File

@ -0,0 +1,14 @@
def Error(errno='undefined error',msg='Error'):
return {
"status":"Error",
"data":{
"message":msg,
"errno":errno
}
}
def Success(data):
return {
"status":"OK",
"data":data
}

View File

@ -20,10 +20,6 @@ from appPublic.uniqueID import setNode,getID
from appPublic.unicoding import unicoding,uDict,uObject
from appPublic.Singleton import SingletonDecorator
from sql.crud import _CRUD,CRUD
# from sql.sqlorAPI import DBPools,runSQL,runSQLPaging,runSQLIterator
# from sql.sqlorAPI import getTables,getTableFields,getTablePrimaryKey
# from sql.sqlorAPI import getTableForignKeys,runSQLResultFields
from sqlor.dbpools import DBPools
@ -167,7 +163,6 @@ def initEnv():
g.folderInfo = folderInfo
g.abspath = abspath
g.request2ns = request2ns
g.CRUD = CRUD
g.data2xlsx = data2xlsx
g.xlsxdata = XLSXData
g.openfile = openfile

View File

@ -19,7 +19,7 @@ from aiohttp.web_routedef import AbstractRouteDef
from appPublic.jsonConfig import getConfig
from appPublic.MiniI18N import getI18N
from appPublic.dictObject import DictObject
from appPublic.dictObject import DictObject, multiDict2Dict
from .baseProcessor import getProcessor
from .xlsxdsProcessor import XLSXDataSourceProcessor
@ -27,19 +27,7 @@ from .sqldsProcessor import SQLDataSourceProcessor
from .serverenv import ServerEnv
from .url2file import Url2File
from .filestorage import FileStorage
def multiDict2Dict(md):
ns = {}
for k,v in md.items():
ov = ns.get(k,None)
if ov is None:
ns[k] = v
elif type(ov) == type([]):
ov.append(v)
ns[k] = ov
else:
ns[k] = [ov,v]
return ns
from .restful import DBCrud
def getHeaderLang(request):
al = request.headers.get('Accept-Language')
@ -70,6 +58,10 @@ class ProcessorResource(StaticResource):
append_version=append_version)
gr = self._routes.get('GET')
self._routes.update({'POST':gr})
self._routes.update({'PUT':gr})
self._routes.update({'OPTIONS':gr})
self._routes.update({'DELETE':gr})
self._routes.update({'TRACE':gr})
self.y_processors = []
self.y_prefix = prefix
self.y_directory = directory
@ -90,7 +82,7 @@ class ProcessorResource(StaticResource):
real_path = os.path.abspath(rp)
return real_path
async def getPostData(self,request):
async def getPostData(self,request: Request) -> dict:
reader = await request.multipart()
if reader is None:
md = await request.post()
@ -161,8 +153,6 @@ class ProcessorResource(StaticResource):
return await self.getPostData(request)
ns = multiDict2Dict(request.query)
return ns
print('** ret=',ret,request.query)
return ns
self.y_env.i18n = serveri18n
self.y_env.i18nDict = i18nDICT
@ -172,6 +162,19 @@ class ProcessorResource(StaticResource):
self.y_env.request2ns = getArgs
self.y_env.resource = self
path = request.path
config = getConfig()
if config.website.dbrest and path.startswith(config.website.dbrest):
pp = path.split('/')[2:]
if len(pp)<2:
raise HTTPNotFound
dbname = pp[0]
tablename = pp[1]
id = None
if len(pp) > 2:
id = pp[2]
crud = DBCrud(request,dbname,tablename,id=id)
return await crud.dispatch()
for word, handlername in self.y_processors:
if path.endswith(word):
Klass = getProcessor(handlername)

123
ahserver/restful.py Normal file
View File

@ -0,0 +1,123 @@
import os
import re
from aiohttp.web_urldispatcher import StaticResource, _WebHandler, PathLike
from aiohttp.web_urldispatcher import Optional, _ExpectHandler
from aiohttp.web_urldispatcher import Path
from aiohttp.web_response import Response, StreamResponse
from aiohttp.web_exceptions import (
HTTPException,
HTTPExpectationFailed,
HTTPForbidden,
HTTPMethodNotAllowed,
HTTPNotFound,
)
from aiohttp import web
from aiohttp.web_fileresponse import FileResponse
from aiohttp.web_request import Request
from aiohttp.web_response import Response, StreamResponse
from aiohttp.web_routedef import AbstractRouteDef
from aiohttp.web import json_response
from sqlor.crud import CRUD
from appPublic.dictObject import multiDict2Dict
from appPublic.jsonConfig import getConfig
from .error import Error,Success
DEFAULT_METHODS = ('GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'TRACE')
class RestEndpoint:
def __init__(self):
self.methods = {}
for method_name in DEFAULT_METHODS:
method = getattr(self, method_name.lower(), None)
if method:
self.register_method(method_name, method)
def register_method(self, method_name, method):
self.methods[method_name.upper()] = method
async def dispatch(self):
method = self.methods.get(self.request.method.upper())
if not method:
raise HTTPMethodNotAllowed('', DEFAULT_METHODS)
return await method()
class DBCrud(RestEndpoint):
def __init__(self, request,dbname,tablename, id=None):
print(f'***{dbname}*{tablename}*{id}************')
super().__init__()
self.dbname = dbname
self.tablename = tablename
self.request = request
self.id = id
try:
self.crud = CRUD(dbname,tablename)
except Exception as e:
print('e=',e)
raise HTTPNotFound
async def options(self) -> Response:
try:
d = await self.crud.I()
return json_response(Success(d))
except Exception as e:
print(e)
return json_response(Error(errno='metaerror',msg='get metadata error'))
async def get(self) -> Response:
"""
query data
"""
try:
ns = multiDict2Dict(self.request.query)
if self.id is not None:
ns['__id'] = self.id
d = await self.crud.R(NS=ns)
return json_response(Success(d))
except Exception as e:
print(e)
return json_response(Error(errno='search error',msg='search error'))
async def post(self):
"""
insert data
"""
try:
ns = multiDict2Dict(await self.request.post())
d = await self.crud.C(ns)
return json_response(Success(d))
except Exception as e:
print(e)
return json_response(Error(errno='add error',msg='add error'))
async def put(self):
"""
update data
"""
try:
ns = multiDict2Dict(await self.request.post())
d = await self.crud.U(ns)
return json_response(Success(''))
except Exception as e:
print(e)
return json_response(Error(errno='update error',msg='update error'))
async def delete(self, request: Request, instance_id):
"""
delete data
"""
try:
ns = multiDict2Dict(self.request.query)
d = await self.crud.D(ns)
return json_response(Success(d))
except Exception as e:
print(e)
return json_response(Error(erron='delete error',msg='error'))

View File

@ -43,6 +43,7 @@
"index.dspy",
"index.md"
],
"dbrest":"/dbs",
"visualcoding":{
"default_root":"/samples/vc/test",
"userroot":{

View File

@ -11,4 +11,5 @@ sqlor
jinja2
ujson
openpyxl
#appPublic
appPublic
patterncoding