删除敏感信息

This commit is contained in:
chenyongzhiaaron 2023-07-04 18:05:35 +08:00
parent ae6cf6eb48
commit 979f2ffdaf
90 changed files with 1569 additions and 7260 deletions

View File

@ -1,3 +0,0 @@
2023-06-30 09:01:03 | ERROR | 发送请求失败: Value for header {BSP_USER_ID: 216684145642752200} must be of type str or bytes, not <class 'int'>
2023-06-30 09:01:25 | ERROR | 发送请求失败: Value for header {projectId: 99000022} must be of type str or bytes, not <class 'int'>
2023-06-30 09:01:34 | ERROR | 发送请求失败: Method cannot contain non-token characters '/IBS/API/IBS-LMS-BASE/WORK-KIND/PAGE/LIST?T=1636702597000&CURRENT=1&SIZE=1000&PROJECTID=99000022&KEY=&SUPPLYID=&STATUS=0&ENABLED=1' (found at least '/')

View File

@ -1,188 +0,0 @@
{
"projectId": "99000022",
"suitability": "",
"avatar": "https://bimuse.bzlrobot.com/bsp/test/opi/document/v1/document/fileStore/viewPicture/6f2a66c24aa8446b8e5b2e828ca17909",
"isTeamLeader": 0,
"name": "张妹春",
"phone": "18188888888",
"workKindCode": "GZ_CGY",
"workKindName": "仓管员",
"isSpec": 0,
"idCard": {
"memberId": "1674348283581112321",
"name": "张妹春",
"cardNo": "230281196910179732",
"sex": "男",
"clan": "土族",
"birthday": "1969-10-17",
"age": 53,
"issuingAuthority": "",
"validityStart": "",
"validityEnd": "",
"address": "香港特别行政区北镇县秀英长春路y座",
"cardFront": "",
"cardEnd": "",
"avatar": ""
},
"supplier": {
"id": "1674345370494054401",
"createTime": "2023-06-29 17:14:14",
"updateTime": "2023-06-29 17:14:14",
"companyName": "测试公司",
"shortName": "",
"companyType": "CONSTRUCTION_UNIT",
"businessLicense": "993101016769636918",
"legalPerson": "张三",
"legalIdcard": "",
"bank": "",
"bankCardNumber": "",
"bankNumber": "",
"projectId": "99000022",
"projectName": "佛山陈村旧改项目",
"companyId": "1674345370041069569",
"entryStatus": 1,
"contractName": "",
"contractUrl": "",
"supplierType": "",
"outsourcerId": "",
"outsourcerName": "",
"inGroup": "0",
"tenantId": "",
"inTime": "2023-06-29 17:13:39",
"outTime": ""
},
"team": {
"id": "1674347643433529346",
"createTime": "2023-06-29 17:23:15",
"updateTime": "2023-06-29 17:23:15",
"name": "铝模",
"teamLibraryId": "1674347643160899585",
"projectId": "99000022",
"supplyId": "1674345370494054401",
"memberId": "",
"memberName": "",
"memberIdcard": "",
"memberPhone": "",
"principal": "",
"principalIdcard": "",
"principalPhone": "",
"status": "0",
"member": null,
"contractName": "",
"contractUrl": "",
"supplier": null
},
"memberInfo": {
"memberId": "1674348283581112321",
"education": "其他",
"political": "其他",
"maritalStatus": "UM",
"emergencyContact1": "KIRA",
"emergencyPhone1": "18222222222",
"emergencyContact2": "",
"emergencyPhone2": ""
},
"laborContractInfo": {
"memberId": "1674348283581112321",
"contractType": "劳动合同",
"singingDate": "",
"validityStart": "",
"validityEnd": "",
"contractAttachment": "",
"contractAttachmentName": "",
"attachments": []
},
"certInfo": {
"createTime": "2023-06-29 17:25:13",
"updateTime": "2023-06-29 17:43:13",
"memberId": "1674348283581112321",
"certName": "注册会计师",
"certNameCode": "",
"validityStart": "2023-06-30",
"validityEnd": "2023-07-01",
"certTypeName": "",
"certTypeCode": "",
"certCategory": "1",
"certNo": "900000000",
"certPhoto": "https://bimuse.bzlrobot.com/bsp/test/opi/document/v1/document/fileStore/viewPicture/4cc4ac79ddda4b7ebdc9ca1d8a1ee38b",
"certPhotoFileName": "一个TCP 连接可以发送多少个HTTP请求.png",
"issuingAuthority": "中国政府"
},
"specialCertInfo": {
"createTime": "2023-06-29 17:25:13",
"updateTime": "2023-06-29 17:43:13",
"memberId": "1674348283581112321",
"certName": "",
"certNameCode": "",
"validityStart": "2023-06-29",
"validityEnd": "",
"certTypeName": "",
"certTypeCode": "",
"certCategory": "2",
"certNo": "",
"certPhoto": "",
"certPhotoFileName": "",
"issuingAuthority": ""
},
"safeTrainingInfo": {
"createTime": "2023-06-29 17:25:13",
"updateTime": "2023-06-29 17:43:13",
"memberId": "1674348283581112321",
"trainingType": "SAFE",
"trainingDate": "2023-06-29",
"trainingPhoto": "https://bimuse.bzlrobot.com/bsp/test/opi/document/v1/document/fileStore/viewPicture/2ef488193b9d4a38bca6aca918ae17ce",
"trainingPhotoFileName": "一等奖-幼儿园公开课-小白鱼过生日.png"
},
"bankCardInfo": {
"memberId": "1674348283581112321",
"bankName": "中国农业银行",
"accountBank": "银行沪杭",
"cardNo": "9092324234",
"cardPhoto": "https://bimuse.bzlrobot.com/bsp/test/opi/document/v1/document/fileStore/viewPicture/7934b54c857a43098e9590a51d5c2a2b",
"cardPhotoFileName": "一个TCP 连接可以发送多少个HTTP请求.png",
"status": 0
},
"healthInfo": {
"createTime": "2023-06-29 17:25:13",
"updateTime": "2023-06-29 17:43:13",
"memberId": "1674348283581112321",
"laborId": "230281196910179732",
"laborName": "张妹春",
"deviceId": "",
"projectId": "99000022",
"healthStatus": "其他",
"height": "180",
"weight": "60",
"bmi": "500",
"systolicPressure": "39",
"diastolicPressure": "500",
"pulse": "187",
"temperature": "40",
"tempvType": "",
"tempvUnit": "",
"glu": "500",
"sao2": "98",
"fatMass": "",
"fatRate": "",
"fatFreeMass": "",
"moistureMass": "",
"moistureRate": "",
"skeletonMass": "",
"muscleMass": "",
"extracellularFluid": "",
"intracellularFluid": "",
"proteinMass": "",
"mineralsMass": "",
"other": "",
"basalMetabolism": "",
"fatAdjust": "",
"muscleAdjust": "",
"isHistory": 0,
"isMajorDiseases": "1",
"isPurchaseInsurance": "0",
"inspectTime": "2023-06-21",
"actionType": "",
"fileName": "一等奖-幼儿园公开课-小白鱼过生日.png",
"filePath": "https://bimuse.bzlrobot.com/bsp/test/opi/document/v1/document/fileStore/viewPicture/b3884269188641ab97c4b80b51e3667a"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\r\n \"account\": \"18127813600\",\r\n \"password\": \"WD6Y0+LJLHXuFaplzUtSCnwktA7KgXCpjCS+OVvIFGTEoz2gbqK2oOOuJUf7ao0m2YYGiGi1pQTMBnkrxIY1cztGYbVp97kvIQwZLN4UhrOAe3h1asY/NLnDwB/byl7agcGv9WI4oy6B1Z93HVHmQiAKn7QqnDgPVITu4jthNc8=\"\r\n}",
"raw": "{\r\n \"account\": \"181200\",\r\n \"password\": \"WD6YB1ZhNc8=\"\r\n}",
"options": {
"raw": {
"language": "json"
@ -42,498 +42,11 @@
"{{url}}"
],
"path": [
"bsp",
"test",
"user",
"ugs",
"auth",
"loginByNotBip"
]
}
},
"response": []
},
{
"name": "获取需求采购列表(默认条件查询-成功)",
"event": [
{
"listen": "prerequest",
"script": {
"exec": [
""
],
"type": "text/javascript"
}
},
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"assert_code\", function () {\r",
" let body = JSON.parse(pm.request.body.raw)\r",
" body_code = body.code\r",
" let res = pm.response.json()\r",
" for (let i of res.data.records) {\r",
" pm.expect(i.orderCode, \"不包含0003\").to.include(body_code)\r",
" }\r",
" let requireId = res.data.records[0].id\r",
" pm.environment.set(\"requireId\", requireId)\r",
"})"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "BSP_TOKEN",
"value": "{{bsToken}}",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\r\n \"ncCode\": \"\",\r\n \"applyTimeBegin\": \"\",\r\n \"applyTimeEnd\": \"\",\r\n \"applyUserName\": \"\",\r\n \"auditStatus\": \"\",\r\n \"buildingCode\": \"\",\r\n \"code\": \"RE202210270003\",\r\n \"name\": \"\",\r\n \"purchaseType\": \"\",\r\n \"size\": 10,\r\n \"current\": 1,\r\n \"projectId\": \"104966\"\r\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{url}}/bsp/test/user/ugs/ibs/api/ibs-material/material/jobRequire/pages?t=1681310676000",
"host": [
"{{url}}"
],
"path": [
"bsp",
"test",
"user",
"ugs",
"ibs",
"api",
"ibs-material",
"material",
"jobRequire",
"pages"
],
"query": [
{
"key": "t",
"value": "1681310676000"
}
]
}
},
"response": []
},
{
"name": "获取请购详情",
"request": {
"method": "GET",
"header": [
{
"key": "BSP_TOKEN",
"value": "aba920e63584c3b1fef3cb4c498bca44",
"type": "text"
}
],
"url": {
"raw": "https://bimdc.bzlrobot.com/bsp/test/user/ugs/ibs/api/ibs-material/material/jobRequire/detail?t=&isEdit=&requireId=5804&projectId=",
"protocol": "https",
"host": [
"bimdc",
"bzlrobot",
"com"
],
"path": [
"bsp",
"test",
"user",
"ugs",
"ibs",
"api",
"ibs-material",
"material",
"jobRequire",
"detail"
],
"query": [
{
"key": "t",
"value": ""
},
{
"key": "isEdit",
"value": ""
},
{
"key": "requireId",
"value": "5804"
},
{
"key": "projectId",
"value": ""
}
]
}
},
"response": []
},
{
"name": "文件上传",
"request": {
"method": "POST",
"header": [
{
"key": "Accept",
"value": "*/*"
},
{
"key": "Accept-Language",
"value": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"
},
{
"key": "Connection",
"value": "keep-alive"
},
{
"key": "Cookie",
"value": "sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%221876a7f1e0f1368-09fbff283e5df9-4c657b58-2073600-1876a7f1e10e86%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E5%BC%95%E8%8D%90%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Flogin.countrygarden.com.cn%2F%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTg3NmE3ZjFlMGYxMzY4LTA5ZmJmZjI4M2U1ZGY5LTRjNjU3YjU4LTIwNzM2MDAtMTg3NmE3ZjFlMTBlODYifQ%3D%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%221876a7f1e0f1368-09fbff283e5df9-4c657b58-2073600-1876a7f1e10e86%22%7D; x-access-token=9f576f5f914c6e29584f82e5c5fe9c92"
},
{
"key": "Origin",
"value": "https://bimdc.bzlrobot.com"
},
{
"key": "Sec-Fetch-Dest",
"value": "empty"
},
{
"key": "Sec-Fetch-Mode",
"value": "cors"
},
{
"key": "Sec-Fetch-Site",
"value": "same-origin"
},
{
"key": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.0.0"
},
{
"key": "app_token",
"value": "A4C419A561A3404A86A33628A3F681C3"
},
{
"key": "sec-ch-ua",
"value": "\"Not/A)Brand\";v=\"99\", \"Microsoft Edge\";v=\"115\", \"Chromium\";v=\"115\""
},
{
"key": "sec-ch-ua-mobile",
"value": "?0"
},
{
"key": "sec-ch-ua-platform",
"value": "\"Windows\""
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "test.jpeg"
}
]
},
"url": {
"raw": "https://bimdc.bzlrobot.com/bsp/opi/document/v1/document/fileStore/uploadFile",
"protocol": "https",
"host": [
"bimdc",
"bzlrobot",
"com"
],
"path": [
"bsp",
"opi",
"document",
"v1",
"document",
"fileStore",
"uploadFile"
]
}
},
"response": []
},
{
"name": "https://bimdc.bzlrobot.com/bsp/opi/document/v1/document/fileStore/uploadFile",
"request": {
"method": "POST",
"header": [
{
"key": "Accept",
"value": "*/*"
},
{
"key": "Accept-Language",
"value": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"
},
{
"key": "Connection",
"value": "keep-alive"
},
{
"key": "Cookie",
"value": "sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%221876a7f1e0f1368-09fbff283e5df9-4c657b58-2073600-1876a7f1e10e86%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E5%BC%95%E8%8D%90%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Flogin.countrygarden.com.cn%2F%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTg3NmE3ZjFlMGYxMzY4LTA5ZmJmZjI4M2U1ZGY5LTRjNjU3YjU4LTIwNzM2MDAtMTg3NmE3ZjFlMTBlODYifQ%3D%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%22%2C%22value%22%3A%22%22%7D%2C%22%24device_id%22%3A%221876a7f1e0f1368-09fbff283e5df9-4c657b58-2073600-1876a7f1e10e86%22%7D; x-access-token=9f576f5f914c6e29584f82e5c5fe9c92"
},
{
"key": "Origin",
"value": "https://bimdc.bzlrobot.com"
},
{
"key": "Sec-Fetch-Dest",
"value": "empty"
},
{
"key": "Sec-Fetch-Mode",
"value": "cors"
},
{
"key": "Sec-Fetch-Site",
"value": "same-origin"
},
{
"key": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.0.0"
},
{
"key": "app_token",
"value": "A4C419A561A3404A86A33628A3F681C3"
},
{
"key": "sec-ch-ua",
"value": "\"Not/A)Brand\";v=\"99\", \"Microsoft Edge\";v=\"115\", \"Chromium\";v=\"115\""
},
{
"key": "sec-ch-ua-mobile",
"value": "?0"
},
{
"key": "sec-ch-ua-platform",
"value": "\"Windows\""
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/C:/Users/chenyongzhi11/Desktop/微信图片_20221025174254.jpg"
}
]
},
"url": {
"raw": "https://bimdc.bzlrobot.com/bsp/opi/document/v1/document/fileStore/uploadFile",
"protocol": "https",
"host": [
"bimdc",
"bzlrobot",
"com"
],
"path": [
"bsp",
"opi",
"document",
"v1",
"document",
"fileStore",
"uploadFile"
]
}
},
"response": []
},
{
"name": "平台登录",
"event": [
{
"listen": "test",
"script": {
"exec": [
""
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "username",
"value": "admin",
"type": "text"
},
{
"key": "password",
"value": "3306",
"type": "text"
},
{
"key": "csrfmiddlewaretoken",
"value": "av1VLobtvmrqvvoDRygqIqBr8QOa2ExxzcB1zVpHRKXXvOtoDzhmuLapxdP8uJj7",
"type": "text"
}
]
},
"url": {
"raw": "http://127.0.0.1:8000/index/",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"index",
""
]
}
},
"response": []
},
{
"name": "新增项目",
"request": {
"method": "POST",
"header": [
{
"key": "Cookie",
"value": "sessionid=zjs3ytyud4hh952ongttt6vvx3fihlqv",
"type": "text"
}
],
"body": {
"mode": "urlencoded",
"urlencoded": []
},
"url": {
"raw": "http://127.0.0.1:8000/project/create_project/",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"project",
"create_project",
""
]
}
},
"response": []
},
{
"name": "查询项目列表信息",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://127.0.0.1:8000/project/get_projects/",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"project",
"get_projects",
""
]
}
},
"response": []
},
{
"name": "新增模块",
"request": {
"method": "POST",
"header": [
{
"key": "Cookie",
"value": "sessionid=zjs3ytyud4hh952ongttt6vvx3fihlqv",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "",
"options": {
"raw": {
"language": "html"
}
}
},
"url": {
"raw": "http://127.0.0.1:8000/module/create_modul/",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"module",
"create_modul",
""
]
}
},
"response": []
},
{
"name": "查询模块列表",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://127.0.0.1:8000/module/get_module/",
"protocol": "http",
"host": [
"127",
"0",
"0",
"1"
],
"port": "8000",
"path": [
"module",
"get_module",
""
]
}
},
"response": []
}
]
}

View File

@ -14,80 +14,80 @@ import paho.mqtt.client as mqtt
class MQTTClient:
def __init__(self, broker_address, topic):
self.broker_address = broker_address
self.topic = topic
def on_connect(self, client, userdata, flags, rc):
print("Connected with result code " + str(rc))
def on_publish(self, client, userdata, mid):
print("Message " + str(mid) + " published.")
def send_message(self, message):
client = mqtt.Client()
client.on_connect = self.on_connect
client.on_publish = self.on_publish
client.connect(self.broker_address)
client.loop_start()
client.publish(self.topic, json.dumps(message))
client.loop_stop()
def __init__(self, broker_address, topic):
self.broker_address = broker_address
self.topic = topic
def on_connect(self, client, userdata, flags, rc):
print("Connected with result code " + str(rc))
def on_publish(self, client, userdata, mid):
print("Message " + str(mid) + " published.")
def send_message(self, message):
client = mqtt.Client()
client.on_connect = self.on_connect
client.on_publish = self.on_publish
client.connect(self.broker_address)
client.loop_start()
client.publish(self.topic, json.dumps(message))
client.loop_stop()
msg = {
"datapoint": [
{
"value": "492875336",
"type": "string",
"index": "0"
},
{
"value": "2023-04-24T15:48:33.128Z",
"type": "string",
"index": "6"
},
{
"value": 0,
"type": "byte",
"index": "7"
},
{
"value": "11132.00",
"type": "float",
"index": "8"
},
{
"index": "11",
"type": "string",
"value": "粤EJC5V3"
},
{
"index": "12",
"type": "string",
"value": "1"
},
{
"index": "13",
"type": "string",
"value": "http://192.1.14.19/document/fileStore/viewPicture/08188228a79b42ffa6b32a85f08b38ba"
},
{
"index": "14",
"type": "string",
"value": "https://ibs-test.bzlrobot.com/dfs/get?fileName=In-rear-pic.jpg&group=group1&path=M00/0A/4F/CgjLoWDiwteEBoWJAAAAANRLO4A310.jpg"
},
{
"index": "18",
"type": "string",
"value": "20230423174821"
}
],
"from_id": "492875336",
"msg_id": "1682243313128531625",
"time": "2023-04-23T19:48:33.128Z",
"type": "SYNC"
"datapoint": [
{
"value": "492875336",
"type": "string",
"index": "0"
},
{
"value": "2023-04-24T15:48:33.128Z",
"type": "string",
"index": "6"
},
{
"value": 0,
"type": "byte",
"index": "7"
},
{
"value": "11132.00",
"type": "float",
"index": "8"
},
{
"index": "11",
"type": "string",
"value": "粤EJC5V3"
},
{
"index": "12",
"type": "string",
"value": "1"
},
{
"index": "13",
"type": "string",
"value": "/08188228a72a85f08b38ba"
},
{
"index": "14",
"type": "string",
"value": "/CgjLoBoA310.jpg"
},
{
"index": "18",
"type": "string",
"value": "20230423174821"
}
],
"from_id": "492875336",
"msg_id": "1682243313128531625",
"time": "2023-04-23T19:48:33.128Z",
"type": "SYNC"
}
if __name__ == '__main__':
p = sys.argv[0]
rab = MQTTClient(broker_address='192.2.3.59', topic='weigh/492875336/rtdata')
rab.send_message(msg)
p = sys.argv[0]
rab = MQTTClient(broker_address='1.2.3.4', topic='9999999')
rab.send_message(msg)

View File

@ -13,111 +13,111 @@ import pika
class RabbitMQClient:
def __init__(self, host, queue_name=None, exchange_name=None, exchange_type=None, routing_key=None):
"""
RabbitMQClient 类的构造函数AMQP 协议默认
参数
- host: RabbitMQ 服务器的主机地址
- queue_name: 队列名称如果指定了该参数则消息将被发送到指定的队列
- exchange_name: 主题交换机名称如果指定了该参数则消息将被发送到指定的主题交换机
- exchange_type: 主题交换机类型如果指定了 exchange_name 参数则必须指定此参数例如'direct' 'topic'
- routing_key: 路由键如果指定了 exchange_name 参数则必须指定此参数路由键用于将消息路由到特定的队列
"""
self.host = host
self.queue_name = queue_name
self.exchange_name = exchange_name
self.exchange_type = exchange_type
self.routing_key = routing_key
self.connection = None
self.channel = None
def connect(self):
"""
连接到 RabbitMQ 服务器并根据需要声明队列和交换机
"""
# 连接到 RabbitMQ 服务器
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host))
self.channel = self.connection.channel()
# 如果指定了 exchange_name 参数,则声明主题交换机
if self.exchange_name:
self.channel.exchange_declare(exchange=self.exchange_name, exchange_type=self.exchange_type)
# 如果指定了 queue_name 参数,则声明队列,并将其绑定到主题交换机上
if self.queue_name:
self.channel.queue_declare(queue=self.queue_name)
if self.exchange_name:
self.channel.queue_bind(queue=self.queue_name, exchange=self.exchange_name,
routing_key=self.routing_key)
def send_message(self, message):
"""
发送一条消息到指定的队列或主题
参数
- message: 要发送的消息
"""
# 如果指定了 queue_name 参数,则将消息发送到指定的队列
if self.queue_name:
self.channel.basic_publish(exchange='', routing_key=self.queue_name, body=message)
# 如果指定了 exchange_name 参数,则将消息发送到指定的主题交换机
elif self.exchange_name:
self.channel.basic_publish(exchange=self.exchange_name, routing_key=self.routing_key,
body=message)
def close(self):
"""
关闭与 RabbitMQ 的连接
"""
self.connection.close()
def __init__(self, host, queue_name=None, exchange_name=None, exchange_type=None, routing_key=None):
"""
RabbitMQClient 类的构造函数AMQP 协议默认
参数
- host: RabbitMQ 服务器的主机地址
- queue_name: 队列名称如果指定了该参数则消息将被发送到指定的队列
- exchange_name: 主题交换机名称如果指定了该参数则消息将被发送到指定的主题交换机
- exchange_type: 主题交换机类型如果指定了 exchange_name 参数则必须指定此参数例如'direct' 'topic'
- routing_key: 路由键如果指定了 exchange_name 参数则必须指定此参数路由键用于将消息路由到特定的队列
"""
self.host = host
self.queue_name = queue_name
self.exchange_name = exchange_name
self.exchange_type = exchange_type
self.routing_key = routing_key
self.connection = None
self.channel = None
def connect(self):
"""
连接到 RabbitMQ 服务器并根据需要声明队列和交换机
"""
# 连接到 RabbitMQ 服务器
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host))
self.channel = self.connection.channel()
# 如果指定了 exchange_name 参数,则声明主题交换机
if self.exchange_name:
self.channel.exchange_declare(exchange=self.exchange_name, exchange_type=self.exchange_type)
# 如果指定了 queue_name 参数,则声明队列,并将其绑定到主题交换机上
if self.queue_name:
self.channel.queue_declare(queue=self.queue_name)
if self.exchange_name:
self.channel.queue_bind(queue=self.queue_name, exchange=self.exchange_name,
routing_key=self.routing_key)
def send_message(self, message):
"""
发送一条消息到指定的队列或主题
参数
- message: 要发送的消息
"""
# 如果指定了 queue_name 参数,则将消息发送到指定的队列
if self.queue_name:
self.channel.basic_publish(exchange='', routing_key=self.queue_name, body=message)
# 如果指定了 exchange_name 参数,则将消息发送到指定的主题交换机
elif self.exchange_name:
self.channel.basic_publish(exchange=self.exchange_name, routing_key=self.routing_key,
body=message)
def close(self):
"""
关闭与 RabbitMQ 的连接
"""
self.connection.close()
if __name__ == '__main__':
msg = {
"datapoint": [
{
"value": "492875336",
"type": "string",
"index": "0"
},
{
"value": "2023-04-23T17:48:33.128Z",
"type": "string",
"index": "6"
},
{
"value": 0,
"type": "byte",
"index": "7"
},
{
"value": "11132.00",
"type": "float",
"index": "8"
},
{
"index": "11",
"type": "string",
"value": "粤EJC5V3"
},
{
"index": "12",
"type": "string",
"value": "1"
},
{
"index": "18",
"type": "string",
"value": "20230423174821"
}
],
"from_id": "492875336",
"msg_id": "1682243313128531625",
"time": "2023-04-23T17:48:33.128Z",
"type": "SYNC"
}
rab = RabbitMQClient(host='192.1.1.59:1883', exchange_name='/bridge/492/rtdata',
# exchange_type='topic',
# routing_key='connected'
)
rab.send_message(json.dumps(msg))
msg = {
"datapoint": [
{
"value": "492875336",
"type": "string",
"index": "0"
},
{
"value": "2023-04-23T17:48:33.128Z",
"type": "string",
"index": "6"
},
{
"value": 0,
"type": "byte",
"index": "7"
},
{
"value": "11132.00",
"type": "float",
"index": "8"
},
{
"index": "11",
"type": "string",
"value": "粤EJC5V3"
},
{
"index": "12",
"type": "string",
"value": "1"
},
{
"index": "18",
"type": "string",
"value": "20230423174821"
}
],
"from_id": "492875336",
"msg_id": "1682243313128531625",
"time": "2023-04-23T17:48:33.128Z",
"type": "SYNC"
}
rab = RabbitMQClient(host='1.1.1.9:18', exchange_name='/rtdata',
# exchange_type='topic',
# routing_key='connected'
)
rab.send_message(json.dumps(msg))

View File

@ -3,11 +3,12 @@
# -------------------------------------------------------------------------------
# Name: bif_datetime.py
# Description:
# Author: chenyongzhi
# Author: kira
# EMAIL: 262667641@qq.com
# Date: 2021/1/12 14:03
# -------------------------------------------------------------------------------
from datetime import datetime, timedelta
from common.bif_functions import logger
__all__ = ['get_current_date', 'get_current_time', 'get_delta_time']
@ -15,46 +16,46 @@ __all__ = ['get_current_date', 'get_current_time', 'get_delta_time']
@logger.log_decorator()
def get_current_date(fmt="%Y-%m-%d"):
"""
获取当前日期默认格式为%Y-%m-%d
Args:
fmt: 日期格式
Returns:
"""
return datetime.now().strftime(fmt)
"""
获取当前日期默认格式为%Y-%m-%d
Args:
fmt: 日期格式
Returns:
"""
return datetime.now().strftime(fmt)
@logger.log_decorator()
def get_current_time(fmt="%Y-%m-%d %H:%M:%S"):
"""
获取当前时间默认格式为%Y-%m-%d %H:%M:%S
Args:
fmt: 时间格式
Returns:
"""
return datetime.now().strftime(fmt)
"""
获取当前时间默认格式为%Y-%m-%d %H:%M:%S
Args:
fmt: 时间格式
Returns:
"""
return datetime.now().strftime(fmt)
@logger.log_decorator()
def get_delta_time(days=0, hours=0, minutes=0, seconds=0, fmt="%Y-%m-%d %H:%M:%S"):
"""
获取当前时间指定间隔后的时间
Args:
days:距离当前时间多少天
hours:距离当前时间多少时
minutes:距离当前时间多少分
seconds: 距离当前时间多少秒
fmt: 时间格式
Returns:
"""
return (datetime.now() + timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)).strftime(fmt)
"""
获取当前时间指定间隔后的时间
Args:
days:距离当前时间多少天
hours:距离当前时间多少时
minutes:距离当前时间多少分
seconds: 距离当前时间多少秒
fmt: 时间格式
Returns:
"""
return (datetime.now() + timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)).strftime(fmt)
if __name__ == '__main__':
get_delta_time(4)
get_delta_time(4)

View File

@ -16,17 +16,17 @@ from common.bif_functions import logger
@logger.log_decorator()
def md5_encryption(raw_str, sha_str='', toupper=False):
"""
执行md5加密
Args:
raw_str: 原始字符串
sha_str: md5加密的盐值
toupper: 是否将加密后的结果转大写
Returns: 经md5加密后的字符串
"""
md5_obj = hashlib.md5(sha_str.encode('utf-8'))
md5_obj.update(str(raw_str).encode('utf-8'))
encrypted_str = md5_obj.hexdigest().upper() if toupper else md5_obj.hexdigest()
return encrypted_str
"""
执行md5加密
Args:
raw_str: 原始字符串
sha_str: md5加密的盐值
toupper: 是否将加密后的结果转大写
Returns: 经md5加密后的字符串
"""
md5_obj = hashlib.md5(sha_str.encode('utf-8'))
md5_obj.update(str(raw_str).encode('utf-8'))
encrypted_str = md5_obj.hexdigest().upper() if toupper else md5_obj.hexdigest()
return encrypted_str

View File

@ -3,7 +3,7 @@
# -------------------------------------------------------------------------------
# Name: bif_json.py
# Description:
# Author: chenyongzhi
# Author: kira
# EMAIL: 262667641@qq.com
# Date: 2021/1/12 14:02
# -------------------------------------------------------------------------------
@ -16,25 +16,25 @@ __all__ = ['json_dumps', 'json_loads']
@logger.log_decorator()
def json_dumps(obj):
"""
Serialize ``obj`` to a JSON formatted ``str``.
Args:
obj:
Returns:
"""
return json.dumps(obj, ensure_ascii=False)
"""
Serialize ``obj`` to a JSON formatted ``str``.
Args:
obj:
Returns:
"""
return json.dumps(obj, ensure_ascii=False)
@logger.log_decorator()
def json_loads(obj):
"""
Deserialize ``obj`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object.
Args:
obj:
Returns:
"""
return json.loads(obj)
"""
Deserialize ``obj`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object.
Args:
obj:
Returns:
"""
return json.loads(obj)

View File

@ -3,7 +3,7 @@
# -------------------------------------------------------------------------------
# Name: bif_list.py
# Description:
# Author: chenyongzhi
# Author: kira
# EMAIL: 262667641@qq.com
# Date: 2021/1/12 15:15
# -------------------------------------------------------------------------------
@ -14,65 +14,65 @@ __all__ = ['list_slice', 'sublist']
@logger.log_decorator()
def list_slice(obj, index=None, start=None, end=None, step=1):
"""
切片方法
Args:
obj:
index: 索引
start: 开始索引
end: 结束索引不含
step: 步长
Returns:
"""
if isinstance(obj, (str, tuple, list)):
if index is not None:
try:
return obj[index]
except IndexError:
return
else:
return obj[start:end:step]
return None
"""
切片方法
Args:
obj:
index: 索引
start: 开始索引
end: 结束索引不含
step: 步长
Returns:
"""
if isinstance(obj, (str, tuple, list)):
if index is not None:
try:
return obj[index]
except IndexError:
return
else:
return obj[start:end:step]
return None
@logger.log_decorator()
def sublist(raw_list, start=None, end=None):
"""
截取子列表
Args:
raw_list: 原始列表
start: 字符串开始位置
end: 字符串结束位置
Returns: 截取的字符串或子列表
"""
if isinstance(raw_list, (str, list)) and isinstance(start, (int, str)) and isinstance(end, (int, str)):
try:
start = int(start) if isinstance(start, str) and start.isdigit() else start
end = int(end) if isinstance(end, str) and end.isdigit() else end
if isinstance(raw_list, str):
return list(raw_list[start:end])
else:
return raw_list[start:end]
except TypeError:
pass
return []
"""
截取子列表
Args:
raw_list: 原始列表
start: 字符串开始位置
end: 字符串结束位置
Returns: 截取的字符串或子列表
"""
if isinstance(raw_list, (str, list)) and isinstance(start, (int, str)) and isinstance(end, (int, str)):
try:
start = int(start) if isinstance(start, str) and start.isdigit() else start
end = int(end) if isinstance(end, str) and end.isdigit() else end
if isinstance(raw_list, str):
return list(raw_list[start:end])
else:
return raw_list[start:end]
except TypeError:
pass
return []
if __name__ == '__main__':
# lst = [1, 2, 3, 4, 5]
# print(list_slice(lst, index=2)) # 3
# print(list_slice(lst, start=1, end=4)) # [2, 3, 4]
# print(list_slice(lst, start=1, end=4, step=2)) # [2, 4]
# print(list_slice(123)) # None
raw_list = ['a', 'b', 'c', 'd', 'e']
print(sublist(raw_list, start=1, end=4)) # ['b', 'c', 'd']
print(sublist(raw_list, start='1', end='4')) # ['b', 'c', 'd']
print(sublist(raw_list, start='x', end='4')) # []
print(sublist(raw_list, start=1, end=10)) # ['b', 'c', 'd', 'e']
print(sublist('abcdef', start=1, end=4)) # ['b', 'c', 'd']
print(sublist(123, start=1, end=4)) # []
# lst = [1, 2, 3, 4, 5]
# print(list_slice(lst, index=2)) # 3
# print(list_slice(lst, start=1, end=4)) # [2, 3, 4]
# print(list_slice(lst, start=1, end=4, step=2)) # [2, 4]
# print(list_slice(123)) # None
raw_list = ['a', 'b', 'c', 'd', 'e']
print(sublist(raw_list, start=1, end=4)) # ['b', 'c', 'd']
print(sublist(raw_list, start='1', end='4')) # ['b', 'c', 'd']
print(sublist(raw_list, start='x', end='4')) # []
print(sublist(raw_list, start=1, end=10)) # ['b', 'c', 'd', 'e']
print(sublist('abcdef', start=1, end=4)) # ['b', 'c', 'd']
print(sublist(123, start=1, end=4)) # []

View File

@ -3,7 +3,7 @@
# -------------------------------------------------------------------------------
# Name: bif_random.py
# Description:
# Author: chenyongzhi
# Author: kira
# EMAIL: 262667641@qq.com
# Date: 2021/1/12 14:02
# -------------------------------------------------------------------------------
@ -17,38 +17,38 @@ __all__ = ['random_choice', 'gen_random_num', 'gen_random_str']
@logger.log_decorator()
def random_choice(args):
"""
随机选择
Args:
args:
Returns:
"""
return random.choice(args)
"""
随机选择
Args:
args:
Returns:
"""
return random.choice(args)
@logger.log_decorator()
def gen_random_num(length):
"""
随机生成指定长度的数字
Args:
length: 指定长度
Returns:
"""
return random.randint(int('1' + '0' * (length - 1)), int('9' * length))
"""
随机生成指定长度的数字
Args:
length: 指定长度
Returns:
"""
return random.randint(int('1' + '0' * (length - 1)), int('9' * length))
@logger.log_decorator()
def gen_random_str(length):
"""
生成指定长度的随机字符串
Args:
length: 指定长度
Returns:
"""
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
"""
生成指定长度的随机字符串
Args:
length: 指定长度
Returns:
"""
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

View File

@ -17,25 +17,25 @@ __all__ = ['regex_extract']
@logger.log_decorator()
def regex_extract(string, pattern, group=None):
"""
根据正则表达式提取内容
Args:
string: 字符串
pattern: 正则表达式
group: 分组组号
Returns:
"""
if not isinstance(string, str):
string = json.dumps(string, ensure_ascii=False)
re_obj = re.search(pattern, string)
result = None
if re_obj:
result = re_obj.group(0)
if group:
try:
result = re_obj.group(group)
except IndexError:
pass
return result
"""
根据正则表达式提取内容
Args:
string: 字符串
pattern: 正则表达式
group: 分组组号
Returns:
"""
if not isinstance(string, str):
string = json.dumps(string, ensure_ascii=False)
re_obj = re.search(pattern, string)
result = None
if re_obj:
result = re_obj.group(0)
if group:
try:
result = re_obj.group(group)
except IndexError:
pass
return result

View File

@ -16,48 +16,48 @@ logger = MyLogger()
@logger.log_decorator()
def substr(raw_str, start=None, end=None):
"""
截取字符串
Args:
raw_str: 原始字符串
start: 字符串开始位置
end: 字符串结束位置
Returns: 截取的字符串
"""
try:
start = int(start) if (isinstance(start, str) and start.isdigit()) else start
end = int(end) if (isinstance(end, str) and end.isdigit()) else end
return raw_str[start:end]
except TypeError as e:
return ''
"""
截取字符串
Args:
raw_str: 原始字符串
start: 字符串开始位置
end: 字符串结束位置
Returns: 截取的字符串
"""
try:
start = int(start) if (isinstance(start, str) and start.isdigit()) else start
end = int(end) if (isinstance(end, str) and end.isdigit()) else end
return raw_str[start:end]
except TypeError as e:
return ''
@logger.log_decorator()
def str_join(obj, connector=","):
"""
连接任意数量的字符
Args:
obj: 被连接对象类型listtuple
connector: 连接符
Returns:
"""
if not isinstance(connector, str):
connector = str(connector)
if isinstance(obj, str):
return obj
elif isinstance(obj, (list, tuple)):
temp_obj = []
for item in obj:
if not isinstance(item, str):
item = str(item)
temp_obj.append(item)
return connector.join(temp_obj)
"""
连接任意数量的字符
Args:
obj: 被连接对象类型listtuple
connector: 连接符
Returns:
"""
if not isinstance(connector, str):
connector = str(connector)
if isinstance(obj, str):
return obj
elif isinstance(obj, (list, tuple)):
temp_obj = []
for item in obj:
if not isinstance(item, str):
item = str(item)
temp_obj.append(item)
return connector.join(temp_obj)
if __name__ == '__main__':
substr()
str_join()
substr()
str_join()

View File

@ -16,45 +16,47 @@ __all__ = ['get_timestamp', 'ms_fmt_hms']
@logger.log_decorator("错误原因时间戳的长度只能在10到16位之间默认返回长度为13位的时间戳")
def get_timestamp(length=13):
"""
获取时间戳字符串长度最多为16位默认13位
Args:
length: 时间戳长度
Returns:
"""
if isinstance(length, (int,)) and 10 <= length <= 16:
power = length - 10
timestamp = time.time()
return int(timestamp * 10 ** power)
else:
get_timestamp(13)
"""
获取时间戳字符串长度最多为16位默认13位
Returns:
Args:
length: 时间戳长度
Returns:
"""
if isinstance(length, (int,)) and 10 <= length <= 16:
power = length - 10
timestamp = time.time()
return int(timestamp * 10 ** power)
else:
get_timestamp(13)
@logger.log_decorator()
def ms_fmt_hms(ms):
"""
将毫秒转换成 h:m:s.ms格式字符串
Args:
ms:
Returns:
"""
ms = int(ms)
sec = ms // 1000
hour = sec // 3600
minute = (sec - hour * 3600) // 60
sec = sec % 60
ms = ms % 1000
hour = str(hour).rjust(2, '0')
minute = str(minute).rjust(2, '0')
sec = str(sec).rjust(2, '0')
ms = str(ms).rjust(2, '0')
return f"{hour}:{minute}:{sec}.{ms}"
"""
将毫秒转换成 h:m:s.ms格式字符串
Args:
ms: 毫秒
Returns:
"""
ms = int(ms)
sec = ms // 1000
hour = sec // 3600
minute = (sec - hour * 3600) // 60
sec = sec % 60
ms = ms % 1000
hour = str(hour).rjust(2, '0')
minute = str(minute).rjust(2, '0')
sec = str(sec).rjust(2, '0')
ms = str(ms).rjust(2, '0')
return f"{hour}:{minute}:{sec}.{ms}"
if __name__ == '__main__':
get_timestamp()
get_timestamp()

View File

@ -1,4 +1,12 @@
# -*- coding: utf-8 -*-
# coding: utf-8
# -------------------------------------------------------------------------------
# Name: bif_time.py
# Description:
# Author: kira
# EMAIL: 262667641@qq.com
# Date: 2021/1/12 14:03
# -------------------------------------------------------------------------------
import datetime
import math
import random
@ -6,109 +14,109 @@ import random
from faker import Faker
__all__ = [
'random_phone', 'random_gps',
"random_string", "random_ssn",
"random_email", "random_id_card",
"random_int", "random_male_name",
"random_female_name", "random_current_time"
'random_phone', 'random_gps',
"random_string", "random_ssn",
"random_email", "random_id_card",
"random_int", "random_male_name",
"random_female_name", "random_current_time"
]
f = Faker(locale='Zh-CN')
def random_gps(base_log=None, base_lat=None, radius=None):
"""
"""
Args:
base_log:
base_lat:
radius:
Returns:
"""
radius_in_degrees = radius / 111300
u = float(random.uniform(0.0, 1.0))
v = float(random.uniform(0.0, 1.0))
w = radius_in_degrees * math.sqrt(u)
t = 2 * math.pi * v
x = w * math.cos(t)
y = w * math.sin(t)
longitude = y + base_log
latitude = x + base_lat
# 这里是想保留6位小数点
loga = '%.6f' % longitude
lat = '%.6f' % latitude
return loga, lat
Args:
base_log:
base_lat:
radius:
Returns:
"""
radius_in_degrees = radius / 111300
u = float(random.uniform(0.0, 1.0))
v = float(random.uniform(0.0, 1.0))
w = radius_in_degrees * math.sqrt(u)
t = 2 * math.pi * v
x = w * math.cos(t)
y = w * math.sin(t)
longitude = y + base_log
latitude = x + base_lat
# 这里是想保留6位小数点
loga = '%.6f' % longitude
lat = '%.6f' % latitude
return loga, lat
def random_string():
"""
:return:随机生成字符串,20
"""
return f.pystr()
"""
:return:随机生成字符串,20
"""
return f.pystr()
def random_ssn():
"""
:return:随机生成省份中
"""
return f.ssn()
"""
:return:随机生成省份中
"""
return f.ssn()
def random_phone(self) -> int:
"""
:return: 随机生成手机号码
"""
return f.phone_number()
"""
:return: 随机生成手机号码
"""
return f.phone_number()
def random_id_card(self) -> int:
"""
"""
:return: 随机生成身份证号码
"""
return f.ssn()
:return: 随机生成身份证号码
"""
return f.ssn()
def random_female_name(self) -> str:
"""
"""
:return: 女生姓名
"""
return f.name_male()
:return: 女生姓名
"""
return f.name_male()
def random_male_name(self) -> str:
"""
"""
:return: 男生姓名
"""
return f.name_female()
:return: 男生姓名
"""
return f.name_female()
def random_email() -> str:
"""
"""
:return: 生成邮箱
"""
return f.email()
:return: 生成邮箱
"""
return f.email()
def random_current_time() -> datetime.datetime:
"""
计算当前时间
:return:
"""
return datetime.datetime.now()
"""
计算当前时间
:return:
"""
return datetime.datetime.now()
def random_int():
"""随机生成 0 - 9999 的数字"""
return f.random_int()
"""随机生成 0 - 9999 的数字"""
return f.random_int()
if __name__ == '__main__':
print(random_current_time())
print(random_current_time())

View File

@ -9,32 +9,37 @@
"""
from common.crypto import logger
from common.crypto.encryption_rsa import Rsa
# from common.crypto.encryption_aes import DoAES
from extensions import sign
@logger.log_decorator()
class EncryptData:
def encrypts(self, headers_crypto, headers, request_data_crypto, request_data):
encryption_methods = {
"MD5": sign.md5_sign,
"sha1": sign.sha1_sign,
"rsa": lambda data: Rsa(data).rsa_encrypt()
}
if headers_crypto:
encrypt_func = encryption_methods.get(headers_crypto)
if encrypt_func:
try:
headers = encrypt_func(headers)
except Exception as e:
logger.error(f"{headers_crypto} 加密失败:{e}")
if request_data_crypto:
encrypt_func = encryption_methods.get(request_data_crypto)
if encrypt_func:
try:
request_data = encrypt_func(request_data)
except Exception as e:
logger.error(f"{request_data_crypto} 加密失败:{e}")
return headers, request_data
"""
数据加密入口
"""
def encrypts(self, headers_crypto, headers, request_data_crypto, request_data):
encryption_methods = {
"MD5": sign.md5_sign,
"sha1": sign.sha1_sign,
"rsa": lambda data: Rsa(data).rsa_encrypt()
}
if headers_crypto:
encrypt_func = encryption_methods.get(headers_crypto)
if encrypt_func:
try:
headers = encrypt_func(headers)
except Exception as e:
logger.error(f"{headers_crypto} 加密失败:{e}")
if request_data_crypto:
encrypt_func = encryption_methods.get(request_data_crypto)
if encrypt_func:
try:
request_data = encrypt_func(request_data)
except Exception as e:
logger.error(f"{request_data_crypto} 加密失败:{e}")
return headers, request_data

View File

@ -41,7 +41,7 @@ class DoAES:
if __name__ == '__main__':
# key = os.urandom(16) #随即产生n个字节的字符串可以作为随机加密key使用
key = '2l4LoWczlWxlMZJAAp5N0g6EygZZd9A6' # 随即产生n个字节的字符串可以作为随机加密key使用
key = '2l4LoWczlWxlMZJAAp5N0g6EygZZd9C6' # 随即产生n个字节的字符串可以作为随机加密key使用
text = '4534' # 需要加密的内容
aes_test = DoAES(key)
cipher_text = aes_test.encrypt(text)

File diff suppressed because one or more lines are too long

View File

@ -8,10 +8,9 @@
@desc:
"""
import hashlib
import base64
import binascii
import rsa
import hashlib
from pyDes import des, CBC, PAD_PKCS5
@ -20,117 +19,117 @@ from pyDes import des, CBC, PAD_PKCS5
def bs64_data_encode(st):
"""
base64 加密
Args:
st:
Returns:
"""
return base64.b64encode(st.encode("utf-8"))
"""
base64 加密
Args:
st:
Returns:
"""
return base64.b64encode(st.encode("utf-8"))
def bs64_data_decode(st):
"""
base64 解密
Args:
st:
Returns:
"""
return base64.b64decode(st).decode()
"""
base64 解密
Args:
st:
Returns:
"""
return base64.b64decode(st).decode()
def md5(st: str) -> str:
"""
"""
Args:
st:待加密字符串
Returns: 返回MD5 加密后的字符串
"""
md = hashlib.md5() # 创建MD5对象
md.update(st.encode(encoding="utf-8"))
return md.hexdigest()
Args:
st:待加密字符串
Returns: 返回MD5 加密后的字符串
"""
md = hashlib.md5() # 创建MD5对象
md.update(st.encode(encoding="utf-8"))
return md.hexdigest()
def sha1_secret_str(st):
"""
使用sha1加密算法返回str加密后的字符串
Args:
st:
Returns:
"""
sha = hashlib.sha1(st.encode("utf-8"))
return sha.hexdigest()
"""
使用sha1加密算法返回str加密后的字符串
Args:
st:
Returns:
"""
sha = hashlib.sha1(st.encode("utf-8"))
return sha.hexdigest()
def sha256_single(st):
"""
sha256加密
Args:
st: 加密字符串
Returns:加密结果转换为16进制字符串并大写
"""
sha_obj = hashlib.sha256()
sha_obj.update(st.encode("utf-8"))
return sha_obj.hexdigest().upper()
"""
sha256加密
Args:
st: 加密字符串
Returns:加密结果转换为16进制字符串并大写
"""
sha_obj = hashlib.sha256()
sha_obj.update(st.encode("utf-8"))
return sha_obj.hexdigest().upper()
class Des:
def __init__(self, text, key):
self.text = text # 原始字符串
self.KEY = key # 这个key是固定问开发
def des_encrypt(self):
"""DES 加密
Returns:加密后字符串16进制
"""
secret_key = self.KEY # 密码
iv = secret_key # 偏移
# secret_key:加密密钥CBC:加密模式iv:偏移, padmode:填充
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
# 返回为字节
secret_bytes = des_obj.encrypt(self.text.encode("utf-8"), padmode=PAD_PKCS5)
# 返回为16进制
return binascii.b2a_hex(secret_bytes)
def des_decrypt(self):
"""
DES 解密
Returns:解密后的字符串
"""
secret_key = self.KEY
iv = secret_key
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
decrypt_str = des_obj.decrypt(binascii.a2b_hex(self.text), padmode=PAD_PKCS5)
return bytes.decode(decrypt_str) # bytes.decode() 将bit转为str
def __init__(self, text, key):
self.text = text # 原始字符串
self.KEY = key # 这个key是固定问开发
def des_encrypt(self):
"""DES 加密
Returns:加密后字符串16进制
"""
secret_key = self.KEY # 密码
iv = secret_key # 偏移
# secret_key:加密密钥CBC:加密模式iv:偏移, padmode:填充
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
# 返回为字节
secret_bytes = des_obj.encrypt(self.text.encode("utf-8"), padmode=PAD_PKCS5)
# 返回为16进制
return binascii.b2a_hex(secret_bytes)
def des_decrypt(self):
"""
DES 解密
Returns:解密后的字符串
"""
secret_key = self.KEY
iv = secret_key
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
decrypt_str = des_obj.decrypt(binascii.a2b_hex(self.text), padmode=PAD_PKCS5)
return bytes.decode(decrypt_str) # bytes.decode() 将bit转为str
def add_to_16(text: str):
"""
使用空格补足16位数
Args:
text:源字符串
Returns:补位后字符串
"""
b_text = text.encode("utf-8")
add = 0
# 计算需要补的位数
if len(b_text) % 16:
add = 16 - len(b_text) % 16
return b_text + b'\0' * add
"""
使用空格补足16位数
Args:
text:源字符串
Returns:补位后字符串
"""
b_text = text.encode("utf-8")
add = 0
# 计算需要补的位数
if len(b_text) % 16:
add = 16 - len(b_text) % 16
return b_text + b'\0' * add
# class AesEcb:
#

View File

@ -3,7 +3,6 @@
# @Author : kira
# @Email : 262667641@qq.com
# @File : analysis_json.py
# @Project : risk_api_project
"""
接口返回的数据是 列表字典
新建两个函数 A B函数 A 处理字典数据被调用后判断传循环嵌套 格式的通过一个 key 获取到被包裹了多层的目标数据

View File

@ -3,7 +3,6 @@
# @Author : kira
# @Email : 262667641@qq.com
# @File : assert_dict.py
# @Project : risk_api_project
import sys
sys.path.append("../")
@ -14,103 +13,103 @@ from common.utils.singleton import singleton
@singleton
class AssertDict(object):
@staticmethod
def is_contain(expect_result, response_result):
"""
Args:
response_result:
expect_result:
expect_result:
"""
assert expect_result.items() <= response_result.items()
@staticmethod
def assert_value(expect_result, response_result):
"""
:param expect_result: 预期结果
:param response_result: 响应结果
:return:
"""
contain_expect_key_dict = [] # 所有预期结果的字典key
expect_value_list = [] # 所有预期结果的字典value
tmp_list = []
need_search_key = []
res_list = {}
for key, value in expect_result.items():
expect_value_list.append(value)
need_search_key.append(key)
for expect_value in need_search_key:
# 接收由预期key在实际响应中的所有值,返回的是一个[]
try:
contain_expect_key_dict = (AnalysisJson().get_target_value(
expect_value, response_result, tmp_list))
except Exception as identifier:
print("查找值异常:{}".format(contain_expect_key_dict))
raise identifier
for each_value in expect_value_list:
# 判断是否每一个由预期结果组成的列表中每一个值都存在由预期key组成的实际结果列表中
try:
if each_value in contain_expect_key_dict:
res_list["${}".format(each_value)] = True
else:
res_list["${}".format(each_value)] = False
except Exception as e:
print("字典的key异常{}".format(each_value))
raise e
if False in res_list.values():
flag = 0
else:
flag = 1
return flag, res_list
@staticmethod
def is_contain(expect_result, response_result):
"""
Args:
response_result:
expect_result:
expect_result:
"""
assert expect_result.items() <= response_result.items()
@staticmethod
def assert_value(expect_result, response_result):
"""
:param expect_result: 预期结果
:param response_result: 响应结果
:return:
"""
contain_expect_key_dict = [] # 所有预期结果的字典key
expect_value_list = [] # 所有预期结果的字典value
tmp_list = []
need_search_key = []
res_list = {}
for key, value in expect_result.items():
expect_value_list.append(value)
need_search_key.append(key)
for expect_value in need_search_key:
# 接收由预期key在实际响应中的所有值,返回的是一个[]
try:
contain_expect_key_dict = (AnalysisJson().get_target_value(
expect_value, response_result, tmp_list))
except Exception as identifier:
print("查找值异常:{}".format(contain_expect_key_dict))
raise identifier
for each_value in expect_value_list:
# 判断是否每一个由预期结果组成的列表中每一个值都存在由预期key组成的实际结果列表中
try:
if each_value in contain_expect_key_dict:
res_list["${}".format(each_value)] = True
else:
res_list["${}".format(each_value)] = False
except Exception as e:
print("字典的key异常{}".format(each_value))
raise e
if False in res_list.values():
flag = 0
else:
flag = 1
return flag, res_list
if __name__ == '__main__':
first = {
"data": [{
"saleRatio": "14.29",
"weekDate": "2021-04-15"
}, {
"weekDate": "2021-04-16",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-17",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-18",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-19",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-20",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-21",
"saleRatio": "14.29"
}],
"status": 200
}
second = {"data": [{
"weekDate": "2021-04-19",
"saleRatio": "14.29"
}], "status": 200}
expect = {
"status": "success",
"code": 200,
"message": "OK"
}
response = {
"status": "success",
"code": 200,
"message": "OK",
"data": {
"id": 123,
"name": "John"
}
}
print(AssertDict().assert_value(second, first))
print(AssertDict().assert_value(expect, response))
first = {
"data": [{
"saleRatio": "14.29",
"weekDate": "2021-04-15"
}, {
"weekDate": "2021-04-16",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-17",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-18",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-19",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-20",
"saleRatio": "14.29"
}, {
"weekDate": "2021-04-21",
"saleRatio": "14.29"
}],
"status": 200
}
second = {"data": [{
"weekDate": "2021-04-19",
"saleRatio": "14.29"
}], "status": 200}
expect = {
"status": "success",
"code": 200,
"message": "OK"
}
response = {
"status": "success",
"code": 200,
"message": "OK",
"data": {
"id": 123,
"name": "John"
}
}
print(AssertDict().assert_value(second, first))
print(AssertDict().assert_value(expect, response))

View File

@ -1,7 +1,7 @@
# -*- coding:utf-8 -*-
"""
Time: 2020/6/1/001 15:29
Author: 陈勇志
Author: kira
Email:262667641@qq.com
Project:api_project
"""
@ -15,135 +15,137 @@ from jsonpath_ng import parse
from common.variables import Variables
from common.data_extraction import logger
# from common.http_client.http_client import Pyt
REPLACE_DICT = {
"null": None,
"True": True,
"false": False
"null": None,
"True": True,
"false": False
}
# d = Variables()
class DataExtractor(Variables):
def __init__(self):
super().__init__()
# self.PATTERN = getattr(Variables, "PATTERN") # 预编译正则表达式
@logger.log_decorator("提取参数出现了意想不到的错误!!")
def substitute_data(self, response, regex=None, keys=None, deps=None, jp_dict=None):
"""
方法接收一个正则表达式 regex 和一个关联参数表 deps用于从接口返回的数据中提取关联参数
它会从接口返回的数据中使用正则表达式 regex 和正则表达式返回结果的键列表 keys 提取数据并将其更新到关联参数表中
然后它会使用 subs_deps subs_lists 方法提取更多的关联参数最后它将更新后的关联参数表设置为 Variables 类的静态变量并将其返回
Args:
response: 被提取数据对象
regex: 正则表达式 r'"id": (\d+), "name": "(\w+)",'
keys: 接收正则表达式返回结果的key ["a", "b"]
deps: "name=data[0].name;ok=data[0].id;an=data[0].age[3].a"
jp_dict: jsonpath 提取方式入参{"k": "$.data", "x": "$.data[0].age[3].a"}
Returns:
"""
response = response
if not isinstance(response, (dict, str, list)):
logger.error(f"被提取对象非字典、非字符串、非列表不执行jsonpath提取被提取对象: {response}")
return {}
if regex and keys:
self.substitute_regex(response, regex, keys)
response = response if isinstance(response, (dict, list)) else json.loads(response)
if deps:
self.substitute_route(response, deps)
if jp_dict:
self.substitute_jsonpath(response, jp_dict)
def substitute_regex(self, response, regex, keys):
"""
方法用于使用正则表达式 regex 和正则表达式返回结果的键列表 keys 从接口返回的数据中提取数据并将其更新到关联参数表中
Args:
response:
regex: 正则表达式r'"id": (\d+), "name": "(\w+)",'
keys:结果键列表["a", "b"],
Returns:
"""
response = json.dumps(response) if isinstance(response, (dict, list)) else response
match = re.search(regex, response)
if not match:
return {}
groups = match.groups()
for i, key in enumerate(keys):
try:
self.update_variable(key, groups[i])
except:
self.update_variable(key, None)
def substitute_route(self, response, route_str):
deps_list = re.sub(f"[\r\n]+", "", route_str).split(";")
for dep_item in deps_list:
key, value_path = dep_item.split("=")
value_path_parts = re.findall(r'\w+', value_path)
temp = response
for part in value_path_parts:
if isinstance(temp, dict):
temp = temp.get(part)
elif isinstance(temp, list):
if part.isdigit():
index = int(part)
if index < len(temp):
temp = temp[index]
else:
temp = None
break
else:
temp = None
break
else:
temp = None
break
if isinstance(temp, (dict, list)):
continue
else:
break
if temp is not None:
self.update_variable(key, temp)
def substitute_jsonpath(self, response, json_path_dict):
"""
jsonpath 提取参数
Args:
response: 响应结果
json_path_dict: {"k": "$.data", "x": "$.data[0].age[3].a"}
Returns: 字符串或者list
"""
json_path_dict = json_path_dict if isinstance(json_path_dict, dict) else json.loads(json_path_dict)
for key, expression in json_path_dict.items():
try:
parsed_expression = parse(expression)
data = response
# 使用解析器对象进行匹配和提取
match = parsed_expression.find(data)
result = [m.value for m in match]
self.update_variable(key, result[0]) if len(result) == 1 else self.update_variable(key,
result)
except Exception as e:
logger.error(f"jsonpath表达式错误'{expression}': {e}")
def __init__(self):
super().__init__()
@logger.log_decorator("提取参数出现了意想不到的错误!!")
def substitute_data(self, response, regex=None, keys=None, deps=None, jp_dict=None):
"""
方法接收一个正则表达式 regex 和一个关联参数表 deps用于从接口返回的数据中提取关联参数
它会从接口返回的数据中使用正则表达式 regex 和正则表达式返回结果的键列表 keys 提取数据并将其更新到关联参数表中
然后它会使用 subs_deps subs_lists 方法提取更多的关联参数最后它将更新后的关联参数表设置为 Variables 类的静态变量并将其返回
Args:
response: 被提取数据对象
regex: 正则表达式 r'"id": (\d+), "name": "(\w+)",'
keys: 接收正则表达式返回结果的key ["a", "b"]
deps: "name=data[0].name;ok=data[0].id;an=data[0].age[3].a"
jp_dict: jsonpath 提取方式入参{"k": "$.data", "x": "$.data[0].age[3].a"}
Returns:
"""
response = response
if not isinstance(response, (dict, str, list)):
logger.error(f"被提取对象非字典、非字符串、非列表不执行jsonpath提取被提取对象: {response}")
return {}
if regex and keys:
self.substitute_regex(response, regex, keys)
response = response if isinstance(response, (dict, list)) else json.loads(response)
if deps:
self.substitute_route(response, deps)
if jp_dict:
self.substitute_jsonpath(response, jp_dict)
def substitute_regex(self, response, regex, keys):
"""
方法用于使用正则表达式 regex 和正则表达式返回结果的键列表 keys 从接口返回的数据中提取数据并将其更新到关联参数表中
Args:
response:
regex: 正则表达式r'"id": (\d+), "name": "(\w+)",'
keys:结果键列表["a", "b"],
Returns:
"""
response = json.dumps(response) if isinstance(response, (dict, list)) else response
match = re.search(regex, response)
if not match:
return {}
groups = match.groups()
for i, key in enumerate(keys):
try:
self.update_variable(key, groups[i])
except:
self.update_variable(key, None)
def substitute_route(self, response, route_str):
"""
想字典一样取值:name=data[0].name;ok=data[0].id;an=data[0].age
Args:
response:
route_str:
Returns:
"""
deps_list = re.sub(f"[\r\n]+", "", route_str).split(";")
for dep_item in deps_list:
key, value_path = dep_item.split("=")
value_path_parts = re.findall(r'\w+', value_path)
temp = response
for part in value_path_parts:
if isinstance(temp, dict):
temp = temp.get(part)
elif isinstance(temp, list):
if part.isdigit():
index = int(part)
if index < len(temp):
temp = temp[index]
else:
temp = None
break
else:
temp = None
break
else:
temp = None
break
if isinstance(temp, (dict, list)):
continue
else:
break
if temp is not None:
self.update_variable(key, temp)
def substitute_jsonpath(self, response, json_path_dict):
"""
jsonpath 提取参数
Args:
response: 响应结果
json_path_dict: {"k": "$.data", "x": "$.data[0].age[3].a"}
Returns: 字符串或者list
"""
json_path_dict = json_path_dict if isinstance(json_path_dict, dict) else json.loads(json_path_dict)
for key, expression in json_path_dict.items():
try:
parsed_expression = parse(expression)
data = response
# 使用解析器对象进行匹配和提取
match = parsed_expression.find(data)
result = [m.value for m in match]
self.update_variable(key, result[0]) if len(result) == 1 else self.update_variable(key,
result)
except Exception as e:
logger.error(f"jsonpath表达式错误'{expression}': {e}")
if __name__ == '__main__':
# 测试subs函数
res = '{"code": 1,"data": [{"id": 1, "name": "Alice", "age": [20, 21, 22, {"a": "b"}]}]}'
lists = {"k": "$..code", "x": "$.data[0].age[3].a"}
dep_str = "name=data[0].name;ok=data[0].id;an=data[0].age"
regex_str = r'"id": (\d+), "name": "(\w+)",'
regex_key = ["a", "b"]
t = DataExtractor()
t.substitute_data(res, regex=regex_str, keys=regex_key, deps=dep_str, jp_dict=lists)
print("-------->res:", t.get_variable())
# 测试subs函数
res = '{"code": 1,"data": [{"id": 1, "name": "Alice", "age": [20, 21, 22, {"a": "b"}]}]}'
lists = {"k": "$..code", "x": "$.data[0].age[3].a"}
dep_str = "name=data[0].name;ok=data[0].id;an=data[0].age"
regex_str = r'"id": (\d+), "name": "(\w+)",'
regex_key = ["a", "b"]
t = DataExtractor()
t.substitute_data(res, regex=regex_str, keys=regex_key, deps=dep_str, jp_dict=lists)
print("-------->res:", t.get_variable())

View File

@ -3,60 +3,59 @@
# @Author : kira
# @Email : 262667641@qq.com
# @File : dict_get.py
# @Project : api_project
def dict_get(dic, locators, default=None):
"""
以参数形式获取字典中特定的值
:param dic: 输入需要在其中取值的原始字典 <dict>
:param locators: 输入取值定位器, :['result', 'msg', '-1', 'status'] <list>
:param default: 进行取值中报错时所返回的默认值 (default: None)
:return: 返回根据参数locators找出的值
"""
if not isinstance(dic, dict) or not isinstance(locators, list):
return default
value = None
for locator in locators:
if not type(value) in [dict, list] and isinstance(locator, str) and not can_convert_to_int(locator):
try:
value = dic[locator]
except KeyError:
return default
continue
if isinstance(value, dict):
try:
value = dict_get(value, [locator])
except KeyError:
return default
continue
if isinstance(value, list) and can_convert_to_int(locator):
try:
value = value[int(locator)]
except IndexError:
return default
continue
return value
"""
以参数形式获取字典中特定的值
:param dic: 输入需要在其中取值的原始字典 <dict>
:param locators: 输入取值定位器, :['result', 'msg', '-1', 'status'] <list>
:param default: 进行取值中报错时所返回的默认值 (default: None)
:return: 返回根据参数locators找出的值
"""
if not isinstance(dic, dict) or not isinstance(locators, list):
return default
value = None
for locator in locators:
if not type(value) in [dict, list] and isinstance(locator, str) and not can_convert_to_int(locator):
try:
value = dic[locator]
except KeyError:
return default
continue
if isinstance(value, dict):
try:
value = dict_get(value, [locator])
except KeyError:
return default
continue
if isinstance(value, list) and can_convert_to_int(locator):
try:
value = value[int(locator)]
except IndexError:
return default
continue
return value
def can_convert_to_int(input_s):
try:
int(input_s)
return True
except Exception:
return False
try:
int(input_s)
return True
except Exception:
return False
if __name__ == '__main__':
# dict_test = {"result": {"code": "110002", "msg": [{'status': 'ok'}, {'status': 'failed'}]}}
# result = dict_get(dict_test, ['result', 'msg', '-1', 'status'])
dict_test = {
"data": {"result": [{"taskId": 1, "taskName": "2020-01-23 调研任务", "taskStatus": 2}], "totalCount": 1,
"pageSize": 20}, "taskId": 2, "msg": "操作成功!", "status": 200}
result = dict_get(dict_test, ['data', 'result', 0, 'taskId'])
print(result)
# dict_test = {"result": {"code": "110002", "msg": [{'status': 'ok'}, {'status': 'failed'}]}}
# result = dict_get(dict_test, ['result', 'msg', '-1', 'status'])
dict_test = {
"data": {"result": [{"taskId": 1, "taskName": "2020-01-23 调研任务", "taskStatus": 2}], "totalCount": 1,
"pageSize": 20}, "taskId": 2, "msg": "操作成功!", "status": 200}
result = dict_get(dict_test, ['data', 'result', 0, 'taskId'])
print(result)

View File

@ -8,43 +8,42 @@ from common.database import logger
@logger.log_decorator()
def execute_sql_files(sql_path, db_config):
"""
批量执行sql语句
Args:
sql_path:文件夹
db_config: 数据库配置
Returns:
"""
connection = pymysql.connect(**db_config)
try:
with connection.cursor() as cur:
# 获取指定目录下的所有SQL文件
sql_files = glob.glob(os.path.join(sql_path, "*.sql"))
for file in sql_files:
with open(file, "r", encoding="utf-8") as f:
sql_statements = f.read().strip().split(";")
for sql_statement in sql_statements:
if sql_statement:
cur.execute(sql_statement)
connection.commit()
finally:
connection.close()
"""
批量执行sql语句
Args:
sql_path:文件夹
db_config: 数据库配置
Returns:
"""
connection = pymysql.connect(**db_config)
try:
with connection.cursor() as cur:
# 获取指定目录下的所有SQL文件
sql_files = glob.glob(os.path.join(sql_path, "*.sql"))
for file in sql_files:
with open(file, "r", encoding="utf-8") as f:
sql_statements = f.read().strip().split(";")
for sql_statement in sql_statements:
if sql_statement:
cur.execute(sql_statement)
connection.commit()
finally:
connection.close()
if __name__ == '__main__':
config = {
"host": "xxxx.xxx.xxx.xx",
"port": 3306,
"database": "db_name",
"user": "root",
"password": "xxxx"
}
execute_sql_files('./sql.sql', config)
config = {
"host": "xxxx.xxx.xxx.xx",
"port": 3306,
"database": "db_name",
"user": "root",
"password": "xxxx"
}
execute_sql_files('./sql.sql', config)

View File

@ -19,151 +19,144 @@ from common.utils.singleton import singleton
@singleton
class MysqlClient:
def __init__(self, db_config):
"""
初始化连接配置
Args:
db_config: 数据库连接配置字典
{
"host": "xxxx.xxx.xxx.xx",
"port": 3306,
"database": "db_name",
"user": "root",
"password": "xxxx"
}
"""
if not db_config:
return
try:
self.db_base = db_config if isinstance(db_config, dict) else json.loads(db_config)
self.pool = PooledDB(creator=pymysql, maxconnections=10, **self.db_base)
except Exception as e:
logger.error(f"数据库链接失败: {e}")
raise
@logger.log_decorator()
def execute_sql(self, sql):
"""
执行 SQL 语句
Args:
sql: SQL 语句字典
{
"delete": {
"sql_name": "DELETE FROM table_name WHERE condition"
},
"update": {
"sql_name": "UPDATE table_name SET column1=value1 WHERE condition"
},
"insert": {
"sql_name": "INSERT INTO table_name (column1, column2) VALUES (value1, value2)"
},
"select": {
"sql_name": "SELECT * FROM table_name WHERE condition"
}
}
Returns:
执行结果字典
{
"sql_name": [result1, result2, ...]
}
"""
if not sql:
return
try:
conn = self.pool.connection()
cur = conn.cursor(DictCursor)
result = {}
for method, sql_data in sql.items():
execute_method = getattr(self, f"_execute_{method}", None)
if not execute_method:
logger.error("sql字典集编写格式不符合规范")
raise ValueError("Invalid SQL method")
execute_method(cur, sql_data, result)
cur.close()
conn.close()
return result
except Exception as e:
logger.error(f"数据库操作异常: {e}")
raise
def _execute_delete(self, cursor, sql_data, result):
"""
执行 DELETE 语句
"""
for sql_name, sql_ in sql_data.items():
try:
cursor.execute(str(sql_))
except Exception as err:
logger.error(f"执行 SQL 异常: {sql_}")
raise err
cursor.connection.commit()
def _execute_update(self, cursor, sql_data, result):
"""
执行 UPDATE 语句
"""
self.execute_delete(cursor, sql_data, result)
def _execute_insert(self, cursor, sql_data, result):
"""
执行 INSERT 语句
"""
self.execute_delete(cursor, sql_data, result)
def _execute_select(self, cursor, sql_data, result):
"""
执行 SELECT 语句
Args:
cursor: 数据库游标
sql_data: SQL 语句数据字典
{
"sql_name": "SELECT * FROM table_name WHERE condition"
}
result: 字典结果
Raises:
Exception: 执行异常
"""
for sql_name, sql_ in sql_data.items():
try:
cursor.execute(sql_)
result[sql_name] = cursor.fetchall()
except Exception as err:
logger.error(f"查询异常 sql: {sql_}")
raise err
def __init__(self, db_config):
"""
初始化连接配置
Args:
db_config: 数据库连接配置字典
"""
if not db_config:
return
try:
self.db_base = db_config if isinstance(db_config, dict) else json.loads(db_config)
self.pool = PooledDB(creator=pymysql, maxconnections=10, **self.db_base)
except Exception as e:
logger.error(f"数据库链接失败: {e}")
raise
@logger.log_decorator()
def execute_sql(self, sql):
"""
执行 SQL 语句
Args:
sql: SQL 语句字典
{
"delete": {
"sql_name": "DELETE FROM table_name WHERE condition"
},
"update": {
"sql_name": "UPDATE table_name SET column1=value1 WHERE condition"
},
"insert": {
"sql_name": "INSERT INTO table_name (column1, column2) VALUES (value1, value2)"
},
"select": {
"sql_name": "SELECT * FROM table_name WHERE condition"
}
}
Returns:
执行结果字典
{
"sql_name": [result1, result2, ...]
}
"""
if not sql:
return
try:
conn = self.pool.connection()
cur = conn.cursor(DictCursor)
result = {}
for method, sql_data in sql.items():
execute_method = getattr(self, f"_execute_{method}", None)
if not execute_method:
logger.error("sql字典集编写格式不符合规范")
raise ValueError("Invalid SQL method")
execute_method(cur, sql_data, result)
cur.close()
conn.close()
return result
except Exception as e:
logger.error(f"数据库操作异常: {e}")
raise
def _execute_delete(self, cursor, sql_data, result):
"""
执行 DELETE 语句
"""
for sql_name, sql_ in sql_data.items():
try:
cursor.execute(str(sql_))
except Exception as err:
logger.error(f"执行 SQL 异常: {sql_}")
raise err
cursor.connection.commit()
def _execute_update(self, cursor, sql_data, result):
"""
执行 UPDATE 语句
"""
self.execute_delete(cursor, sql_data, result)
def _execute_insert(self, cursor, sql_data, result):
"""
执行 INSERT 语句
"""
self.execute_delete(cursor, sql_data, result)
def _execute_select(self, cursor, sql_data, result):
"""
执行 SELECT 语句
Args:
cursor: 数据库游标
sql_data: SQL 语句数据字典
{
"sql_name": "SELECT * FROM table_name WHERE condition"
}
result: 字典结果
Raises:
Exception: 执行异常
"""
for sql_name, sql_ in sql_data.items():
try:
cursor.execute(sql_)
result[sql_name] = cursor.fetchall()
except Exception as err:
logger.error(f"查询异常 sql: {sql_}")
raise err
if __name__ == '__main__':
sql_2 = {
"select":
{
"select_sale": "select count(1) total, (case when t1.status = 1 then '待整改' when t1.status = 2 then '待复查' when t1.status = 3 then '整改完成' else '未知类型' end) orderStatus from ibs_ai_iot.ai_rectification_main t1 left join ibs_ai_iot.work_order t3 on t1.id = t3.rectification_id where t1.project_id = 103672 and t1.delete_flag = 0 and t3.is_delete = 0 group by t1.status order by orderStatus desc;",
"select_sale_1": "select count(1) total, (case when t1.status = 1 then '待整改' when t1.status = 2 then '待复查' when t1.status = 3 then '整改完成' else '未知类型' end) orderStatus from ibs_ai_iot.ai_rectification_main t1 left join ibs_ai_iot.work_order t3 on t1.id = t3.rectification_id where t1.project_id = 103672 and t1.delete_flag = 0 and t3.is_delete = 0 group by t1.status order by orderStatus desc;"
}
}
database_2 = {
"host": "10.8.203.25",
"port": 3306,
"database": "ibs_lms_base",
"user": "root",
"password": "gd1234"
}
res = MysqlClient(database_2).execute_sql(sql_2)
print("数据执行结果", res)
from common.data_extraction.data_extractor import DataExtractor
from common.variables import Variables
t = DataExtractor()
t.substitute_data(res, jp_dict={"total": "$.select_sale[0].total", "total_1": "$..total"})
print(Variables.get_variable())
sql_2 = {
"select":
{
"select_sale": "select count(1) total, (case when t1.status = 1 then '待整改' when t1.status = 2 then '待复查' when t1.status = 3 then '整改完成' else '未知类型' end) orderStatus from ibs_ai_iot.ai_rectification_main t1 left join ibs_ai_iot.work_order t3 on t1.id = t3.rectification_id where t1.project_id = 103672 and t1.delete_flag = 0 and t3.is_delete = 0 group by t1.status order by orderStatus desc;",
"select_sale_1": "select count(1) total, (case when t1.status = 1 then '待整改' when t1.status = 2 then '待复查' when t1.status = 3 then '整改完成' else '未知类型' end) orderStatus from ibs_ai_iot.ai_rectification_main t1 left join ibs_ai_iot.work_order t3 on t1.id = t3.rectification_id where t1.project_id = 103672 and t1.delete_flag = 0 and t3.is_delete = 0 group by t1.status order by orderStatus desc;"
}
}
database_2 = {
"host": "10.10.10.10",
"port": 3306,
"database": "base",
"user": "root",
"password": "roottttttttttttttttttttest"
}
res = MysqlClient(database_2).execute_sql(sql_2)
print("数据执行结果", res)
from common.data_extraction.data_extractor import DataExtractor
from common.variables import Variables
t = DataExtractor()
t.substitute_data(res, jp_dict={"total": "$.select_sale[0].total", "total_1": "$..total"})
print(Variables.get_variable())

View File

@ -8,83 +8,87 @@ import redis
class RedisClient:
def __init__(self):
self.redis = redis.Redis(host='10.8.203.25', port=6379, password='test2020')
def set_data(self, key, value, expire_time=None):
self.redis.set(key, value)
if expire_time is not None:
self.redis.expire(key, expire_time)
def get_data(self, key):
return self.redis.get(key)
def delete_data(self, key):
self.redis.delete(key)
def hash_set_field(self, key, field, value):
self.redis.hset(key, field, value)
def hash_get_field(self, key, field):
return self.redis.hget(key, field)
def hash_delete_field(self, key, field):
self.redis.hdel(key, field)
"""
redis数据库
"""
def __init__(self):
self.redis = redis.Redis(host='1.1.3.5', port=6379, password='test')
def set_data(self, key, value, expire_time=None):
self.redis.set(key, value)
if expire_time is not None:
self.redis.expire(key, expire_time)
def get_data(self, key):
return self.redis.get(key)
def delete_data(self, key):
self.redis.delete(key)
def hash_set_field(self, key, field, value):
self.redis.hset(key, field, value)
def hash_get_field(self, key, field):
return self.redis.hget(key, field)
def hash_delete_field(self, key, field):
self.redis.hdel(key, field)
if __name__ == '__main__':
# r = redis.Redis(host='10.8.203.25', port=6379, password='test2020')
# print(r.select(1)) # 切数据库1
# print(r.dbsize()) # 看 db 大小
#
# # 设置键为"key1"的字符串值为"Hello, Redis!"
# r.set('key1', 'Hello, Redis!')
#
# # 获取键为"key1"的字符串值
# value = r.get('key1')
# print(value) # 输出: b'Hello, Redis!'
#
# # 向名为"list1"的列表左侧插入元素
# r.lpush('list1', 'item1')
# r.lpush('list1', 'item2')
# r.lpush('list1', 'item3')
#
# # 获取名为"list1"的列表所有元素
# items = r.lrange('list1', 0, -1)
# print(items) # 输出: [b'item3', b'item2', b'item1']
#
# # 设置名为"hash1"的哈希表字段和值
# r.hset('hash1', 'field1', 'value1')
# r.hset('hash1', 'field2', 'value2')
#
# # 获取名为"hash1"的哈希表字段和值
# value1 = r.hget('hash1', 'field1')
# value2 = r.hget('hash1', 'field2')
# values = r.hgetall('hash1')
# print(value1, value2) # 输出: b'value1' b'value2
# print(values) # 输出:{b'field1': b'value1', b'field2': b'value2'}
#
# # 向名为"set1"的集合添加元素
# r.sadd('set1', 'item1')
# r.sadd('set1', 'item2')
# r.sadd('set1', 'item3')
#
# # 获取名为"set1"的集合所有元素
# items = r.smembers('set1')
# print(items) # 输出: {b'item1', b'item2', b'item3'}
redis_client = RedisClient()
redis_client.set_data('user1', '100', 3600)
def get_user_info(user_id):
cache_key = f'user1:{user_id}'
user_info = redis_client.get_data(cache_key)
if not user_info:
print("--")
print(f'{user_info}')
get_user_info(100)
# r = redis.Redis(host='10.8.203.25', port=6379, password='test2020')
# print(r.select(1)) # 切数据库1
# print(r.dbsize()) # 看 db 大小
#
# # 设置键为"key1"的字符串值为"Hello, Redis!"
# r.set('key1', 'Hello, Redis!')
#
# # 获取键为"key1"的字符串值
# value = r.get('key1')
# print(value) # 输出: b'Hello, Redis!'
#
# # 向名为"list1"的列表左侧插入元素
# r.lpush('list1', 'item1')
# r.lpush('list1', 'item2')
# r.lpush('list1', 'item3')
#
# # 获取名为"list1"的列表所有元素
# items = r.lrange('list1', 0, -1)
# print(items) # 输出: [b'item3', b'item2', b'item1']
#
# # 设置名为"hash1"的哈希表字段和值
# r.hset('hash1', 'field1', 'value1')
# r.hset('hash1', 'field2', 'value2')
#
# # 获取名为"hash1"的哈希表字段和值
# value1 = r.hget('hash1', 'field1')
# value2 = r.hget('hash1', 'field2')
# values = r.hgetall('hash1')
# print(value1, value2) # 输出: b'value1' b'value2
# print(values) # 输出:{b'field1': b'value1', b'field2': b'value2'}
#
# # 向名为"set1"的集合添加元素
# r.sadd('set1', 'item1')
# r.sadd('set1', 'item2')
# r.sadd('set1', 'item3')
#
# # 获取名为"set1"的集合所有元素
# items = r.smembers('set1')
# print(items) # 输出: {b'item1', b'item2', b'item3'}
redis_client = RedisClient()
redis_client.set_data('user1', '100', 3600)
def get_user_info(user_id):
cache_key = f'user1:{user_id}'
user_info = redis_client.get_data(cache_key)
if not user_info:
print("--")
print(f'{user_info}')
get_user_info(100)

View File

@ -29,36 +29,10 @@ class DoExcel:
# def __exit__(self, exc_type, exc_val, exc_tb):
# self.wb.save(self.file_name)
# self.wb.close()
@logger.log_decorator()
def do_excel(self):
"""
通过 title 定位单元格获取所有测试数据
Returns: 读取每一条测试用用例分别保存到字典中然后再将所有用例保存到列表中[{用例1},{用例2},{用例3}]
[{"":""},{},{}]
"""
sheets = eval(self.get_excel_init().get("sheets"))
test_data = []
for sheet_name in sheets: # 遍历存在配置文件里面的字典sheet_name == 每一个 excel 中的 sheetName
sheet = self.wb[sheet_name] # 获取所有 sheet 句柄
max_row = sheet.max_row # 获取最大行
max_column = sheet.max_column # 获取最大列
fist_header = [] # 获取第一行标题所有值
for i in range(1, max_column + 1):
fist_header.append(sheet.cell(1, i).value)
# 定位单元格
for i in range(2, max_row + 1):
sub_data = {} # 列表内的字典(也就是测试数据)
for k in range(1, max_column + 1):
sub_data[fist_header[k - 1]] = sheet.cell(i, k).value
sub_data["sheet"] = sheet_name
test_data.append(sub_data) # 将所有单元格 title 对应的值组成字典添加到列表中。
return test_data
# @logger.log_decorator()
def do_excel_yield(self):
"""
读取excel数据的生成器
读取excel数据
Returns:
"""

View File

@ -8,10 +8,8 @@ import json
import os
import sys
# 把当前目录加入到系统环境变量中
sys.path.append(os.path.split(os.path.dirname(os.path.abspath(__file__)))[0])
sys.path.append("../..")
# sys.path.append('venv/Lib/site-packages')
from openpyxl import load_workbook, Workbook
from common.file_handling import logger

View File

@ -16,156 +16,156 @@ import yaml
class FileUtils:
@staticmethod
def get_all_path(open_file_path):
"""
递归获取目录下所有的文件的路径
Args:
open_file_path: 指定目录路径
Returns:
包含所有文件路径的列表
"""
path_list = []
for root, dirs, files in os.walk(open_file_path):
path_list.extend([os.path.join(root, file) for file in files])
return path_list
@staticmethod
def get_files_in_folder(folder_path):
"""
获取指定文件夹内的所有文件
Args:
folder_path: 指定文件夹路径
Returns:
包含所有文件名的列表
"""
if not os.path.isdir(folder_path):
raise ValueError("Invalid folder path")
file_list = []
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
if os.path.isfile(file_path):
file_list.append(filename)
return file_list
@staticmethod
def get_folders_in_path(dir_path):
"""
获取指定路径下的所有文件夹
Args:
dir_path: 指定路径
Returns:
包含所有文件夹名的列表
"""
if not os.path.isdir(dir_path):
raise ValueError("Invalid directory path")
folder_list = []
for foldername in os.listdir(dir_path):
folder_path = os.path.join(dir_path, foldername)
if os.path.isdir(folder_path):
folder_list.append(foldername)
return folder_list
@staticmethod
def read_file(file_path):
"""
读取文件内容
Args:
file_path: 文件路径
Returns:
文件内容的字符串
"""
if not os.path.isfile(file_path):
raise ValueError("Invalid file path")
with open(file_path, "r", encoding="utf-8") as f:
return f.read()
@staticmethod
def read_json_file(file_path):
"""
读取 JSON 文件
Args:
file_path: JSON 文件路径
Returns:
解析后的 JSON 数据
"""
content = FileUtils.read_file(file_path)
try:
return json.loads(content)
except json.JSONDecodeError as e:
raise ValueError("Invalid JSON file: {}".format(e))
@staticmethod
def read_yaml_file(file_path):
"""
读取 YAML 文件
Args:
file_path: YAML 文件路径
Returns:
解析后的 YAML 数据
"""
with open(file_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
@staticmethod
def get_value_from_dict(data, key_path):
"""
从嵌套字典中获取指定键路径的值
Args:
data: 嵌套字典
key_path: 键路径可以是用点分隔的字符串或字符串列表
Returns:
指定键路径的值如果路径不存在则返回 None
"""
if isinstance(key_path, str):
key_path = key_path.split('.')
for key in key_path:
if isinstance(data, dict) and key in data:
data = data[key]
else:
return None
return data
@staticmethod
def read_config_data(file_path, section, option):
"""
读取配置文件中的数据
Args:
file_path: 配置文件路径
section: 文件中的 section
option: 文件中的 option
Returns:
配置文件中指定数据的值
"""
cf = RawConfigParser()
cf.read(file_path, encoding="UTF-8")
return eval(cf.get(section, option))
@staticmethod
def read_json_data(file_path):
"""
读取 JSON 文件中的数据
Args:
file_path: JSON 文件路径
Returns:
JSON 文件中的数据
"""
with open(file_path, "r", encoding="utf-8") as fb:
return json.load(fb)
@staticmethod
def get_all_path(open_file_path):
"""
递归获取目录下所有的文件的路径
Args:
open_file_path: 指定目录路径
Returns:
包含所有文件路径的列表
"""
path_list = []
for root, dirs, files in os.walk(open_file_path):
path_list.extend([os.path.join(root, file) for file in files])
return path_list
@staticmethod
def get_files_in_folder(folder_path):
"""
获取指定文件夹内的所有文件
Args:
folder_path: 指定文件夹路径
Returns:
包含所有文件名的列表
"""
if not os.path.isdir(folder_path):
raise ValueError("Invalid folder path")
file_list = []
for filename in os.listdir(folder_path):
file_path = os.path.join(folder_path, filename)
if os.path.isfile(file_path):
file_list.append(filename)
return file_list
@staticmethod
def get_folders_in_path(dir_path):
"""
获取指定路径下的所有文件夹
Args:
dir_path: 指定路径
Returns:
包含所有文件夹名的列表
"""
if not os.path.isdir(dir_path):
raise ValueError("Invalid directory path")
folder_list = []
for foldername in os.listdir(dir_path):
folder_path = os.path.join(dir_path, foldername)
if os.path.isdir(folder_path):
folder_list.append(foldername)
return folder_list
@staticmethod
def read_file(file_path):
"""
读取文件内容
Args:
file_path: 文件路径
Returns:
文件内容的字符串
"""
if not os.path.isfile(file_path):
raise ValueError("Invalid file path")
with open(file_path, "r", encoding="utf-8") as f:
return f.read()
@staticmethod
def read_json_file(file_path):
"""
读取 JSON 文件
Args:
file_path: JSON 文件路径
Returns:
解析后的 JSON 数据
"""
content = FileUtils.read_file(file_path)
try:
return json.loads(content)
except json.JSONDecodeError as e:
raise ValueError("Invalid JSON file: {}".format(e))
@staticmethod
def read_yaml_file(file_path):
"""
读取 YAML 文件
Args:
file_path: YAML 文件路径
Returns:
解析后的 YAML 数据
"""
with open(file_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
@staticmethod
def get_value_from_dict(data, key_path):
"""
从嵌套字典中获取指定键路径的值
Args:
data: 嵌套字典
key_path: 键路径可以是用点分隔的字符串或字符串列表
Returns:
指定键路径的值如果路径不存在则返回 None
"""
if isinstance(key_path, str):
key_path = key_path.split('.')
for key in key_path:
if isinstance(data, dict) and key in data:
data = data[key]
else:
return None
return data
@staticmethod
def read_config_data(file_path, section, option):
"""
读取配置文件中的数据
Args:
file_path: 配置文件路径
section: 文件中的 section
option: 文件中的 option
Returns:
配置文件中指定数据的值
"""
cf = RawConfigParser()
cf.read(file_path, encoding="UTF-8")
return eval(cf.get(section, option))
@staticmethod
def read_json_data(file_path):
"""
读取 JSON 文件中的数据
Args:
file_path: JSON 文件路径
Returns:
JSON 文件中的数据
"""
with open(file_path, "r", encoding="utf-8") as fb:
return json.load(fb)
if __name__ == '__main__':
fu = FileUtils()
rest = fu.read_yaml_file(r'../../config.yaml')
print(rest)
fu = FileUtils()
rest = fu.read_yaml_file(r'../../config.yaml')
print(rest)

View File

@ -1,37 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: get_init.py
@time: 2023/3/16 10:33
@desc:
"""
from common.file_handling.do_excel import DoExcel
from common.utils.logger import MyLog
@MyLog().decorator_log("读取excel中初始化数据异常")
def get_init(test_file):
"""
Returns:返回初始化数据及测试用例
"""
MyLog().my_log(f"读取测试用例excel文件{test_file}", "info")
excel_handle = DoExcel(test_file) # 实例化对象
try:
excel_handle.clear_date() # 清空 excel 中实际结果列的数据
# test_case = excel_handle.do_excel() # 获取 excel 中的测试用例
test_case = excel_handle.do_excel_yield() # 获取 excel 中的测试用例
init_data = excel_handle.get_excel_init() # 获取初始化基本数据
MyLog().my_log(f"如下是初始化得到得数据:{init_data}", "info")
except Exception as e:
raise e
return excel_handle, init_data, test_case
if __name__ == '__main__':
from common.config import Config
init = get_init(Config.test_case)
print(init)

View File

@ -10,90 +10,79 @@ sys.path.append("../")
sys.path.append("./common")
from common.http_client import logger
# from common.data_extraction.data_extractor import DataExtractor
# from common.data_extraction.dependent_parameter import DependentParameter
from common.validation.load_modules_from_folder import LoadModulesFromFolder
# @singleton
class Pyt(LoadModulesFromFolder):
# 类属性,保存一个会话对象,防止每次都创建一个新的会话,节省资源
session = requests.Session()
def __init__(self):
super().__init__()
self.request = None
self.response = None
# @staticmethod
def log_decorator(msg="请求异常"):
def decorator(func):
def wrapper(*args, **kwargs):
try:
print(f"发送请求的参数: {kwargs}")
response = func(*args, **kwargs)
print(f"请求地址 --> {response.request.url}")
print(f"请求头 --> {response.request.headers}")
print(f"请求 body --> {response.request.body}")
print(f"接口状态--> {response.status_code}")
print(f"接口耗时--> {response.elapsed}")
print(f"接口响应--> {response.text}")
return response
except Exception as e:
logger.error(f"发送请求失败: {e}")
return
return wrapper
return decorator
# @log_decorator()
def http_client(self, host, url, method, **kwargs):
"""
发送 http 请求
@param host: 域名
@param __url: 接口 __url
@param method: http 请求方法
# @param request_data_type: 请求数据类型
# @param headers: 请求头部信息,默认为 None
@param kwargs: 接受 requests 原生的关键字参数
@return: 响应对象
"""
# 关闭 https 警告信息
urllib3.disable_warnings()
if not url:
raise ValueError("URL cannot be None")
__url = f'{host}{url}' if not re.match(r"https?", url) else url
# 获取session 中的请求方法
# func = getattr(session, method.lower())
# 增加兼容
# 处理 headers 参数为字符串类型的情况
if 'headers' in kwargs and isinstance(kwargs['headers'], str):
kwargs['headers'] = json.loads(kwargs['headers'])
# 处理 json 参数为字符串类型的情况
if 'json' in kwargs and isinstance(kwargs['json'], str):
kwargs['json'] = json.loads(kwargs['json'])
# 发送请求
# return func(__url, verify=True, timeout=30, **kwargs)
self.request = requests.Request(method, __url, **kwargs)
self.response = self.session.send(self.request.prepare(), timeout=30, verify=True)
return self.response
# 类属性,保存一个会话对象,防止每次都创建一个新的会话,节省资源
session = requests.Session()
def __init__(self):
super().__init__()
self.request = None
self.response = None
# @staticmethod
def log_decorator(msg="请求异常"):
def decorator(func):
def wrapper(*args, **kwargs):
try:
print(f"发送请求的参数: {kwargs}")
response = func(*args, **kwargs)
print(f"请求地址 --> {response.request.url}")
print(f"请求头 --> {response.request.headers}")
print(f"请求 body --> {response.request.body}")
print(f"接口状态--> {response.status_code}")
print(f"接口耗时--> {response.elapsed}")
print(f"接口响应--> {response.text}")
return response
except Exception as e:
logger.error(f"发送请求失败: {e}")
return
return wrapper
return decorator
# @log_decorator()
def http_client(self, host, url, method, **kwargs):
"""
发送 http 请求
@param host: 域名
@param url: 接口 __url
@param method: http 请求方法
@param kwargs: 接受 requests 原生的关键字参数
@return: 响应对象
"""
# 关闭 https 警告信息
urllib3.disable_warnings()
if not url:
raise ValueError("URL cannot be None")
__url = f'{host}{url}' if not re.match(r"https?", url) else url
# 增加兼容
# 处理 headers 参数为字符串类型的情况
if 'headers' in kwargs and isinstance(kwargs['headers'], str):
kwargs['headers'] = json.loads(kwargs['headers'])
# 处理 json 参数为字符串类型的情况
if 'json' in kwargs and isinstance(kwargs['json'], str):
kwargs['json'] = json.loads(kwargs['json'])
# 发送请求
self.request = requests.Request(method, __url, **kwargs)
self.response = self.session.send(self.request.prepare(), timeout=30, verify=True)
return self.response
if __name__ == '__main__':
hst = 'https://ibs-test.bzlrobot.com'
url = '/api/ibs-auth/ibs_platform/login?t=168672334'
method = 'post'
kwargs = {
'json': '{"account": "luoshunwen005", "grantType": "password", "isBip": "false","password": "o+t2SnEEylblxlfIspJUvGFa0gCDNrU2dC34LjVFqIiTmxa855YDBE/6J7eRVBGaQwR7mozSKComk9n6kjSNRjSX1m574dRZdESIeYsmM/xk2Nt5n5dqB268qCMivJMXpHQMygpT4RpDiYoOiEqlOi9eG5G7v/5rixHiZ9xv98m34xVD1VdlaCbphoB9JI7T9HmVFJniSWt01ruC5t+aFUvfxLjOpRmYmfz8GwtSd5XXKaKr29ce1C39Fg+PtqOkQ3cOLVS9hXgzz6s2zud0++T4vwgVtrHx86aMrrozhCdKzrQuWPEO1cSsaEaNVdSUsT54je+4O+xKzxkJhoGMnQ=="}',
'headers': None}
pyt = Pyt()
pyt.http_client(hst, url, method, **kwargs)
# print(pyt.request.json)
# print(pyt.request.headers)
# print(pyt.response.text)
hst = 'https://baidu.com'
url = '/login?t=168672334'
method = 'post'
kwargs = {
'json': '{"account": "kira","password": "9999999"}',
'headers': None}
pyt = Pyt()
pyt.http_client(hst, url, method, **kwargs)

View File

@ -1,124 +0,0 @@
# -*- coding: utf-8 -*-
import json
import re
import sys
import requests
import urllib3
sys.path.append("../")
sys.path.append("./common")
from common.http_client import logger
# from common.data_extraction.data_extractor import DataExtractor
# from common.data_extraction.dependent_parameter import DependentParameter
from common.validation.load_modules_from_folder import LoadModulesFromFolder
# @singleton
class Pyt(LoadModulesFromFolder):
# 类属性,保存一个会话对象,防止每次都创建一个新的会话,节省资源
session = requests.Session()
def __init__(self):
super().__init__()
self.request = None
self.response = None
# @staticmethod
def log_decorator(msg="请求异常"):
def decorator(func):
def wrapper(*args, **kwargs):
try:
print(f"发送请求的参数: {kwargs}")
response = func(*args, **kwargs)
print(f"请求地址 --> {response.request.url}")
print(f"请求头 --> {response.request.headers}")
print(f"请求 body --> {response.request.body}")
print(f"接口状态--> {response.status_code}")
print(f"接口耗时--> {response.elapsed}")
print(f"接口响应--> {response.text}")
return response
except Exception as e:
logger.error(f"发送请求失败: {e}")
return
return wrapper
return decorator
def before_request(self, request, **kwargs):
item = kwargs.get("item")
# 拼接动态代码段文件
prepost_script = f"prepost_script_{item.get('sheet')}_{item.get('iid')}.py"
item = self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "setup", item)
# 替换 URL, PARAMETERS, HEADER,期望值
item = self.action.replace_dependent_parameter(item)
url, query_str, request_data, headers, expected, request_data_type = self.__request_info(item)
# 提取请求参数信息
self.action.substitute_data(request_data, jp_dict=jp_dict)
headers, request_data = self.action.encrypt.encrypts(headers_crypto, headers, request_crypto, request_data)
result_tuple = None
result = "PASS"
response = None
# 执行请求操作
kwargs = {
request_data_type: request_data,
'headers': headers
}
# @log_decorator()
def http_client(self, host, url, method, **kwargs):
"""
发送 http 请求
@param host: 域名
@param __url: 接口 __url
@param method: http 请求方法
# @param request_data_type: 请求数据类型
# @param headers: 请求头部信息,默认为 None
@param kwargs: 接受 requests 原生的关键字参数
@return: 响应对象
"""
# 关闭 https 警告信息
urllib3.disable_warnings()
if not url:
raise ValueError("URL cannot be None")
__url = f'{host}{url}' if not re.match(r"https?", url) else url
# 获取session 中的请求方法
# func = getattr(session, method.lower())
# 增加兼容
# 处理 headers 参数为字符串类型的情况
if 'headers' in kwargs and isinstance(kwargs['headers'], str):
kwargs['headers'] = json.loads(kwargs['headers'])
# 处理 json 参数为字符串类型的情况
if 'json' in kwargs and isinstance(kwargs['json'], str):
kwargs['json'] = json.loads(kwargs['json'])
# 发送请求
# return func(__url, verify=True, timeout=30, **kwargs)
self.request = requests.Request(method, __url, **kwargs)
self.response = self.session.send(self.request.prepare(), timeout=30, verify=True)
return self.response
if __name__ == '__main__':
hst = 'https://ibs-test.bzlrobot.com'
url = '/api/ibs-auth/ibs_platform/login?t=168672334'
method = 'post'
kwargs = {
'json': '{"account": "luoshunwen005", "grantType": "password", "isBip": "false","password": "o+t2SnEEylblxlfIspJUvGFa0gCDNrU2dC34LjVFqIiTmxa855YDBE/6J7eRVBGaQwR7mozSKComk9n6kjSNRjSX1m574dRZdESIeYsmM/xk2Nt5n5dqB268qCMivJMXpHQMygpT4RpDiYoOiEqlOi9eG5G7v/5rixHiZ9xv98m34xVD1VdlaCbphoB9JI7T9HmVFJniSWt01ruC5t+aFUvfxLjOpRmYmfz8GwtSd5XXKaKr29ce1C39Fg+PtqOkQ3cOLVS9hXgzz6s2zud0++T4vwgVtrHx86aMrrozhCdKzrQuWPEO1cSsaEaNVdSUsT54je+4O+xKzxkJhoGMnQ=="}',
'headers': None}
pyt = Pyt()
pyt.http_client(hst, url, method, **kwargs)
# print(pyt.request.json)
# print(pyt.request.headers)
# print(pyt.response.text)

View File

@ -1,55 +0,0 @@
import re
import requests
import urllib3
from common.http_client.request_hooks import Hooks
hooks = Hooks()
def req(host, url, method, **kwargs):
"""
发送 http 请求
@param host: 域名
@param url: 接口 url
@param method: http 请求方法
@param kwargs: 接受 requests 原生的关键字参数
@return: 响应对象
"""
# 关闭 https 警告信息
urllib3.disable_warnings()
session = requests.Session()
if not url:
raise ValueError("URL 不能为 None")
url = f'{host}{url}' if not re.match(r"https?", url) else url
# 执行 before_request 钩子函数
request = requests.Request(method, url, **kwargs)
request = hooks.run_before_request_funcs(request)
# 发送请求
prepared_request = session.prepare_request(request)
response = session.send(prepared_request)
# 执行 after_request 钩子函数
response = hooks.run_after_request_funcs(response)
return response
if __name__ == '__main__':
url = "https://ibs-test.bzlrobot.com/api/ibs-auth/ibs_platform/login?t=1686740475000"
payload = {
"grantType": "password",
"account": "luoshunwen005",
"password": "TTdNRuVHxmOI7P8G2yjrfRBaMyQzmy8XGzS1rvbV8X/WqQuJpTAVgTqTAkIswJ0xbGpA2rvoVRnsW3Dg+vmtiJrm/hNUmd7nRV42tMltWDzFAgCC4KOFBC1b+mRkACby+nuiS+N7J6xEAieXJXh6Ml5jWy9qbt2rziteB8npxsMsOygiuRpUmoSkHz8wshQGtqOAr9uQRhglNLJdLWzZtas6TQvypeOMOGSatA2arJ7ipGE3oW+AiATyDu22Eh+PBO+eR7wLWOyO2XxeWhK+5EGiiIVmKRyaMY3JedVHSjpnWmnZ1Vj9pZjUaenJQfCgSS5CBnxLX/AoxB5TvJmMEA==",
"isBip": False
}
headers = {
'Content-Type': 'application/json'
}
kg = {'json': payload, "headers": headers}
res = req("", url, 'post', **kg)
print(res, res.json())

View File

@ -8,7 +8,6 @@ class Hooks:
注册 before_request 钩子函数将其添加到 before_request_funcs 列表中
"""
self.before_request_funcs.append(func)
print(self.before_request_funcs)
return func
def after_request(self, func):
@ -16,7 +15,6 @@ class Hooks:
注册 after_request 钩子函数将其添加到 after_request_funcs 列表中
"""
self.after_request_funcs.append(func)
print(self.after_request_funcs)
return func
def run_before_request_funcs(self, request):

View File

@ -1,64 +0,0 @@
from common.data_extraction.dependent_parameter import DependentParameter
from common.crypto.encryption_main import do_encrypt
from common.http_client.request_hooks import Hooks
from common.utils.mylogger import MyLogger
dep_par = DependentParameter() # 参数提取类实例化
logger = MyLogger()
hooks = Hooks()
@logger.log_decorator()
@hooks.before_request
def update_url(request):
"""更新url"""
request.url = dep_par.replace_dependent_parameter(request.url)
print(request.url)
return request
@logger.log_decorator()
@hooks.before_request
def update_header(request):
"""更新请求头"""
request.headers = dep_par.replace_dependent_parameter(request.headers)
print(request.headers)
return request
@logger.log_decorator()
@hooks.before_request
def update_body(request):
"""更新请求参数"""
if request.json:
request.json = dep_par.replace_dependent_parameter(request.json)
if request.encryption:
request.data = do_encrypt(request.encryption, request.json) # 数据加密MD5  
else:
request.data = dep_par.replace_dependent_parameter(request.data)
if request.encryption:
request.data = do_encrypt(request.encryption, request.data) # 数据加密MD5  
return request
@logger.log_decorator()
@hooks.before_request
def update_expected(request):
"""更新预期结果"""
request.expected = dep_par.replace_dependent_parameter(request.expected)
print(request.expected)
return request
@logger.log_decorator()
@hooks.after_request
def parse_json(response):
"""
尝试将响应中的内容解析为 JSON 格式
"""
try:
response.json_data = response.json()
except ValueError:
response.json_data = None
return response

View File

@ -23,8 +23,7 @@ class WxWorkSms:
self.send_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={key}"
self.up_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={key}&type=file"
def send_markdown(self, project_name, project_port, total_cases, pass_rate, success_cases, fail_cases,
skip_cases,
def send_markdown(self, project_name, project_port, total_cases, pass_rate, success_cases, fail_cases, skip_cases,
error_cases, report_url):
"""
发送markdown 请求
@ -107,4 +106,4 @@ class WxWorkSms:
if __name__ == '__main__':
dirs = r'D:\apk_api\api-test-project\OutPut\Reports'
WxWorkSms('8b1647d4-dc32-447c-b524-548acf18a938').send_main(dirs, 2, 3, 4, 5, 6, 7, 8, 9, 10)
# WxWorkSms('8b1647d4-dc32-447c-b524-548acf18a938').send_markdown(1, 2, 3, 4, 5, 6, 7, 8, 9)
# WxWorkSms('8b1647d4-dc32-447c-b524-548acf18a938').send_markdown(1, 2, 3, 4, 5, 6, 7, 8, 9)

View File

@ -1,13 +0,0 @@
import time
from functools import wraps
def fn_time(func):
def inner(*args, **kwargs):
t0 = time.time()
func(*args, **kwargs)
t1 = time.time()
print(f"{func.__name__}总共运行:{str(t1 - t0)}")
# return func(*args, **kwargs)
return inner

View File

@ -17,14 +17,15 @@ class ScriptNotFoundError(Exception):
class LoadScript:
# @logger.log_decorator()
def load_script(self, script_path):
"""
加载脚本文件并返回模块对象
Args:
script_path (str): 脚本文件的路径
script_path (str): 脚本文件的路径
Returns:
module: 脚本文件对应的模块对象
module: 脚本文件对应的模块对象
"""
try:
spec = importlib.util.spec_from_file_location(os.path.basename(script_path), script_path)
@ -33,17 +34,17 @@ class LoadScript:
return script_module
except FileNotFoundError:
raise ScriptNotFoundError(script_path)
@logger.log_decorator()
def load_and_execute_script(self, script_directory, script_name, method_name, request):
"""
加载并执行脚本文件中的指定方法
Args:
request: 请求数据
script_directory (str): 脚本文件所在的目录
script_name (str): 脚本文件的名称
method_name (str): 要执行的方法的名称
request: 请求数据
script_directory (str): 脚本文件所在的目录
script_name (str): 脚本文件的名称
method_name (str): 要执行的方法的名称
"""
script_path = os.path.join(script_directory, script_name)
try:
@ -57,7 +58,7 @@ class LoadScript:
if __name__ == '__main__':
from common.config import Config
SCRIPTS_DIR = Config.SCRIPTS_DIR
load_and_exe_s = LoadScript()
load_and_exe_s.load_and_execute_script(SCRIPTS_DIR, 'request_script_sheetname_id.py', 'setup', {"y": "z"})

View File

@ -21,7 +21,7 @@ class MyLog:
"error": logging.ERROR,
"critic": logging.CRITICAL
} # 日志级别关系映射
def my_log(self, msg, level="error", when="D", back_count=10):
"""
实例化 TimeRotatingFileHandler
@ -34,10 +34,10 @@ class MyLog:
midnight 每天凌晨
"""
file_name = Config.log_path
my_logger = logging.getLogger() # 定义日志收集器 my_logger
my_logger.setLevel(self.level_relations.get(level)) # 设置日志级别
format_str = logging.Formatter(
"%(asctime)s-%(levelname)s-%(filename)s-[ line:%(lineno)d ] - 日志信息:%(message)s") # 设置日志格式
# 创建输出渠道
@ -45,19 +45,16 @@ class MyLog:
sh.setFormatter(format_str) # 设置屏幕上显示的格式
current = time.strftime("%Y-%m-%d", time.localtime()) # 设置当前日期
if level == "error":
th = handlers.TimedRotatingFileHandler(filename=f'{file_name}/{current}_{level}.logger',
when=when,
th = handlers.TimedRotatingFileHandler(filename=f'{file_name}/{current}_{level}.logger', when=when,
backupCount=back_count, encoding="utf-8")
else:
th = handlers.TimedRotatingFileHandler(filename=file_name + "/{}_info.logger".format(current),
when=when,
backupCount=back_count,
encoding="utf-8") # 往文件里写日志
th = handlers.TimedRotatingFileHandler(filename=file_name + "/{}_info.logger".format(current), when=when,
backupCount=back_count, encoding="utf-8") # 往文件里写日志
th.setFormatter(format_str) # 设置文件里写入的格式
my_logger.addHandler(sh) # 将对象加入logger里
my_logger.addHandler(th)
if level == "debug":
my_logger.debug(msg)
elif level == "error":
@ -68,11 +65,11 @@ class MyLog:
my_logger.warning(msg)
else:
my_logger.critical(msg)
my_logger.removeHandler(sh)
my_logger.removeHandler(th)
logging.shutdown()
def decorator_log(self, msg=None):
def warp(fun):
def inner(*args, **kwargs):
@ -80,9 +77,9 @@ class MyLog:
return fun(*args, **kwargs)
except Exception as e:
self.my_log(f"{msg}: {e}", "error")
return inner
return warp
@ -94,6 +91,6 @@ if __name__ == '__main__':
def add():
print("试一下")
raise "不好使,异常了。"
add()

View File

@ -1,7 +1,5 @@
import json
from common.utils import logger
# @logger.log_decorator()
def parsing_openapi(file_path):
@ -13,30 +11,30 @@ def parsing_openapi(file_path):
for path, methods in paths.items():
for method, details in methods.items():
test_case = {
"id": count,
"name": "openapi",
"description": details.get("summary"),
"Id": count,
"Name": "openapi",
"Description": details.get("summary"),
"Run": "yes",
"Time": "0.1",
'method': method,
'url': path,
'headers': json.dumps(extract_parameters(details.get('parameters', []), 'header')),
'Headers是否加密': "",
'params': json.dumps(extract_parameters(details.get('parameters', []), 'query')),
'request_data_type': determine_request_type(details.get('requestBody')),
'request_data': json.dumps(extract_request_body(details.get('requestBody'))),
'请求参数是否加密': '',
'提取请求参数': '',
'Method': method,
'Url': path,
'Headers': json.dumps(extract_parameters(details.get('parameters', []), 'header')),
'Headers Crypto': "",
'Query Str': json.dumps(extract_parameters(details.get('parameters', []), 'query')),
'Request Data Type': determine_request_type(details.get('requestBody')),
'Request Data': json.dumps(extract_request_body(details.get('requestBody'))),
'Request Data Crypto': '',
'Extract Request Data': '',
'Jsonpath': '',
'正则表达式': '',
'正则变量': '',
'绝对路径表达式': '',
'Regex': '',
'Regex Params List': '',
'Retrieve Value': '',
'SQL': '',
'sql变量': '',
'预期结果': '',
'响应结果': '',
'断言结果': '',
'报错日志': ''}
'Sql Params Dict': '',
'Expected': '',
'Response': '',
'Assertion': '',
'Error Log': ''}
test_cases.append(test_case)
count += 1
@ -105,3 +103,9 @@ if __name__ == '__main__':
file = f'../../cases/temporary_file/openapi.json'
res = parsing_openapi(file)
print(res)
from common.file_handling.excel import DoExcel
from common.config import Config
templates = Config.templates # 使用标准模板
ex = DoExcel(templates)
ex.do_main("openapi.xlsx", *res)

View File

@ -8,7 +8,7 @@ result = []
def parsing_postman(path):
"""
解析postman到处的json文件
解析postman导出的json文件 转为excel测试用例
Args:
path:
@ -29,9 +29,9 @@ def parsing_postman(path):
_parse_api(content=content.get('item'))
elif 'request' in content.keys():
id_count += 1
api['id'] = id_count
api['name'] = 'postman'
api['description'] = content.get('name')
api['Id'] = id_count
api['Name'] = 'postman'
api['Description'] = content.get('name')
request = content.get('request')
api['Run'] = 'yes'
api['Time'] = 0.5
@ -39,14 +39,12 @@ def parsing_postman(path):
# api请求方法
api['Method'] = request.get('method', 'GET').upper()
header = request.get('header')
header = {item.get('key'): item.get('value') for item in
header} if header else {}
header = {item.get('key'): item.get('value') for item in header} if header else {}
auth = request.get('auth')
if auth:
auth_type = auth.get('type')
if auth.get(auth_type):
auth_value = {item.get('key'): item.get('value') for item in
auth.get(auth_type) if
auth_value = {item.get('key'): item.get('value') for item in auth.get(auth_type) if
(item and item.get('key'))}
header.update(auth_value)
# api 请求地址
@ -63,51 +61,46 @@ def parsing_postman(path):
# [item.get('key') + '=' + (item.get('value') or '') for item in url.get('query') if item])
# api请求头
api['Headers'] = json.dumps(header, ensure_ascii=False)
api['Headers是否加密'] = ''
api['params'] = ''
api['Headers Crypto'] = ''
api['Query Str'] = ''
body = request.get('body')
if body:
# api接口请求参数类型
request_mode = body.get('mode')
if 'raw' == request_mode:
api['request_data_type'] = 'json'
api['Request Data Type'] = 'json'
elif 'formdata' == request_mode:
api['request_data_type'] = 'data'
api['Request Data Type'] = 'data'
elif 'urlencoded' == request_mode:
api['request_data_type'] = 'data'
api['Request Data Type'] = 'data'
# api接口请求参数
request_data = body.get(request_mode)
api['Request Data'] = {}
if request_data and 'raw' == request_mode:
api['Request Data'].update(
json.loads(request_data.replace('\t', '').replace('\n',
'').replace(
'\r', '')))
json.loads(request_data.replace('\t', '').replace('\n', '').replace('\r', '')))
elif request_data and 'formdata' == request_mode:
if isinstance(request_data, list):
for item in request_data:
if item.get("type") == "text":
api['Request Data'].update({item.get(
'key'): item.get("value", "")})
api['Request Data'].update({item.get('key'): item.get("value", "")})
elif item.get("type") == "file":
api["Request Data"].update({item.get(
'key'): item.get("src", "")})
api["request_data_type"] = "files"
api["Request Data"] = json.dumps(api["Request Data"],
ensure_ascii=False)
api['请求参数是否加密'] = ''
api['提取请求参数'] = ''
api["Request Data"].update({item.get('key'): item.get("src", "")})
api["Request Data Type"] = "files"
api["Request Data"] = json.dumps(api["Request Data"], ensure_ascii=False)
api['Request Data Crypto'] = ''
api['Extract Request Data'] = ''
api['Jsonpath'] = ''
api['正则表达式'] = ''
api['正则变量'] = ''
api['绝对路径表达式'] = ''
api['Regex'] = ''
api['Regex Params List'] = ''
api['Retrieve Value'] = ''
api['SQL'] = ''
api['sql变量'] = ''
api['预期结果'] = ''
api['响应结果'] = ''
api['断言结果'] = ''
api['报错日志'] = ''
api['Sql Params Dict'] = ''
api['Expected'] = ''
api['Response'] = ''
api['Assertion'] = ''
api['Error Log'] = ''
result.append(api)
@ -117,7 +110,7 @@ def parsing_postman(path):
if __name__ == '__main__':
pat = r'E:\apitest\cases\temporary_file\postman.json'
pat = r'..\..\cases\temporary_file\postman.json'
res = parsing_postman(pat)
from common.file_handling.excel import DoExcel
from common.config import Config

View File

@ -1,21 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: retry.py
@time: 2023/3/15 11:15
@desc:
"""
def retry(func):
"函数重跑"
def run_again(*args, **kwargs):
try:
func(*args, **kwargs)
except:
pass
return run_again

View File

@ -12,12 +12,9 @@ from functools import wraps
def singleton(cls):
"""
单例模式类装饰器
Args:
cls:被装饰类
cls:被装饰类
Returns:
"""
instance = {}

View File

@ -5,43 +5,44 @@ from dataclasses import dataclass
@dataclass
class Variables:
variables = {} # 定义依赖表
pattern_l = re.compile(r"{{\s*([^}\s]+)\s*}}(?:\[(\d+)\])?")
PATTERN = re.compile(r"{{(.*?)}}") # 预编译正则表达式
pattern = re.compile(r'({)')
pattern_fun = re.compile(r"{{(\w+\(\))}}")
@classmethod
def update_variable(cls, key, value):
"""更新依赖表"""
cls.variables[f"{{{{{key}}}}}"] = value
@classmethod
def get_variable(cls, key=None):
"""获取依赖表 或 依赖表中key对应的值"""
return cls.variables if not key else cls.variables.get(key)
@classmethod
def set_variable(cls, value):
"""设置依赖表"""
cls.variables = value
@classmethod
def reset(cls):
"""重置"""
cls.variables.clear()
cls.request = None
cls.response = None
variables = {} # 定义依赖表
# 预编译正则表达式
pattern_l = re.compile(r"{{\s*([^}\s]+)\s*}}(?:\[(\d+)\])?")
PATTERN = re.compile(r"{{(.*?)}}")
pattern = re.compile(r'({)')
pattern_fun = re.compile(r"{{(\w+\(\))}}")
@classmethod
def update_variable(cls, key, value):
"""更新依赖表"""
cls.variables[f"{{{{{key}}}}}"] = value
@classmethod
def get_variable(cls, key=None):
"""获取依赖表 或 依赖表中key对应的值"""
return cls.variables if not key else cls.variables.get(key)
@classmethod
def set_variable(cls, value):
"""设置依赖表"""
cls.variables = value
@classmethod
def reset(cls):
"""重置"""
cls.variables.clear()
cls.request = None
cls.response = None
if __name__ == '__main__':
from common.file_handling.get_excel_init import get_init
from common.config import Config
test_file = Config.test_case
excel_handle, init_data, test_case = get_init(test_file)
initialize_data = eval(init_data.get("initialize_data"))
print(initialize_data)
d = Variables
d.set_variable(initialize_data) # 初始化依赖表
print("--------------------->", d.get_variable())
# from common.file_handling.get_excel_init import get_init
from common.config import Config
test_file = Config.test_case
# excel_handle, init_data, test_case = get_init(test_file)
# initialize_data = eval(init_data.get("initialize_data"))
# print(initialize_data)
# d = Variables
# d.set_variable(initialize_data)
# print("--------------------->", d.get_variable())

View File

@ -1,17 +0,0 @@
# decorator_test.py
def my_decorator(func):
print("Decorator function called.")
def wrapper(*args, **kwargs):
print("Wrapper function called.")
return func(*args, **kwargs)
return wrapper
@my_decorator
def my_function():
print("Original function called.")
# print("Module imported.")

View File

@ -1,35 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: depr.py
@time: 2023/6/19 17:51
@desc:
"""
import requests
from common.database.redis_client import RedisClient
redis_client = RedisClient()
# 第一个接口,设置依赖数据
def first_api():
response = requests.get('https://api.example.com/first')
data = response.json()
redis_client.set_data('key', data['value'])
def second_api():
# 获取依赖数据
dependency_data = redis_client.get_data('key')
response = requests.post('https://api.example.com/second', data={'data': dependency_data})
result = response.json()
# 处理接口响应结果
if __name__ == '__main__':
first_api()
second_api()

View File

@ -1,38 +0,0 @@
import gc
# 引用计数示例
# a = [1, 2, 3]
# b = a
# print(sys.getrefcount(a)-1) # 输出2a和b都引用了该对象
# b = None
# print(sys.getrefcount(a)-1) # 输出1只有a引用了该对象
#
# # 标记-清除算法示例
class Node:
def __init__(self):
self.next = None
node1 = Node()
node2 = Node()
node1.next = node2
node2.next = node1
res = gc.collect() # 执行垃圾回收,循环引用的对象会被清除
# # 分代回收示例
# a = [1, 2, 3]
# gc.collect()
# print(gc.get_count()) # 输出(0, 0, 0)第0代对象计数为1
# b = [4, 5, 6]
# c = [7, 8, 9]
# gc.collect()
# print(gc.get_count()) # 输出(1, 0, 0)第0代对象计数为0第1代对象计数为2
# d = [10, 11, 12]
# e = [13, 14, 15]
# gc.collect()
# print(gc.get_count()) # 输出(2, 0, 0)第0代对象计数为0第1代对象计数为0第2代对象计数为2
#
# # 对象的代信息
# print(gc.get_objects()) # 输出对象的代信息

View File

@ -1,16 +0,0 @@
def sum(x, y):
return x + y
def generate():
for i in range(4):
yield i
res = generate()
for n in [0, 1, 2, 3]:
base =(sum(i, n) for i in res)
print(base)

View File

@ -1,59 +0,0 @@
# !/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: rt.py
@time: 2023/6/19 17:15
@desc:
"""
import concurrent.futures
import requests
from common.database.redis_client import RedisClient
# 创建 Redis 客户端
redis_client = RedisClient()
def get_user_info(user_id):
cache_key = f'user:{user_id}'
user_info = redis_client.get_data(cache_key)
if not user_info:
# 调用接口获取用户信息
response = requests.get(f'http://127.0.0.1:5000/?user_id={user_id}')
if response.status_code == 200:
user_info = response.text
print(user_info)
redis_client.set_data(cache_key, user_info, expire_time=3600)
else:
print(f"Failed to retrieve user info for user_id: {user_id}. Status code: {response.status_code}")
return user_info
# 并发测试函数
def run_concurrent_test(user_ids):
with concurrent.futures.ThreadPoolExecutor() as executor:
# 提交任务到线程池
future_to_user_id = {executor.submit(get_user_info, user_id): user_id for user_id in user_ids}
# 处理返回结果
for future in concurrent.futures.as_completed(future_to_user_id):
user_id = future_to_user_id[future]
try:
user_info = future.result()
print(f"user_id: {user_id}; user_info: {user_info}")
except Exception as e:
print(f"Error occurred for user_id: {user_id}, Error: {str(e)}")
if __name__ == '__main__':
u_ids = [i for i in range(10, 99)]
run_concurrent_test(u_ids)
# u_ids = [i for i in range(1000, 99999)]
# for i in u_ids:
# response = requests.get(f'http://127.0.0.1:5000/?user_id={i}')
# print(response.text)

View File

@ -1,39 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: test_single_class.py
@time: 2023/6/21 17:03
@desc:
"""
from functools import wraps
def single(cls):
instance = {}
@wraps(cls)
def decortator(*args, **kwargs):
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return decortator
class A:
pass
@single
class B(A):
pass
class C(B):
pass
if __name__ == '__main__':
C()

View File

@ -2,8 +2,8 @@ import os.path
from common.config import Config
from common.file_handling.excel import DoExcel
from common.utils.parsing_postman import parsing_postman
from common.utils.parsing_openapi import parsing_openapi
from common.utils.parsing_postman import parsing_postman
class ExcelConverter:
@ -37,10 +37,8 @@ class ExcelConverter:
if __name__ == '__main__':
postman_to_json = r'.\data\temporary_file\postman.json' # postman导出的json文件
postman_out_file = os.path.join(Config.base_path, 'cases', 'test_cases',
'test_postman_cases.xlsx') # 转化后的文件保存的位置
postman_out_file = os.path.join(Config.base_path, 'cases', 'test_cases', 'test_postman_cases.xlsx') # 转化后的文件保存的位置
openapi_to_json = r'.\data\temporary_file\openapi.json' # postman导出的json文件
openapi_out_file = os.path.join(Config.base_path, 'cases', 'test_cases',
'test_openapi_cases.xlsx') # 转化后的文件保存的位置
openapi_out_file = os.path.join(Config.base_path, 'cases', 'test_cases', 'test_openapi_cases.xlsx') # 转化后的文件保存的位置
ExcelConverter('postman', postman_to_json, postman_out_file).main()
ExcelConverter('postman', openapi_to_json, openapi_out_file).main()

View File

@ -11,5 +11,7 @@
__all__ = ["online_function"]
# 用户自定义扩展函数文件。
def online_function():
pass

View File

@ -20,45 +20,45 @@ from extensions import logger
@logger.log_decorator()
def md5_sign(data: dict):
"""
数据加签
Args:
**data:需要加钱的数据
Returns:
"""
sorted_list = []
for key, value in data.items():
try:
sorted_params = str(key) + str(value)
sorted_list.append(sorted_params)
except Exception:
raise
sort = natsorted(sorted_list) # 列表自然排序
argument = "加签所需要的密钥"
keystore = argument + ("".join(sort)) # 生成加带密钥的新字符串
sign_value = md5(keystore)
return {**data, **{"sign": sign_value}}
"""
数据加签
Args:
**data:需要加钱的数据
Returns:
"""
sorted_list = []
for key, value in data.items():
try:
sorted_params = str(key) + str(value)
sorted_list.append(sorted_params)
except Exception:
raise
sort = natsorted(sorted_list) # 列表自然排序
argument = "加签所需要的密钥"
keystore = argument + ("".join(sort)) # 生成加带密钥的新字符串
sign_value = md5(keystore)
return {**data, **{"sign": sign_value}}
@logger.log_decorator()
def sha1_sign(post_data: dict):
timestamp = int(round(time.time() * 1000)) # 毫秒级时间戳
argument = {"secretKey": "", "timestamp": timestamp} # 加密加盐参数
res = {**post_data, **argument}
sorted_list = []
for key, value in res.items():
try:
value = json.dumps(value, ensure_ascii=False) if isinstance(value, list) or isinstance(value,
dict) else str(
value)
sorted_params = str(key) + "=" + value
sorted_list.append(sorted_params)
except Exception as e:
raise e
sort = natsorted(sorted_list) # 列表自然排序 返回[(key,value),(key,value)]
splicing_str = "&".join(sort) # 排序结果 key=value&key=value 拼接
encrypted_str = sha1_secret_str(splicing_str) # sha1加密
sign = {"signature": encrypted_str}
return {**res, **sign} # request 中使用json入参则传dict
timestamp = int(round(time.time() * 1000)) # 毫秒级时间戳
argument = {"secretKey": "", "timestamp": timestamp} # 加密加盐参数
res = {**post_data, **argument}
sorted_list = []
for key, value in res.items():
try:
value = json.dumps(value, ensure_ascii=False) if isinstance(value, list) or isinstance(value,
dict) else str(
value)
sorted_params = str(key) + "=" + value
sorted_list.append(sorted_params)
except Exception as e:
raise e
sort = natsorted(sorted_list) # 列表自然排序 返回[(key,value),(key,value)]
splicing_str = "&".join(sort) # 排序结果 key=value&key=value 拼接
encrypted_str = sha1_secret_str(splicing_str) # sha1加密
sign = {"signature": encrypted_str}
return {**res, **sign} # request 中使用json入参则传dict

View File

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
# @Time : 2019/11/18 10:15
# @Author : kira
# @Email : 262667641@qq.com
# @File : __init__.py.py
# @Project : risk_api_project

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +0,0 @@
import json
import requests
class Hooks:
def __init__(self):
self.before_request_funcs = {}
self.after_request_funcs = {}
def before_request(self, func):
"""
注册 before_request 钩子函数
"""
self.before_request_funcs[func.__name__] = func
return func
def after_request(self, func):
"""
注册 after_request 钩子函数
"""
self.after_request_funcs[func.__name__] = func
return func
def run_before_request_hooks(self, func_names, request, json_data):
"""
执行 before_request 钩子函数
"""
for func_name in func_names:
if func_name in self.before_request_funcs:
func = self.before_request_funcs[func_name]
json_data = func(request, json_data)
return json_data
def run_after_request_hooks(self, func_names, response):
"""
执行 after_request 钩子函数
"""
for func_name in func_names:
if func_name in self.after_request_funcs:
func = self.after_request_funcs[func_name]
response = func(response)
return response
hooks = Hooks()
session = requests.Session()
def req(url, method, **kwargs):
"""
发送请求并返回响应对象
"""
before_hooks = kwargs.pop('before_hooks', [])
after_hooks = kwargs.pop('after_hooks', [])
json_data = kwargs.pop('json', {})
request = requests.Request(method=method, url=url, **kwargs)
prepared_request = session.prepare_request(request)
json_data = hooks.run_before_request_hooks(before_hooks, prepared_request, json_data)
prepared_request.body = json.dumps(json_data)
response = session.send(prepared_request)
response = hooks.run_after_request_hooks(after_hooks, response)
return response
@hooks.before_request
def add_authentication_headers(request, json_data):
"""
添加认证头信息
"""
print("前置钩子函数,添加认证头信息", request)
request.headers["Authorization"] = "Bearer YOUR_AUTH_TOKEN"
return json_data
@hooks.before_request
def handle_dependent_parameters(request, json_data):
"""
处理依赖参数
"""
print("前置钩子函数,处理依赖参数", request)
json_data["verification_code"] = get_verification_code()
return json_data
def get_verification_code():
# 实现获取验证码的逻辑
return "YOUR_VERIFICATION_CODE"
@hooks.after_request
def after_dependent_parameters(request, json_data):
"""
处理后置
"""
print("后置钩子函数,处理依赖参数", request)
return json_data
def test_user_registration():
url = "http://jsonplaceholder.typicode.com/posts"
data = {
"userId": "testuser",
"title": "password123",
"body": "测试玩家勇哥"
}
headers = {
"Content-Type": "application/json"
}
before_hooks = [add_authentication_headers.__name__, handle_dependent_parameters.__name__]
after_hooks = [after_dependent_parameters.__name__]
kwargs = {"json": data, "headers": headers}
return req(url, "post", before_hooks=before_hooks, after_hooks=after_hooks, **kwargs)
# assert response.status_code == 200
# assert response.json()["success"] is True
if __name__ == "__main__":
res = test_user_registration()
print(res, res.text)

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: hooks_decorator.py
@time: 2023/6/16 17:03
@desc:
"""
from temp.extent.hooks import Hooks
hooks = Hooks()
def before_decorator(func):
def wrapper(*args, **kwargs):
# hooks.execute_hooks(*args, **kwargs)
return func(*args, **kwargs)
return wrapper
def after_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
# hooks.execute_hooks(*args, **kwargs)
return result
return wrapper

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: run.py
@time: 2023/6/16 16:52
@desc:
"""
import requests
from temp.extent.hooks_decorator import before_decorator, after_decorator
@after_decorator
@before_decorator
def test_user_registration(url, method, **kwargs):
requests.request(method, url, **kwargs)
if __name__ == "__main__":
kwg = {}
test_user_registration("http://jsonplaceholder.typicode.com/posts/2", "get", **kwg)

View File

@ -1,125 +0,0 @@
import json
import requests
class Hooks:
def __init__(self):
self.before_request_funcs = {}
self.after_request_funcs = {}
def before_request(self, func):
"""
注册 before_request 钩子函数
"""
self.before_request_funcs[func.__name__] = func
return func
def after_request(self, func):
"""
注册 after_request 钩子函数
"""
self.after_request_funcs[func.__name__] = func
return func
def run_before_request_hooks(self, func_names, request, json_data):
"""
执行 before_request 钩子函数
"""
for func_name in func_names:
if func_name in self.before_request_funcs:
func = self.before_request_funcs[func_name]
json_data = func(request, json_data)
return json_data
def run_after_request_hooks(self, func_names, request, response):
"""
执行 after_request 钩子函数
"""
for func_name in func_names:
if func_name in self.after_request_funcs:
func = self.after_request_funcs[func_name]
response = func(request, response)
return response
hooks = Hooks()
session = requests.Session()
def req(url, method, **kwargs):
"""
发送请求并返回响应对象
"""
before_hooks = kwargs.pop('before_hooks', [])
after_hooks = kwargs.pop('after_hooks', [])
json_data = kwargs.pop('json', {})
request = requests.Request(method=method, url=url, **kwargs)
prepared_request = session.prepare_request(request)
json_data = hooks.run_before_request_hooks(before_hooks, prepared_request, json_data)
prepared_request.body = json.dumps(json_data)
response = session.send(prepared_request)
response = hooks.run_after_request_hooks(after_hooks, prepared_request, response)
return response
@hooks.before_request
def add_authentication_headers(request, json_data):
"""
添加认证头信息
"""
print("前置钩子函数,添加认证头信息", request)
request.headers["Authorization"] = "Bearer YOUR_AUTH_TOKEN"
return json_data
@hooks.before_request
def handle_dependent_parameters(request, json_data):
"""
处理依赖参数
"""
print("前置钩子函数,处理依赖参数", request)
json_data["verification_code"] = get_verification_code()
return json_data
def get_verification_code():
# 实现获取验证码的逻辑
return "YOUR_VERIFICATION_CODE"
@hooks.after_request
def after_dependent_parameters(request, response):
"""
处理后置
"""
print("发送请求后执行", request, "后置钩子函数,处理依赖参数", response)
return response
def test_user_registration():
url = "http://www.baidu.com"
# url = "http://jsonplaceholder.typicode.com/posts"
data = {
"userId": "testuser",
"title": "password123",
"body": "测试玩家勇哥"
}
headers = {
"Content-Type": "application/json"
}
before_hooks = [add_authentication_headers.__name__, handle_dependent_parameters.__name__]
after_hooks = [after_dependent_parameters.__name__]
kwargs = {"json": data, "headers": headers}
return req(url, "post", before_hooks=before_hooks, after_hooks=after_hooks, **kwargs)
if __name__ == "__main__":
res = test_user_registration()
print("最终打印:----->", res)

View File

@ -42,3 +42,23 @@ class Hooks:
response = func(response)
return response
hooks = Hooks()
def before_decorator(func):
def wrapper(*args, **kwargs):
# hooks.execute_hooks(*args, **kwargs)
return func(*args, **kwargs)
return wrapper
def after_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
# hooks.execute_hooks(*args, **kwargs)
return result
return wrapper

View File

@ -1,12 +1,4 @@
#!/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@contact: 262667641@qq.com
@file: prepost_script.py
@time: 2023/6/16 16:58
@desc:
""" # !/usr/bin/env python
# !/usr/bin/env python
# encoding: utf-8
"""
@author: kira
@ -15,7 +7,7 @@
@time: 2023/6/16 16:58
@desc:
"""
from temp.extent.hooks_decorator import hooks # 导入hooks对象
from temp.hooks import hooks
@hooks.before_request

View File

@ -4,8 +4,8 @@ import unittest
from ddt import ddt, data
from common import bif_functions
from common.config import Config
from common.action import Action
from common.config import Config
from common.database.mysql_client import MysqlClient
from common.file_handling.do_excel import DoExcel
from common.utils.mylogger import MyLogger
@ -36,8 +36,7 @@ class TestProjectApi(unittest.TestCase):
def test_api(self, item):
# f"""用例:{item.get("name")}_{item.get("desc")}"""
sheet, iid, condition, st, name, desc, headers_crypto, request_crypto, method = self.__base_info(
item)
sheet, iid, condition, st, name, desc, headers_crypto, request_crypto, method = self.__base_info(item)
regex, keys, deps, jp_dict, extract_request_data = self.__extractor_info(item)
if self.__is_run(condition):
@ -70,10 +69,7 @@ class TestProjectApi(unittest.TestCase):
try:
# 执行请求操作
kwargs = {
request_data_type: request_data,
'headers': headers
}
kwargs = {request_data_type: request_data, 'headers': headers}
response = self.action.http_client(host, url, method, **kwargs)
# 执行后置代码片段
self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "teardown", response)

View File

@ -1,206 +0,0 @@
import time
import unittest
from ddt import ddt, data
from common import bif_functions
from common.action import Action
from common.config import Config
from common.database.mysql_client import MysqlClient
from common.file_handling.do_excel import DoExcel
from common.utils.mylogger import MyLogger
test_file = Config.test_case # 获取 excel 文件路径
excel = DoExcel(test_file)
init_data, test_case = excel.get_excel_init_and_cases()
databases = init_data.get('databases') # 获取数据库配置信息
mysql = MysqlClient(databases) # 初始化 mysql 链接
logger = MyLogger()
initialize_data = eval(init_data.get("initialize_data"))
host = init_data.get('host', "") + init_data.get("path", "")
@ddt
class TestProjectApi(unittest.TestCase):
maxDiff = None
action = Action()
@classmethod
def setUpClass(cls) -> None:
cls.action.set_variable(initialize_data) # 加载初始化数据
cls.action.set_bif_fun(bif_functions) # 加载内置方法
@data(*test_case)
def test_api(self, item):
# f"""用例:{item.get("name")}_{item.get("desc")}"""
sheet, iid, condition, st, name, desc, headers_crypto, request_crypto, method = self.__base_info(
item)
regex, keys, deps, jp_dict, extract_request_data = self.__extractor_info(item)
if self.__is_run(condition):
return
self.__pause_execution(st)
sql, sql_params_dict = self.__sql_info(item)
# 首先执行sql替换,将sql替换为正确的sql语句
sql = self.action.replace_dependent_parameter(sql)
self.__exc_sql(sql, sql_params_dict, method)
# 拼接动态代码段文件
prepost_script = f"prepost_script_{sheet}_{iid}.py"
item = self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "setup", item)
# 替换 URL, PARAMETERS, HEADER,期望值
item = self.action.replace_dependent_parameter(item)
url, query_str, request_data, headers, expected, request_data_type = self.__request_info(item)
# 提取请求参数信息
self.action.substitute_data(request_data, jp_dict=jp_dict)
headers, request_data = self.action.encrypt.encrypts(headers_crypto, headers, request_crypto, request_data)
result_tuple = None
result = "PASS"
response = None
try:
# 执行请求操作
kwargs = {
"sheet": sheet,
"iid": iid,
"item": item,
"jp_dict": jp_dict,
request_data_type: request_data,
'headers': headers
}
response = self.action.http_client(host, url, method, **kwargs)
# 执行后置代码片段
self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "teardown", response)
result_tuple = self.action.run_validate(expected, response.json()) # 执行断言 返回结果元组
self.assertNotIn("FAIL", result_tuple, "FAIL 存在结果元组中")
try:
# 提取响应
self.action.substitute_data(response.json(), regex=regex, keys=keys, deps=deps, jp_dict=jp_dict)
except Exception as err:
logger.error(f"提取响应失败:{sheet}_{iid}_{name}_{desc}"
f"\nregex={regex};"
f" \nkeys={keys};"
f"\ndeps={deps};"
f"\njp_dict={jp_dict}"
f"\n{err}")
except Exception as e:
result = "FAIL"
logger.error(f'异常用例: {sheet}_{iid}_{name}_{desc}\n{e}')
raise e
finally:
response = response.text if response is not None else str(response)
assert_log = str(result_tuple)
# 响应结果及测试结果回写 excel
excel.write_back(sheet_name=sheet, i=iid, response=response, test_result=result, assert_log=assert_log)
@classmethod
def tearDownClass(cls) -> None:
logger.info(f"所有用例执行完毕")
@staticmethod
def __base_info(item):
"""
获取基础信息
Args:
item:
Returns:
"""
sheet = item.pop("sheet")
item_id = item.pop("Id")
condition = item.pop("Run")
sleep_time = item.pop("Time")
name = item.pop("Name")
desc = item.pop("Description")
headers_crypto = item.pop("Headers Crypto")
request_data_crypto = item.pop("Request Data Crypto")
method = item.pop("Method")
return sheet, item_id, condition, sleep_time, name, desc, headers_crypto, request_data_crypto, method
@staticmethod
def __sql_info(item):
sql = item.pop("SQL")
sql_params_dict = item.pop("Sql Params Dict")
return sql, sql_params_dict
@staticmethod
def __extractor_info(item):
"""
获取提取参数的基本字段信息
Args:
item:
Returns:
"""
regex = item.pop("Regex")
keys = item.pop("Regex Params List")
deps = item.pop("Retrieve Value")
jp_dict = item.pop("Jsonpath")
extract_request_data = item.pop("Extract Request Data")
return regex, keys, deps, jp_dict, extract_request_data
@staticmethod
def __request_info(item):
"""
请求数据
Args:
item:
Returns:
"""
url = item.pop("Url")
query_str = item.pop("Query Str")
request_data = item.pop("Request Data")
headers = item.pop("Headers")
expected = item.pop("Expected")
request_data_type = item.pop("Request Data Type") if item.get("Request Data Type") else 'params'
return url, query_str, request_data, headers, expected, request_data_type
@staticmethod
def __is_run(condition):
is_run = condition
if not is_run or is_run.upper() != "YES":
return True
@staticmethod
def __pause_execution(sleep_time):
if sleep_time:
try:
time.sleep(sleep_time)
except Exception as e:
logger.error("暂时时间必须是数字")
raise e
def __exc_sql(self, sql, sql_params_dict, method):
if sql:
try:
execute_sql_results = mysql.do_mysql(sql)
if execute_sql_results and sql_params_dict:
self.action.extract_request_data(execute_sql_results, jp_dict=sql_params_dict)
if method == "SQL" and mysql:
return None
except Exception as e:
logger.error(f'执行 sql 失败:{sql},异常信息:{e}')
raise e
return sql
if __name__ == '__main__':
unittest.main()

View File

@ -1,86 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/10/12 11:12
# @Author : kira
# -*- coding: utf-8 -*-
# @Time : 2021/7/6 15:31
# @Author : kira
# @Email : 262667641@qq.com
# @File : test_wifi_upload_file.py
# @Project : api-test-project
import os
import random
import sys
import jsonpath
from common.file_handling.file_utils import FileUtils
sys.path.append("../../")
sys.path.append("../../common")
from common.http_client.http_client import Pyt
from common.config import Config
from common.random_tools.names import name
from common.random_tools.phone_numbers import phone
from common.random_tools.identification import idcard
pyt = Pyt()
def test_labor_register(cases):
host = 'https://bimuse.bzlrobot.com/bsp/test/user/ugs'
headers = {"BSP_APP_ID": "8d1f5bdc9c6648af84a98e2c017846c5",
"BSP_TOKEN": "32c9fd9ccc0565d0281b89b5fa198008",
"BSP_USER_ENV_ID": "f8e334ea85df45ed99a311ed022c2973",
"BSP_USER_ID": "216684145642752200",
"BSP_USER_TENANT": "216856950236843913",
"bzlrobot-authorization": "bearer 32c9fd9ccc0565d0281b89b5fa198008",
"projectId": "99000022",
"projectName": "%E4%BD%9B%E5%B1%B1%E9%99%88%E6%9D%91%E6%97%A7%E6%94%B9%E9%A1%B9%E7%9B%AE"
}
sex_id = random.randint(0, 1)
user_sex = "F" if sex_id == 0 else "M"
user_name = name.get_girl() if sex_id == 0 else name.get_boy()
user_id_card = idcard.get_generate_id(sex=sex_id)
user_birthday = idcard.get_birthday(user_id_card)
user_mobile = phone.get_mobile_number()
# 请求工种接口,获取所有工种
url = f"/ibs/api/ibs-lms-base/work-kind/page/list?t=1636702597000&current=1&size=1000&projectId={cases['projectId']}&key=&supplyId=&status=0&enabled=1"
kwargs = {
"headers": headers
}
res = pyt.http_client(host, url, "GET", **kwargs).json()
codes = jsonpath.jsonpath(res, "$.data..code")
names = jsonpath.jsonpath(res, "$.data..name")
work_kinds = dict(zip(codes, names))
work_code = random.choice(list(work_kinds.keys()))
cases["name"] = user_name
cases["idCard"]["name"] = user_name
cases["idCard"]["cardNo"] = user_id_card
cases["phone"] = user_mobile
cases["idCard"]["sex"] = user_sex
cases["idCard"]["birthday"] = user_birthday
cases['workKindCode'] = str(work_code)
cases['workKindName'] = work_kinds[str(work_code)]
if "positionName" in cases:
url = "/ibs/api/ibs-lms-member/manager/register?t=1634607524000"
else:
url = "/ibs/api/ibs-lms-member/labor/register?t=1633743835000"
try:
kwargs.update({"json": cases})
res = pyt.http_client(host, url, "POST", **kwargs)
assert res.status_code == 200
except Exception as e:
raise e
if __name__ == '__main__':
# 测试数据路径
test_case_path = os.path.join(Config.base_path, 'cases', 'cases', "labor.json")
test_case = FileUtils().read_json_file(test_case_path)
for i in range(500):
test_labor_register(test_case)