addproject

This commit is contained in:
qiaoxinjiu
2026-01-22 19:10:37 +08:00
commit 6994b185a3
184 changed files with 21039 additions and 0 deletions

View File

@@ -0,0 +1 @@
special_team = ["EN", "PZ", "ASTOP", "ASOPE", "ASTWB", "ASORG", "UBRD", "UBJ", "ES", "ASTEA", 'GUE', "TMO", "PB"]

View File

@@ -0,0 +1,684 @@
# -*- coding:utf-8 -*-
import copy
import importlib
import importlib.util as i_util
import inspect
import json
import os
import re
import sys
import traceback
from base_framework.platform_tools.Keywords_service import special_team
token_false_server = ["scm-server", "scm-biz-server", "peppa-qi-api", "lggzt", "cti-manage", "ccwx-api", "peppa-la-core-server"]
add_api_list = ["peppa-teach-api"]
host_servers = ["HULK-ORG-API", "HULK-TEACHER-API", "PEPPA-LA-CORE-SERVER"]
host_servers_except_api = ["HULK-CONTENT-AUDIT-SERVER"]
header_servers = ["hulk-operation-api-server", "hulk-teach-supply-cli-api", "hulk-teach-backend-api"]
uid_server = ['SPARKEDU-API', 'SPARKEDU-SITE-API', 'HUOHUA-SERVICE-API']
eid_server = ['SPARKEDU-SITE-MANAGE', 'SPARKEDU-SITE-SCHEDULER']
def check_server_host(servers, host):
"""
检查不需要token的server是否存在url中
"""
for server in servers:
if server in host:
return True
else:
return False
def get_project_root_path(path="base_framework"):
"""
获取项目目录
"""
o_path = os.getcwd()
try:
project_path = re.search(r"(.*%s)" % path, o_path).group(1)
return os.path.abspath(os.path.join(project_path, os.path.pardir))
except:
pass
Project_Path = get_project_root_path()
from base_framework.public_tools.log import get_logger
from base_framework.public_tools.sqlhelper import MySqLHelper
db = MySqLHelper()
log = get_logger()
def get_classes(module):
classes = []
cls_members = inspect.getmembers(module, inspect.isclass)
for (name, _) in cls_members:
classes.append(name)
return classes
def get_module_by_file_path(file_path):
spec = importlib.util.spec_from_file_location("module_name", file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
class SetAttr(object):
def __init__(self, paras):
for key, values in paras.items():
self._add_attr(key, values)
def _add_attr(self, key, value):
self.__setattr__(key, value)
class SwaggerDBInfo(object):
def __init__(self):
pass
@staticmethod
def get_team_swagger_info_by_team(teamname):
sql = "SELECT * FROM sparkatp.swagger_info where team = '%s'" % teamname
return db.select_all(sql, choose_db="huohua")
@staticmethod
def get_team_swagger_info_by_id(swagger_id):
sql = "SELECT * FROM sparkatp.swagger_info where id = '%s'" % swagger_id
return db.select_one(sql, choose_db="huohua")
@staticmethod
def get_interface_info_by_url_and_type(request_url, request_type, interface_id):
sql = '''select * from sparkatp.interface_info where in_url = "%s" and type = "%s" and
id = %s''' % (request_url, request_type, interface_id)
return db.select_all(sql, choose_db="huohua")
@staticmethod
def get_interface_parameters_by_interface_id(interface_id):
sql = """select * from sparkatp.request_parameters a right join sparkatp.parameters_relation b on
a.id = b.parameter_id where a.interface_id = {} and a.is_need != 2 and b.type = 'request'""".format(
interface_id)
return db.select_all(sql=sql, choose_db="huohua")
@staticmethod
def get_interface_request_demo_info_by_interface_id(interface_id):
sql = 'SELECT * FROM sparkatp.parameters_demo where in_id = "%s" order by id DESC' % interface_id
return db.select_all(sql, choose_db="huohua")
class KWFileOperation(object):
"""
操作xx_interface.py文件
"""
def __init__(self, team):
self.kw_file_path = os.path.abspath(os.path.join(Project_Path,
"{team}".format(team=team), "library",
"{team}_interface.py".format(team=team.upper())))
self.all_keywords = []
self.all_url = {}
self.kw_name_with_url = {}
self.runner = self._get_obj_runner()
self.team = team
self.kw_class = self._get_interface_class_name(self.kw_file_path)
def _clean_demo_to_less_key(self, demo):
demo_result = copy.deepcopy(demo)
for key, value in demo.items():
if not value:
demo_result.pop(key)
lenth = len(demo_result)
paras = "kwargs"
if lenth == 1 and isinstance(list(demo_result.values())[0], list):
paras = "args"
return lenth, demo_result, paras
def _get_interface_class_name(self, file_path):
module = get_module_by_file_path(file_path)
classes = get_classes(module)
for class_ in classes:
if "interface" in class_.lower() and class_.lower().startswith(self.team.lower()):
return class_
def _get_obj_runner(self):
spec = i_util.spec_from_file_location("module_name", self.kw_file_path)
module = i_util.module_from_spec(spec)
spec.loader.exec_module(module)
runner = inspect.getmembers(module)
for module in runner:
if module[0] == "obj_runner":
return module[1]
return runner
def _get_file_content(self):
with open(self.kw_file_path, "r", encoding="UTF-8") as f:
for line in f:
yield line.strip("\n")
def re_write_all_keyword_to_py_file(self):
with open(self.kw_file_path, "r", encoding="UTF-8") as file:
all_content = file.readlines()
index = len(all_content)
with open(self.kw_file_path, "r", encoding="UTF-8") as file1:
for line in file1:
if "if __name__" in line and "__main__" in line:
index = all_content.index(line)
break
for i in range(index - 1, 0, -1):
s = all_content[i]
if all_content[i] != "\n":
index = i
all_content.insert(i + 1, "\n")
break
a = all_content[i + 1]
with open(self.kw_file_path, "w", encoding="UTF-8") as file:
file.writelines(all_content[:index + 1])
def get_all_exist_keywords(self):
for item in self._get_file_content():
kw_match = re.search(r"def\s+(kw_in{1}_\w+)\(", item)
if kw_match:
self.all_keywords.append(kw_match.group(1))
return self.all_keywords
def get_all_exist_keywords_info(self):
for item in self._get_file_content():
kw_match = re.search(r"(kw_in{1}_\w+)\(", item)
if kw_match:
self.all_keywords.append(kw_match.group(1))
return self.all_keywords
def write_content_to_interface_file(self, content, file_path=None):
if not file_path:
file_path = self.kw_file_path
with open(file_path, "a+", encoding="UTF-8") as f:
f.write(content)
def generate_all_keyword_info(self):
"""
获取interface文件内已有关键字的url请求地址和请求方法
"""
temp_dict = {}
all_content = self._get_file_content()
server = ""
for line in all_content:
line_new = line
if "def kw_in_" in line:
kw_name = re.search("(kw_in_[\w+_]+)\(", line).group(1)
if "tools.get_container_ip_from_eureka" in line or "tool.get_container_ip_from_eureka" in line:
server = list(re.search("\([\"\']?([\w\-_]+)[\"\']?|\=[\"\']?([\w\-_]+)[\"\']?", line).groups())
server.remove(None)
server = server[0]
if "self." in line and "=" in line:
temp_dict[line.split("=")[0].strip()] = line.split("=")[1].strip().strip("\"")
if " url =" in line or "url=" in line:
log.info(line)
try:
# urls = list(re.search(r"%s(/[\w+-_\}\{]+/?)\??|\}(/[\w+-_\}\{]+/?)\??", line).groups())
match = re.search(r"%s(/[\w+-_\}\{]+/?)\??|\}(/[\w+-_\}\{]+/?)\??", line)
urls = list(match.groups()) if match else []
except Exception as err:
traceback.print_exc()
continue
# urls.remove(None)
urls = [url for url in urls if url is not None]
if not urls:
continue
url = urls[0]
if "\\" in line:
line_new = all_content.__next__()
try:
host = re.search("obj_runner\.([\w\-_]+)", line_new).group(1).strip().strip(")").strip(",")
except:
if "self." in line:
if self.team.upper() in ["EN", "ASTWB", "ASOPE"]:
host_header = "https://"
else:
host_header = "http://"
server = re.search("self\.([\w\-_]+)", line_new).group(1).strip().strip(")").strip(",")
server = server.replace("_", "-").lower()
if self.team.upper() == 'TMO':
host = host_header + "%s" % 'swagger' + ".qa.huohua.cn"
elif server.upper() in host_servers:
if server.upper() == "HULK-ORG-API":
host = host_header + "%s" % server + ".qa.huohua.cn"
else:
host = host_header + "%s" % "api" + ".qa.allschool.com"
else:
if server.upper() in host_servers_except_api:
host = host_header + "%s" % server + ".qa.allschool.com"
else:
host = host_header + "%s" % server + ".qa.huohua.cn"
if self.team.upper() == "TO":
host = "teach_opt_host"
if re.search("\{\}/\{\}", line) and "self." in line:
para = re.search("(self\.[\w_]+)", line).group(1).strip().strip(")").strip(",")
url = temp_dict[para] + urls[0]
if "?" in url:
url = url.split("?")[0]
# if url.endswith("/"):
# url = url[:len(url) - 1]
if server:
if self.team.upper() in special_team and self.team.upper() != 'TMO':
if url.startswith("/"):
url = host + "%s" % url
else:
url = host + "/%s" % url
elif self.team.upper() == 'TMO':
if url.startswith("/"):
url = '%s/%s%s' % (host, server, url)
else:
url = '%s/%s/%s' % (host, server, url)
else:
try:
if url.startswith("/"):
url = eval("self.runner.%s" % host) + "/%s" % server + url
else:
url = eval("self.runner.%s" % host) + "/%s/" % server + url
except Exception as err:
url = "empty_url"
else:
try:
if url.startswith("/"):
url1 = eval("self.runner.%s" % host)
url = url1 + url
else:
url = eval("self.runner.%s" % host) + url
except Exception as err:
url = "empty_url"
if "req_type=" in line:
method = re.search('req_type="(\w+)"|req_type=\'(\w+)\'', line.replace("\'", "\"")).group(1)
self.all_url[url] = [method, kw_name]
server = ""
return self.all_url
class KWOperation(object):
"""
根据数据库内容生成对应的keywords
"""
def __init__(self, team, kw_instance, server=None):
self.team = team
self.doc_string_table_content_temp = " |{}|{}|{}|{}|{}|"
self.function_name = ""
self.help_doc = None
self.function_content = None
self.has_kw_list = []
self.function_list = []
self.file = kw_instance
self.all_keywords = self.file.get_all_exist_keywords()
self.all_url = self.file.generate_all_keyword_info()
self.kw_name = None
self.kw_string = None
self.kw_array = None
self.server = server
def get_interface_demo(self, interface_id):
return SwaggerDBInfo.get_interface_request_demo_info_by_interface_id(interface_id)
def get_interface_parameters(self, interface_id):
return SwaggerDBInfo.get_interface_parameters_by_interface_id(interface_id)
def get_swagger_info_by_id(self, swagger_id):
return SwaggerDBInfo.get_team_swagger_info_by_id(swagger_id)
def _check_kw_exist(self, keywordname):
if keywordname in self.all_keywords:
return False
else:
return True
def generate_kw_name(self, interface_info, demo):
"""
生成对应关键字方法名称如kw_in_to_get_leads_get(**kwargs)
"""
lenth, demo_result, paras_d = self.file._clean_demo_to_less_key(demo)
_, name_list, _, _ = self._generate_all_url_paramaters(interface_info.in_url)
if "" in name_list:
name_list.remove("")
name_list.append(interface_info.name)
for item in add_api_list:
if item in interface_info.in_url:
name_list[-1] = 'api_' + name_list[-1]
count = -1
self.kw_name = "kw_in_{}_{}_{}".format(self.team.lower(), name_list[-1], interface_info.type.lower())
while abs(count) <= len(name_list):
if self._check_kw_exist(self.kw_name):
if lenth > 1:
self.function_name = " def {kw_name}(self, **kwargs):".format(kw_name=self.kw_name)
else:
if self.team.upper() in ["TMO"]:
self.function_name = " def {kw_name}(self, **kwargs):".format(kw_name=self.kw_name)
else:
if demo_result:
if isinstance(list(demo_result.values())[0], list):
self.function_name = " def {kw_name}(self, *args, **kwargs):".format(
kw_name=self.kw_name)
else:
self.function_name = " def {kw_name}(self, **kwargs):".format(
kw_name=self.kw_name)
else:
self.function_name = " def {kw_name}(self, **kwargs):".format(
kw_name=self.kw_name)
self.has_kw_list.append(interface_info.id)
self.all_keywords.append(self.kw_name)
return True
else:
count -= 1
self.kw_name += "_" + name_list[count]
else:
self.has_kw_list.append(interface_info.id)
return False
def generate_kw_doc(self, interface_info, parameters_list):
"""
根据接口参数信息生成对应的帮助文档
"""
def set_lenth(para):
return " " + str(para).strip() + " "
def get_normal_value(normal_values):
return normal_values.split(",")[0] if normal_values else 0
doc = []
doc_string_head = " \"\"\""
doc_string_table_head = " | {} | {} | {} | {} | {} |".format("请求参数名".ljust(30), "说明".ljust(15),
"类型".ljust(12), "是否必填".ljust(8),
"如无要求时的值".ljust(8))
doc.append(doc_string_head)
doc.append(" | 功能说明:| {} |".format(interface_info.interface_describe))
doc.append(doc_string_table_head)
# if self.team.upper() not in ["TMO"]:
# doc.append(self.doc_string_table_content_temp.format(set_lenth("is_check"),
# set_lenth("is_check默认空不校验返回有值就校验返回"),
# set_lenth("string"),
# set_lenth("业务case的时候需要传入值"),
# set_lenth("False")))
for parameter in parameters_list:
attr = SetAttr(parameter)
if int(attr.in_body) != 0 and int(attr.is_need) != 2:
doc.append(self.doc_string_table_content_temp.format(set_lenth(attr.name), set_lenth(attr.note),
set_lenth(attr.type), set_lenth(attr.is_need),
set_lenth(get_normal_value(attr.normal_values))))
doc.append(doc_string_head)
return "\n".join(doc)
def _generate_all_url_paramaters(self, url):
"""
拆解url生成host, 生成keyword名的相关名称和url中带{}的参数
"""
head_list = []
para_list = []
host, url_last = re.search(r"(\S+\.cn|\S+\.com)(\S+)", url).groups()
search = re.findall("[\w+\-_]+|[\{\w+\-_\}]+", url_last)
if self.team.upper() in ["TMO"]:
search.pop(0)
url_lasr_temp = url_last.split("/")
url_lasr_temp.pop(1)
url_last = '/'.join(url_lasr_temp)
for item in search:
if "{" in item:
temp = item.replace("{", "").replace("}", "")
para_list.append(temp)
else:
head_list.append(item)
return host, head_list, para_list, url_last
def _generate_url_host(self, host):
"""
根据host生成对应的url后缀比如teach_opt_host
如果需要将host替换成IP则生成对应的IP
"""
url_host = ""
if 'peppa-cc-manage' in host:
url_host = "cc_host"
elif 'crmv2' in host or 'smm' in host or 'xxljob' in host:
url_host = "crm_host"
elif 'scm' in host:
url_host = "scm_host"
elif "la-gate" in host:
url_host = "insights_host"
elif 'la-ai-api-bg' in host or 'la-api-ai' in host:
url_host = "spark_land_host"
elif 'manage' in host:
url_host = "manage_host"
elif 'teach' in host:
url_host = "teach_host"
elif 'teach-opt-api' in host or 'sparkle-manage' in host:
url_host = "teach_opt_host"
elif 'opengalaxy' in host:
url_host = "opengalaxy_host"
elif 'employee-manage' in host:
url_host = "ehr_host"
elif 'peppa-agent-manage' in host:
url_host = "hhr_host"
elif 'peppa-agent-api' in host:
url_host = "hhr_api_host"
elif "teach-message-api" in host:
url_host = "teacher_message_host"
elif "swagger" in host:
url_host = "swagger_host"
elif "peppa-qi-api" in host:
url_host = "qi_host"
elif "scm-server" in host:
url_host = "scm_server_host"
elif "scm-biz-server" in host:
url_host = "scm_biz_server_host"
elif "cti-manage" in host:
url_host = "cti_host"
elif "peppa-conversion-api" in host:
url_host = "uc_host"
elif "la-api" in host:
url_host = "la_api_host"
elif "hulk_content_audit_server" in host:
url_host = "hulk_content_audit"
elif "ccwx-api" in host:
url_host = "cc_weixin_host"
return url_host
def generate_function_url(self, interface_info, demo):
"""
生成对应的url
"""
lenth, demo_result, paras_d = self.file._clean_demo_to_less_key(demo)
url_list = []
user_kwargs = " user, kwargs = get_user(kwargs)"
url_list.append(user_kwargs)
check_json = " kwargs = convert_json(kwargs)"
if paras_d == "args":
check_json = " args = convert_json(args)"
url_list.append(check_json)
host, _, parameters, url_last = self._generate_all_url_paramaters(interface_info.in_url)
host = re.findall("[\w+-]+", host)
url_host = self._generate_url_host(host)
server = ""
# if self.team.upper() in ["TMO"]:
# url_list.append(" try:\n kwargs = eval(args[0])\n except:")
# url_list.append(" try:\n if args[0] and isinstance(args[0], dict):")
# url_list.append("kwargs = args[0]".rjust(20 + len("kwargs = args[0]"), " "))
# url_list.append("except:".rjust(12 + len("except:"), " "))
# url_list.append("kwargs = kwargs".rjust(16 + len("kwargs = kwargs"), " "))
# url_last_tmp = url_last.split("/")
# server = url_last_tmp.pop(1)
# url_last = "/".join(url_last_tmp)
# ip = " ip = tools.get_container_ip_from_eureka(\"%s\", need_jira_id=True)" % server
# url_list.append(ip)
# host = " obj_runner." + url_host + " = \"http://\" + " + "ip[\"container_ip\"]" + " + \":8080\""
# url_list.append(host)
if self.team.upper() in special_team:
if self.server.upper() in host_servers or self.team.upper() in ["TMO"]:
host_server = self.server.lower().replace("-", "_")
else:
host_server = host[1].replace("-", "_")
url_host = "self.%s" % host_server
else:
if self.server.upper() in host_servers or self.team.upper() in ["TMO"]:
host_server = self.server.lower().replace("-", "_")
url_host = "self.%s" % host_server
# if self.team.upper() == 'LALIVE' and 'la-api' in host:
# url_last = url_last.replace("smart", "api/smart")
if "PEPPA-QI-API".lower() in host:
ip = " obj_runner.%s = \"http://{}:8080\".format(self.get_container_ip('PEPPA-QI-API'))" % url_host
url_list.append(ip)
if parameters:
if lenth > 1:
temp = 'kwargs.get("u")'
else:
temp = 'kwargs'
url = " url = \"%s" + url_last + "\".format("
for item in parameters:
url += "%s=%s, " % (item, "%s.get(\"%s\", \"\")" % (temp, item))
url += ") % "
else:
url = " url = \"%s" + url_last + "\" % "
if self.team.upper() in special_team or self.server.upper() in host_servers:
url += url_host
else:
url += "obj_runner.%s" % url_host
url_list.append(url)
return "\n".join(url_list), server
def generate_function_body(self, interface_info, demo, parameters_all):
"""
生成关键字的body内容
"""
lenth, demo_result, paras_d = self.file._clean_demo_to_less_key(demo)
host, _, parameters, url_last = self._generate_all_url_paramaters(interface_info.in_url)
func_body = []
if re.search(r"\*(\w+)", self.function_name):
paras = re.search(r"\*(\w+)", self.function_name).group(1)
if self.team.upper() in ["TMO"]:
paras = "kwargs"
content = ' obj_log.info("your input:{0}".format(%s))' % paras
func_body.append(content)
if self.kw_string:
func_body.append(" kwargs = kwargs.get('%s', '')" % parameters_all[0].get("name"))
if self.kw_array:
func_body.append(" kwargs = eval(kwargs.pop('%s'))" % parameters_all[0].get("name"))
else:
paras = None
if lenth > 1:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", ' % interface_info.type
if "d" in demo_result:
resp = resp + 'json=kwargs.get("d"), '
if "p" in demo_result:
resp = resp + 'params=kwargs.get("p"), '
if "h" in demo_result:
resp = resp + 'headers=kwargs.get("h"), '
resp = resp + 'user=user)'
else:
if demo_result:
if "d" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", json=%s, user=user)' % (
interface_info.type, paras)
elif "h" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", headers=%s, user=user)' % (
interface_info.type, paras)
elif "p" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", params=%s, user=user)' % (
interface_info.type, paras)
elif "u" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", user=user)' % (
interface_info.type)
else:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", user=user)' % (
interface_info.type)
if self.team.upper() in special_team or check_server_host(token_false_server, host) or \
self.team.upper() in ["TMO"]:
resp = resp.replace("user=user", "token=False")
try:
if self.server.upper() in host_servers:
resp = resp.replace("token=False", "token=False, user=user")
if self.server.upper() == "HULK-ORG-API":
resp = resp.replace("user=user", "user=user, as_login_type=2")
if self.server.upper() in host_servers_except_api:
resp = resp.replace("token=False", "")
except:
pass
if str(self.server).lower() in header_servers:
header = " header = {'debug-param': 'huangliye@huohua.cn'}"
if "h" in demo_result:
resp = resp.replace(' headers=kwargs.get("h"),', "")
header = " header = kwargs.get('h')\n header.update({'debug-param': 'huangliye@huohua.cn'})"
func_body.append(header)
resp = resp.replace("token=False", "token=False, headers=header")
if str(self.server).upper() in eid_server:
header = " header = {'debug-param': 'eid:%s' % self.eid}"
if "h" in demo_result:
resp = resp.replace(' headers=kwargs.get("h"),', "")
header = " header = kwargs.get('h')\n header.update({'debug-param': 'eid:%s' % self.eid})"
func_body.append(header)
resp = resp.replace("token=False", "token=False, headers=header")
if str(self.server).upper() in uid_server:
header = " header = {'debug-param': 'uid:%s' % self.uid}"
if "h" in demo_result:
resp = resp.replace(' headers=kwargs.get("h"),', "")
header = " header = kwargs.get('h')\n header.update({'debug-param': 'uid:%s' % self.uid})"
func_body.append(header)
resp = resp.replace("token=False", "token=False, headers=header")
func_body.append(resp)
# if self.team.upper() not in ["TMO"] and paras_d == "kwargs":
# func_body.append(" check_resp(is_check, resp)")
func_body.append(" return resp\n")
return "\n".join(func_body)
def get_has_keyword_id_in_db(self):
"""
获取所有已有
"""
keyword_list = []
for key in self.all_url.keys():
interface_name = key.split("/")[-1]
sql = "select * from sparkatp.interface_info where name = '%s' and type = '%s'" % (
interface_name, self.all_url[key][0])
interface_infos = SwaggerDBInfo.get_db_info_by_sql(sql=sql)
for interface_info in interface_infos:
interface_attr = SetAttr(interface_info)
if key.lower() in interface_attr.in_url.lower():
keyword_list.append(interface_attr.id)
return keyword_list
def run_keyword_generage(result_path, interface, demo_info, parameters, keyword):
if demo_info.request_demo:
demo_info = json.loads(demo_info.request_demo)
else:
demo_info = {}
if keyword.all_url.get(interface.in_url) and keyword.all_url.get(interface.in_url)[
0].lower() == interface.type.lower():
msg = "接口url%s,%s,已存在关键字,继续生成用例!" % (interface.type, interface.in_url)
log.warning(msg)
keyword.file.write_content_to_interface_file(msg + "\n", result_path)
return True
else:
exist = keyword.generate_kw_name(interface, demo_info)
if exist:
keyword.function_list = []
doc = keyword.generate_kw_doc(interface, parameters)
url, temp = keyword.generate_function_url(interface, demo_info)
content = keyword.generate_function_body(interface, demo_info, parameters)
keyword.function_list.append("\n".join(("", keyword.function_name, doc, url, content)))
keyword.file.re_write_all_keyword_to_py_file()
keyword.file.write_content_to_interface_file("\n".join(keyword.function_list))
keyword.file.all_url[interface.in_url] = [interface.type, keyword.kw_name]
return True
else:
msg = "接口url%s,%s,无法生成关键字,请检查!" % (interface.type, interface.in_url)
log.warning(msg)
keyword.file.write_content_to_interface_file(msg + "\n", result_path)
return False

View File

@@ -0,0 +1,666 @@
# -*- coding:utf-8 -*-
import copy
import importlib
import importlib.util as i_util
import inspect
import json
import os
import re
import sys
import traceback
from base_framework.platform_tools.Keywords_service import special_team
token_false_server = ["scm-server", "scm-biz-server", "peppa-qi-api", "lggzt", "cti-manage", "ccwx-api"]
add_api_list = ["peppa-teach-api"]
host_servers = ["HULK-ORG-API", "HULK-TEACHER-API"]
host_servers_except_api = ["HULK-CONTENT-AUDIT-SERVER"]
header_servers = ["hulk-operation-api-server", "hulk-teach-supply-cli-api", "hulk-teach-backend-api"]
uid_server = ['SPARKEDU-API', 'SPARKEDU-SITE-API']
eid_server = ['SPARKEDU-SITE-MANAGE', 'SPARKEDU-SITE-SCHEDULER']
def check_server_host(servers, host):
"""
检查不需要token的server是否存在url中
"""
for server in servers:
if server in host:
return True
else:
return False
def get_project_root_path(path="base_framework"):
"""
获取项目目录
"""
o_path = os.getcwd()
try:
project_path = re.search(r"(.*%s)" % path, o_path).group(1)
return os.path.abspath(os.path.join(project_path, os.path.pardir))
except:
pass
Project_Path = get_project_root_path()
from base_framework.public_tools.log import get_logger
from base_framework.public_tools.sqlhelper import MySqLHelper
db = MySqLHelper()
log = get_logger()
def get_classes(module):
classes = []
cls_members = inspect.getmembers(module, inspect.isclass)
for (name, _) in cls_members:
classes.append(name)
return classes
def get_module_by_file_path(file_path):
spec = importlib.util.spec_from_file_location("module_name", file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
class SetAttr(object):
def __init__(self, paras):
for key, values in paras.items():
self._add_attr(key, values)
def _add_attr(self, key, value):
self.__setattr__(key, value)
class SwaggerDBInfo(object):
def __init__(self):
pass
@staticmethod
def get_team_swagger_info_by_team(teamname):
sql = "SELECT * FROM sparkatp.swagger_info where team = '%s'" % teamname
return db.select_all(sql, choose_db="huohua")
@staticmethod
def get_team_swagger_info_by_id(swagger_id):
sql = "SELECT * FROM sparkatp.swagger_info where id = '%s'" % swagger_id
return db.select_one(sql, choose_db="huohua")
@staticmethod
def get_interface_info_by_url_and_type(request_url, request_type, team):
sql = 'select * from sparkatp.interface_info where in_url = "%s" and type = "%s" and swagger_id in (select id from sparkatp.swagger_info where team = "%s")' % (request_url, request_type, team)
return db.select_all(sql, choose_db="huohua")
@staticmethod
def get_interface_parameters_by_interface_id(interface_id):
sql = "select * from sparkatp.request_parameters a right join sparkatp.parameters_relation b on a.id = b.parameter_id where a.interface_id = {} and b.type = 'request' and a.offline=0".format(
interface_id)
return db.select_all(sql=sql, choose_db="huohua")
@staticmethod
def get_interface_request_demo_info_by_interface_id(interface_id):
sql = 'SELECT * FROM sparkatp.parameters_demo where in_id = "%s" order by id DESC' % interface_id
return db.select_all(sql, choose_db="huohua")
@staticmethod
def get_swagger_url_by_team_and_server(team, server):
sql = "select * from sparkatp.swagger_info where team='%s' and server_name = '%s';" % (team, server)
return db.select_one(sql, choose_db="huohua")
class KWFileOperation(object):
"""
操作xx_interface.py文件
"""
def __init__(self, team, server):
self.kw_file_path = os.path.abspath(os.path.join(Project_Path,
"{team}".format(team=team), "library",
"{team}_interface.py".format(team=team.upper())))
self.team = team
self.server = server
self.all_url = {}
self.all_keywords = []
self.runner = self._get_obj_runner()
self.file_content = self.re_write_all_keyword_to_py_file()
self.check_server_and_rewrite_server()
self.get_all_exist_keywords()
self.generate_all_keyword_info()
self.kw_class = self._get_interface_class_name(self.kw_file_path)
def check_server_and_rewrite_server(self):
"""
检查server是否在interface.py文件中配置获取IP
"""
start_index = 0
empty_index = 0
server_host = self.server.lower().replace('-', '_')
server_upper = self.server.upper()
if "self.%s =" % server_host in ''.join(self.file_content) or '':
return
for line in self.file_content:
if "def __init__(self):" in line:
start_index = self.file_content.index(line) + 1
log.info(start_index)
if start_index == 0:
continue
if " def " in line and "__init__" not in line:
end_index = self.file_content.index(line)
log.info(end_index)
break
if "pass" in self.file_content[start_index]:
self.file_content[
start_index] = ' self.need_jira_id = True if ReadConfig(env_choose_path).get_value("run_jira_id", "huohua-podenv") else False\n'
elif 'self.need_jira_id = True if ' not in self.file_content[start_index] and "pass" in self.file_content[
start_index]:
self.file_content.insert(start_index,
' self.need_jira_id = True if ReadConfig(env_choose_path).get_value("run_jira_id", "huohua-podenv") else False\n')
for item in range(start_index, end_index):
if self.file_content[item] == "\n":
self.file_content.insert(item,
" self.%s_ip = obj_tool.get_container_ip_from_eureka('%s', need_jira_id=self.need_jira_id)\n" % (
server_host, server_upper))
self.file_content.insert(item + 1,
' self.%s = "http://" + self.%s_ip["container_ip"] + ":8080"\n' % (
server_host, server_host))
break
with open(self.kw_file_path, "w", encoding="UTF-8") as file:
for line1 in self.file_content:
file.writelines(line1)
def _clean_demo_to_less_key(self, demo):
demo_result = copy.deepcopy(demo)
for key, value in demo.items():
if not value:
demo_result.pop(key)
lenth = len(demo_result)
paras = "kwargs"
if lenth == 1 and isinstance(list(demo_result.values())[0], list):
paras = "args"
return lenth, demo_result, paras
def _get_interface_class_name(self, file_path):
module = get_module_by_file_path(file_path)
classes = get_classes(module)
for class_ in classes:
if "interface" in class_.lower():
return class_
def _get_obj_runner(self):
spec = i_util.spec_from_file_location("module_name", self.kw_file_path)
module = i_util.module_from_spec(spec)
spec.loader.exec_module(module)
runner = inspect.getmembers(module)
for module in runner:
if module[0] == "obj_runner":
return module[1]
return runner
def _get_file_content(self):
with open(self.kw_file_path, "r", encoding="UTF-8") as file:
all_content = file.readlines()
return all_content
def re_write_all_keyword_to_py_file(self):
with open(self.kw_file_path, "r", encoding="UTF-8") as file:
all_content = file.readlines()
index = len(all_content)
with open(self.kw_file_path, "r", encoding="UTF-8") as file1:
for line in file1:
if "if __name__" in line and "__main__" in line:
index = all_content.index(line)
break
for i in range(index - 1, 0, -1):
s = all_content[i]
if all_content[i] != "\n":
index = i
all_content.insert(i + 1, "\n")
break
a = all_content[i + 1]
with open(self.kw_file_path, "w", encoding="UTF-8") as file:
file.writelines(all_content[:index + 1])
return all_content[:index + 1]
def get_all_exist_keywords(self):
for item in self.file_content:
kw_match = re.search(r"def\s+(kw_in{1}_\w+)\(", item)
if kw_match:
self.all_keywords.append(kw_match.group(1))
return self.all_keywords
def write_content_to_interface_file(self, content, file_path=None):
if not file_path:
file_path = self.kw_file_path
with open(file_path, "a+", encoding="UTF-8") as f:
f.write(content)
def generate_all_keyword_info(self):
"""
获取interface文件内已有关键字的url请求地址和请求方法
"""
temp_dict = {}
all_content = self.file_content
server = False
kw_line = False
url_line = False
host = False
for line in all_content:
if "def kw_in_" in line:
kw_line = True
kw_name = re.search("(kw_in_[\w+_]+)\(", line).group(1)
if kw_line:
try:
if "get_container_ip" in line:
server = list(re.search(r'get_container_ip.*\([\'\"]([\w\-_]+)[\'\"]', line).groups())
server = server[0]
except Exception as err:
pass
if "self." in line and "=" in line:
temp_dict[line.split("=")[0].strip()] = line.split("=")[1].strip().strip("\"")
if (" url =" in line or "url=" in line) and 'url +' not in line:
log.info(line)
try:
urls = list(re.search(r"%s(/[\w+-_\}\{]+/?)\??|\}(/[\w+-_\}\{]+/?)\??", line).groups())
urls.remove(None)
except Exception as err:
log.info("error: %s" % line)
url_line = True
if url_line:
if 'url = "%s/api/customer/{customerId}/give_up"' in line:
print()
if not host:
try:
host_key = re.search("obj_runner\.([\w\-_]+)", line).group(1).strip().strip(")").strip(",")
host = eval("self.runner.%s" % host_key)
except:
if not server:
if "self." in line:
server = re.search("self\.([\w\-_]+)", line).group(1).strip().strip(")").strip(",")
server = server.replace("_", "-").lower()
if server:
try:
host_temp = SwaggerDBInfo.get_swagger_url_by_team_and_server(self.team, server)['sw_url']
host = host_temp.split("/v2")[0]
except Exception as err:
host = ""
if host:
url = host + urls[0]
if "req_type=" in line:
method = re.search('req_type="(\w+)"|req_type=\'(\w+)\'', line.replace("\'", "\"")).group(1)
self.all_url[url] = [method, kw_name]
server = False
kw_line = False
url_line = False
host = False
return self.all_url
class KWOperation(object):
"""
根据数据库内容生成对应的keywords
"""
def __init__(self, team, kw_instance):
self.team = team
self.doc_string_table_content_temp = " |{}|{}|{}|{}|{}|"
self.function_name = ""
self.help_doc = None
self.function_content = None
self.has_kw_list = []
self.function_list = []
self.file = kw_instance
self.all_keywords = self.file.all_keywords
self.all_url = self.file.all_url
self.kw_name = None
self.kw_string = None
self.server = kw_instance.server
def get_interface_demo(self, interface_id):
return SwaggerDBInfo.get_interface_request_demo_info_by_interface_id(interface_id)
def get_interface_parameters(self, interface_id):
return SwaggerDBInfo.get_interface_parameters_by_interface_id(interface_id)
def get_swagger_info_by_id(self, swagger_id):
return SwaggerDBInfo.get_team_swagger_info_by_id(swagger_id)
def _check_kw_exist(self, keywordname):
if keywordname in self.all_keywords:
return False
else:
return True
def generate_kw_name(self, interface_info, demo):
"""
生成对应关键字方法名称如kw_in_to_get_leads_get(is_check='', **kwargs)
"""
lenth, demo_result, paras_d = self.file._clean_demo_to_less_key(demo)
_, name_list, _, _ = self._generate_all_url_paramaters(interface_info.in_url)
if "" in name_list:
name_list.remove("")
name_list.append(interface_info.name)
for item in add_api_list:
if item in interface_info.in_url:
name_list[-1] = 'api_' + name_list[-1]
count = -1
self.kw_name = "kw_in_{}_{}_{}".format(self.team.lower(), name_list[-1], interface_info.type.lower())
while abs(count) <= len(name_list):
if self._check_kw_exist(self.kw_name):
if lenth > 1:
self.function_name = " def {kw_name}(self, is_check='', **kwargs):".format(kw_name=self.kw_name)
else:
if self.team.upper() in ["TMO"]:
self.function_name = " def {kw_name}(self, *args, **kwargs):".format(kw_name=self.kw_name)
else:
if demo_result:
if isinstance(list(demo_result.values())[0], list):
self.function_name = " def {kw_name}(self, *args, **kwargs):".format(
kw_name=self.kw_name)
else:
self.function_name = " def {kw_name}(self, is_check='', **kwargs):".format(
kw_name=self.kw_name)
else:
self.function_name = " def {kw_name}(self, is_check='', **kwargs):".format(
kw_name=self.kw_name)
self.has_kw_list.append(interface_info.id)
self.all_keywords.append(self.kw_name)
return True
else:
count -= 1
self.kw_name += "_" + name_list[count]
else:
self.has_kw_list.append(interface_info.id)
return False
def generate_kw_doc(self, interface_info, parameters_list):
"""
根据接口参数信息生成对应的帮助文档
"""
def set_lenth(para):
return " " + str(para).strip() + " "
doc = []
doc_string_head = " \"\"\""
doc_string_table_head = " | {}| {}| {}| {}| {}|".format("请求参数名".ljust(30), "说明".ljust(15),
"类型".ljust(12), "条件".ljust(10),
"是否必填".ljust(8))
doc.append(doc_string_head)
doc.append(" {} + {} + interface id: {}".format(interface_info.interface_describe, interface_info.type,
interface_info.id))
doc.append(" url: " + interface_info.in_url)
doc.append(doc_string_table_head)
if self.team.upper() not in ["TMO"]:
doc.append(self.doc_string_table_content_temp.format(set_lenth("is_check"),
set_lenth("is_check默认空不校验返回有值就校验返回"),
set_lenth("string"),
set_lenth("业务case的时候需要传入值"),
set_lenth("False")))
for parameter in parameters_list:
attr = SetAttr(parameter)
if int(attr.in_body) != 0 and int(attr.is_need) != 2:
doc.append(self.doc_string_table_content_temp.format(set_lenth(attr.name), set_lenth(attr.note),
set_lenth(attr.type), set_lenth(attr.p_condition),
set_lenth(attr.is_need)))
doc.append(doc_string_head)
return "\n".join(doc)
def _generate_all_url_paramaters(self, url):
"""
拆解url生成host, 生成keyword名的相关名称和url中带{}的参数
"""
head_list = []
para_list = []
host, url_last = re.search(r"(\S+\.cn|\S+\.com)(\S+)", url).groups()
search = re.findall("[\w+\-_]+|[\{\w+\-_\}]+", url_last)
for item in search:
if "{" in item:
temp = item.replace("{", "").replace("}", "")
para_list.append(temp)
else:
head_list.append(item)
return host, head_list, para_list, url_last
def _generate_url_host(self):
"""
根据host生成对应的url后缀比如teach_opt_host
如果需要将host替换成IP则生成对应的IP
"""
server_temp = self.server.lower().replace('-', '_')
url_host = 'self.%s' % server_temp
# if self.server:
# url_host = ""
# url_host = ""
# if 'peppa-cc-manage' in host:
# url_host = "cc_host"
# elif 'crmv2' in host or 'smm' in host or 'xxljob' in host:
# url_host = "crm_host"
# elif 'scm' in host:
# url_host = "scm_host"
# elif "la-gate" in host:
# url_host = "insights_host"
# elif 'la-ai-api-bg' in host or 'la-api-ai' in host:
# url_host = "spark_land_host"
# elif 'manage' in host:
# url_host = "manage_host"
# elif 'teach' in host:
# url_host = "teach_host"
# elif 'teach-opt-api' in host or 'sparkle-manage' in host:
# url_host = "teach_opt_host"
# elif 'opengalaxy' in host:
# url_host = "opengalaxy_host"
# elif 'employee-manage' in host:
# url_host = "ehr_host"
# elif 'peppa-agent-manage' in host:
# url_host = "hhr_host"
# elif 'peppa-agent-api' in host:
# url_host = "hhr_api_host"
# elif "teach-message-api" in host:
# url_host = "teacher_message_host"
# elif "swagger" in host:
# url_host = "swagger_host"
# elif "peppa-qi-api" in host:
# url_host = "qi_host"
# elif "scm-server" in host:
# url_host = "scm_server_host"
# elif "scm-biz-server" in host:
# url_host = "scm_biz_server_host"
# elif "cti-manage" in host:
# url_host = "cti_host"
# elif "peppa-conversion-api" in host:
# url_host = "uc_host"
# elif "la-api" in host:
# url_host = "la_api_host"
# elif "hulk_content_audit_server" in host:
# url_host = "hulk_content_audit"
return url_host
def generate_function_url(self, interface_info, demo):
"""
生成对应的url
"""
lenth, demo_result, paras_d = self.file._clean_demo_to_less_key(demo)
url_list = []
user_kwargs = " user, kwargs = get_user(kwargs)"
url_list.append(user_kwargs)
check_json = " kwargs = convert_json(kwargs)"
if paras_d == "args":
check_json = " args = convert_json(args)"
url_list.append(check_json)
host, _, parameters, url_last = self._generate_all_url_paramaters(interface_info.in_url)
host = re.findall("[\w+-]+", host)
url_host = self._generate_url_host()
server = ""
if self.team.upper() in ["TMO"]:
url_list.append(" try:\n kwargs = eval(args[0])\n except:")
url_list.append(" try:\n if args[0] and isinstance(args[0], dict):")
url_list.append("kwargs = args[0]".rjust(20 + len("kwargs = args[0]"), " "))
url_list.append("except:".rjust(12 + len("except:"), " "))
url_list.append("kwargs = kwargs".rjust(16 + len("kwargs = kwargs"), " "))
url_last_tmp = url_last.split("/")
server = url_last_tmp.pop(1)
url_last = "/".join(url_last_tmp)
if parameters:
if lenth > 1:
temp = 'kwargs.get("u")'
else:
temp = 'kwargs'
url = " url = \"%s" + url_last + "\".format("
for item in parameters:
url += "%s=%s, " % (item, "%s.get(\"%s\", \"\")" % (temp, item))
url += ") % "
else:
url = " url = \"%s" + url_last + "\" % "
url += url_host
url_list.append(url)
return "\n".join(url_list), server
def generate_function_body(self, interface_info, demo, parameters_all):
"""
生成关键字的body内容
"""
lenth, demo_result, paras_d = self.file._clean_demo_to_less_key(demo)
host, _, parameters, url_last = self._generate_all_url_paramaters(interface_info.in_url)
func_body = []
if re.search(r"\*(\w+)", self.function_name):
paras = re.search(r"\*(\w+)", self.function_name).group(1)
if self.team.upper() in ["TMO"]:
paras = "kwargs"
content = ' obj_log.info("your input:{0}".format(%s))' % paras
func_body.append(content)
if self.kw_string:
func_body.append(" kwargs = kwargs.get('%s', '')" % parameters_all[0].get("name"))
else:
paras = None
if lenth > 1:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", ' % interface_info.type
if "d" in demo_result:
resp = resp + 'json=kwargs.get("d"), '
if "p" in demo_result:
resp = resp + 'params=kwargs.get("p"), '
if "h" in demo_result:
resp = resp + 'headers=kwargs.get("h"), '
resp = resp + 'user=user)'
else:
if demo_result:
if "d" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", json=%s, user=user)' % (
interface_info.type, paras)
elif "h" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", headers=%s, user=user)' % (
interface_info.type, paras)
elif "p" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", params=%s, user=user)' % (
interface_info.type, paras)
elif "u" in demo_result:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", user=user)' % (
interface_info.type)
else:
resp = ' resp = obj_runner.call_rest_api(API_URL=url, req_type="%s", user=user)' % (
interface_info.type)
if self.team.upper() in special_team or check_server_host(token_false_server, host) or self.team.upper() in [
"TMO"]:
resp = resp.replace("user=user", "token=False")
try:
if self.server.upper() in host_servers:
resp = resp.replace("token=False", "token=False, user=user")
if self.server.upper() == "HULK-ORG-API":
resp = resp.replace("user=user", "user=user, as_login_type=2")
if self.server.upper() in host_servers_except_api:
resp = resp.replace("token=False", "")
except:
pass
if str(self.server).lower() in header_servers:
header = " header = {'debug-param': 'huangliye@huohua.cn'}"
if "h" in demo_result:
resp = resp.replace(' headers=kwargs.get("h"),', "")
header = " header = kwargs.get('h')\n header.update({'debug-param': 'huangliye@huohua.cn'})"
func_body.append(header)
resp = resp.replace("token=False", "token=False, headers=header")
if str(self.server).upper() in eid_server:
header = " header = {'debug-param': 'eid:%s' % self.eid}"
if "h" in demo_result:
resp = resp.replace(' headers=kwargs.get("h"),', "")
header = " header = kwargs.get('h')\n header.update({'debug-param': 'eid:%s' % self.eid})"
func_body.append(header)
resp = resp.replace("token=False", "token=False, headers=header")
if str(self.server).upper() in uid_server:
header = " header = {'debug-param': 'uid:%s' % self.uid}"
if "h" in demo_result:
resp = resp.replace(' headers=kwargs.get("h"),', "")
header = " header = kwargs.get('h')\n header.update({'debug-param': 'uid:%s' % self.uid})"
func_body.append(header)
resp = resp.replace("token=False", "token=False, headers=header")
func_body.append(resp)
if self.team.upper() not in ["TMO"] and paras_d == "kwargs":
func_body.append(" check_resp(is_check, resp)")
func_body.append(" return resp\n")
return "\n".join(func_body)
def get_has_keyword_id_in_db(self):
"""
获取所有已有
"""
keyword_list = []
for key in self.all_url.keys():
interface_name = key.split("/")[-1]
sql = "select * from sparkatp.interface_info where name = '%s' and type = '%s'" % (
interface_name, self.all_url[key][0])
interface_infos = SwaggerDBInfo.get_db_info_by_sql(sql=sql)
for interface_info in interface_infos:
interface_attr = SetAttr(interface_info)
if key.lower() in interface_attr.in_url.lower():
keyword_list.append(interface_attr.id)
return keyword_list
def run_keyword_generage(result_path, interface, demo_info, parameters, keyword):
if demo_info.request_demo:
demo_info = json.loads(demo_info.request_demo)
else:
demo_info = {}
if keyword.all_url.get(interface.in_url) and keyword.all_url.get(interface.in_url)[
0].lower() == interface.type.lower():
msg = "接口url%s,%s,已存在关键字,继续生成用例!" % (interface.type, interface.in_url)
log.warning(msg)
keyword.file.write_content_to_interface_file(msg + "\n", result_path)
return True
else:
exist = keyword.generate_kw_name(interface, demo_info)
if exist:
keyword.function_list = []
doc = keyword.generate_kw_doc(interface, parameters)
url, temp = keyword.generate_function_url(interface, demo_info)
content = keyword.generate_function_body(interface, demo_info, parameters)
keyword.function_list.append("\n".join(("", keyword.function_name, doc, url, content)))
keyword.file.re_write_all_keyword_to_py_file()
keyword.file.write_content_to_interface_file("\n".join(keyword.function_list))
keyword.file.all_url[interface.in_url] = [interface.type, keyword.kw_name]
return True
else:
msg = "接口url%s,%s,无法生成关键字,请检查!" % (interface.type, interface.in_url)
log.warning(msg)
keyword.file.write_content_to_interface_file(msg + "\n", result_path)
return False
if __name__ == "__main__":
kw = KWFileOperation("CC", "peppa-qi-api")
kw.check_server_and_rewrite_server()

View File

@@ -0,0 +1,3 @@
目录结构说明:
使用者:王刚
用途存放自动生成py文件关键字的脚本