2 Star 0 Fork 1

Plato/rpc-backend-python3

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
pygen.py 15.48 KB
一键复制 编辑 原始数据 按行查看 历史
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import json
import sys
import os
from string import Template
class FileGenerator:
def __init__(self, file_name, template_folder, pb_json):
file_name = os.path.basename(file_name)
self.file_name_split = file_name.split(".")
self.pb_json = pb_json
self.template_root = os.path.join(template_folder, 'python')
file = open(self.file_name_split[0] + ".py", "w", encoding="utf-8")
file.write('#!/usr/bin/python\n')
file.write('# -*- coding: UTF-8 -*-\n\n')
file.write("# Machine generated code\n\n")
file.write('import types\n')
file.write('import rpc\n')
file.write('import time\n')
file.write('import traceback\n')
file.write('import plato\n\n')
self.gen_enum(file)
self.gen_stub_service(file)
self.gen_prx(file)
file.close()
self.gen_all_table()
self.gen_struct_pb_file()
if 'services' in self.pb_json and self.pb_json['services'] is not None:
for service in self.pb_json['services']:
self.gen_service_api_test(service)
def get_db_field_type(self, idl_type):
if idl_type == 'i32':
return 'IntField'
elif idl_type == 'ui32':
return 'UIntField'
if idl_type == 'i64':
return 'Int64Field'
elif idl_type == 'ui64':
return 'UInt64Field'
elif idl_type == 'float':
return 'FloatField'
elif idl_type == 'double':
return 'DoubleField'
elif idl_type == 'string':
return 'StringField'
def get_table_field_type(self, idl_type):
if idl_type == 'i32':
return 'int'
elif idl_type == 'ui32':
return 'uint'
if idl_type == 'i64':
return 'int64'
elif idl_type == 'ui64':
return 'uint64'
elif idl_type == 'float':
return 'float'
elif idl_type == 'double':
return 'double'
elif idl_type == 'string':
return 'string'
def get_table_field_default(self, field):
idl_type = field["IdlType"]
if 'default_value' in field:
if idl_type == 'string':
return '"'+field['default_value']+'"'
else:
return field['default_value']
return None
def gen_all_table(self):
if ("tables" in self.pb_json) and (self.pb_json["tables"] is not None):
for table in self.pb_json["tables"]:
self.gen_table(table)
def gen_table(self, table):
file = open('db_'+table['name']+'.py', "w")
file.write('import sys\n')
file.write('sys.path.append("..")\n\n')
file.write('import plato\n\n\n')
file.write('class '+table['name']+'(plato.DbObject):\n')
file.write(' def __init__(self, readonly=False, new=False):\n')
file.write(' super().__init__(name="'+table['name']+'", readonly=readonly, new=new)\n')
for field in table['fields']:
default_value = self.get_table_field_default(field)
if field['is_obj_id']:
is_obj_id = "True"
obj_id_field = field
else:
is_obj_id = "False"
if default_value is None:
file.write(' self._'+field['name']+' = plato.'+self.get_db_field_type(field['IdlType'])+'(field_type="'+self.get_table_field_type(field['IdlType'])+'", name="'+field['name']+'", parent=self, readonly=readonly, is_obj_id='+is_obj_id+')\n')
else:
file.write(' self._'+field['name']+' = plato.'+self.get_db_field_type(field['IdlType'])+'(field_type="'+self.get_table_field_type(field['IdlType'])+'", name="'+field['name']+'", parent=self, default='+default_value+', readonly=readonly, is_obj_id='+is_obj_id+')\n')
file.write('\n')
n = 0
for field in table['fields']:
is_obj_id = False
if field['is_obj_id']:
is_obj_id = True
obj_id_field = field
else:
is_obj_id = False
file.write(' def get_'+field['name']+'(self):\n')
file.write(' return self._fields['+str(n)+'].get()\n\n')
if not is_obj_id:
file.write(' def set_'+field['name']+'(self, item):\n')
file.write(' self._fields['+str(n)+'].set(item)\n\n')
else:
file.write(' def set_'+field['name']+'(self, item):\n')
file.write(' if not self.is_new_object():\n')
file.write(' raise RuntimeError("setting object_id only allow for new object")\n')
file.write(' self._fields['+str(n)+'].set(item)\n\n')
n += 1
file.write(' @staticmethod\n')
file.write(' def new(prx, obj_id):\n')
file.write(' o = '+table['name']+'(new=True)\n')
file.write(' o.'+obj_id_field['name']+'.set(obj_id)\n')
file.write(' yield from o.save(prx, save_all=True)\n')
file.write(' return o\n')
file.write('\n @staticmethod\n')
file.write(' def load_index(prx, index):\n')
file.write(' ret = yield from plato.DbObject.load_index(prx, '+table['name']+', "'+obj_id_field['name']+'", "'+self.get_table_field_type(field['IdlType'])+'", index)\n')
file.write(' return ret\n\n')
file.write(' @staticmethod\n')
file.write(' def load_multi(prx, *args):\n')
file.write(' ret = yield from plato.DbObject.load_multi(prx, '+table['name']+', "'+obj_id_field['name']+'", "'+self.get_table_field_type(field['IdlType'])+'", *args)\n')
file.write(' return ret\n\n')
file.write(' @staticmethod\n')
file.write(' def query(prx, filter_cmd):\n')
file.write(' ret = yield from plato.DbObject.query(prx, '+table['name']+', filter_cmd)\n')
file.write(' return ret\n\n')
def gen_service_api_test(self, service):
file = open(self.file_name_split[0] + "_" + service['name'] + "_fixture.py", "w", encoding="utf-8")
if "methods" in service:
for method in service['methods']:
if 'event' in method:
continue
tfile = open(os.path.join(self.template_root, 'api_test_method.template'), 'r').read()
method_template = Template(tfile)
mfile = open(service['name'] + "_" + method['name'] + "_api_test.py", "w", encoding="utf-8")
mfile.write(method_template.substitute(service_name=service['name'], method_name=method['name']))
tfile = open(os.path.join(self.template_root, 'api_test.template'), 'r').read()
server_template = Template(tfile)
file.write(server_template.substitute(service_name=service['name'], idlname=self.file_name_split[0]))
def gen_method_ret_pb(self, file):
if (not ("services" in self.pb_json)) or (self.pb_json["services"] is None):
return
if "services" in self.pb_json:
for service in self.pb_json["services"]:
for method in service["methods"]:
file.write("message " + service["name"] + "_" + method["name"] + "_ret {\n")
if method["retType"]["IdlType"] == "dict":
file.write(" " + method["retType"]["type"] + "<" + method["retType"]["key"]["type"] + "," +
method["retType"]["value"]["type"] + "> " + " _1 = 1;\n")
elif method["retType"]["IdlType"] == "seq" or method["retType"]["IdlType"] == "set":
file.write(
" " + method["retType"]["type"] + " " + method["retType"]["key"]["type"] + " _1 = 1;\n")
elif method["retType"]["IdlType"] == "void":
pass
else:
file.write(" " + method["retType"]["type"] + " _1 = 1;\n")
file.write(" ServiceBoxTraceInfo trace_info = 2;\n")
file.write(" ExceptionInfo exec_info = 3;\n")
file.write(' Context context = 100;\n')
file.write("}\n\n")
def gen_method_pb_file(self, file):
if (not ("services" in self.pb_json)) or (self.pb_json["services"] is None):
return
if "services" in self.pb_json:
for service in self.pb_json["services"]:
for method in service["methods"]:
file.write("message " + service["name"] + "_" + method["name"] + "_args {\n")
n = 1
for arg in method["arguments"]:
if arg["IdlType"] == "dict":
file.write(
" " + arg["type"] + "<" + arg["key"]["type"] + "," + arg["value"]["type"] + ">")
elif arg["IdlType"] == "seq" or arg["IdlType"] == "set":
file.write(" " + arg["type"] + " " + arg["key"]["type"])
elif arg["IdlType"] == "void":
continue
else:
file.write(" " + arg["type"])
file.write(" _" + str(n) + " = " + str(n) + ";\n")
n += 1
file.write(" ServiceBoxTraceInfo trace_info = " + str(n) + ";\n")
file.write(' Context context = 100;\n')
file.write("}\n\n")
def gen_struct_pb_file(self):
file = open(self.file_name_split[0] + ".service.proto", "w", encoding="utf-8")
file.write("// Machine generated code\n\n")
file.write('syntax = "proto3";\n\n')
file.write("package " + self.file_name_split[0] + ";\n\n")
file.write("message ServiceBoxTraceInfo {\n")
file.write(" string tracer_id = 1;\n")
file.write(" uint64 span_id = 2;\n")
file.write(" uint64 parent_span_id = 3;\n")
file.write("}\n\n")
file.write('message KeyValue {\n')
file.write(' string key = 1;\n')
file.write(' string value = 2;\n')
file.write('}\n')
file.write('message Context {\n')
file.write(' repeated KeyValue info = 1;\n')
file.write('}\n')
file.write('message ExceptionInfo {\n')
file.write('\tstring name = 1;\n\tstring detail = 2;\n}\n\n')
if "enums" in self.pb_json:
for enum in self.pb_json["enums"]:
file.write("enum " + enum["name"] + " {\n")
file.write(" default_" + enum["name"] + " = 0;\n")
if "fields" in enum:
for field in enum["fields"]:
file.write(" " + field["name"] + " = " + str(field["value"]) + ";\n")
file.write("}\n\n")
if ("structs" in self.pb_json) and (self.pb_json["structs"] is not None):
for struct in self.pb_json["structs"]:
file.write("message " + struct["name"] + " {\n")
n = 1
if "fields" in struct:
for field in struct["fields"]:
if field["IdlType"] == "dict":
file.write(" " + field["type"] + "<" + field["key"]["type"] + "," + field["value"][
"type"] + "> " + field["name"] + " = " + str(n) + ";\n")
elif field["IdlType"] == "seq" or field["IdlType"] == "set":
file.write(
" " + field["type"] + " " + field["key"]["type"] + " " + field["name"] + " = " + str(
n) + ";\n")
else:
file.write(" " + field["type"] + " " + field["name"] + " = " + str(n) + ";\n")
n += 1
file.write("}\n\n")
self.gen_method_pb_file(file)
self.gen_method_ret_pb(file)
file.close()
os.system("protoc --cpp_out=. " + self.file_name_split[0] + ".service.proto")
def gen_stub_service(self, file):
if (not ("services" in self.pb_json)) or (self.pb_json["services"] is None):
return
for service in self.pb_json["services"]:
method_table_str = "{}"
if "methods" in service:
method_table_str = '{'
for method in service["methods"]:
if 'event' in method:
continue
oneway = "False"
if 'oneway' in method:
oneway = "True"
method_table_str += '"' + method['name'] + '":{"index":' + str(
method['index']) + ', "oneway":' + oneway + '},'
method_table_str += '}'
tfile = open(os.path.join(self.template_root, 'stub_service.template'), 'r').read()
server_template = Template(tfile)
file.write(server_template.substitute(service_name=service['name'], service_uuid=service['uuid'],
service_method_table=method_table_str))
def gen_prx(self, file):
if (not ("services" in self.pb_json)) or (self.pb_json["services"] is None):
return
for service in self.pb_json["services"]:
method_str = ""
if "methods" in service:
for method in service["methods"]:
if 'event' in method:
continue
tfile = open(os.path.join(self.template_root, 'proxy_method.template'), 'r').read()
server_template = Template(tfile)
oneway_flag = '0'
if 'oneway' in method:
oneway_flag = "1"
has_ret = 'True'
if ('oneway' in method) or (method["retType"]["IdlType"] == "void"):
has_ret = 'False'
if ('oneway' in method):
method['timeout'] = 0
method_str += server_template.substitute(method_name=method['name'], service_name=service['name'],
oneway=oneway_flag, method_id=str(method['index']),
timeout=str(method['timeout']), has_retval=has_ret)
tfile = open(os.path.join(self.template_root, 'proxy.template'), 'r').read()
server_template = Template(tfile)
file.write(server_template.substitute(proxy_methods=method_str, service_name=service['name'],
service_uuid=service['uuid']))
def gen_enum(self, file):
if "enums" in self.pb_json:
for enum in self.pb_json["enums"]:
file.write("class " + enum["name"] + ":\n")
if "fields" in enum:
for field in enum["fields"]:
file.write(" " + field["name"] + " = " + str(field["value"]) + "\n")
file.write('\n')
else:
file.write(' pass\n\n')
if __name__ == "__main__":
file = open(sys.argv[1], "r", encoding="utf-8")
if len(sys.argv) == 3:
FileGenerator(sys.argv[1], sys.argv[2], json.load(file))
else:
FileGenerator(sys.argv[1], './template', json.load(file))
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/dennis-kk/rpc-backend-python3.git
[email protected]:dennis-kk/rpc-backend-python3.git
dennis-kk
rpc-backend-python3
rpc-backend-python3
v0.4.0-alpha

搜索帮助