删除敏感信息
This commit is contained in:
parent
ae6cf6eb48
commit
979f2ffdaf
Binary file not shown.
|
@ -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 '/')
|
|
|
@ -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
|
@ -29,7 +29,7 @@
|
||||||
"header": [],
|
"header": [],
|
||||||
"body": {
|
"body": {
|
||||||
"mode": "raw",
|
"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": {
|
"options": {
|
||||||
"raw": {
|
"raw": {
|
||||||
"language": "json"
|
"language": "json"
|
||||||
|
@ -42,498 +42,11 @@
|
||||||
"{{url}}"
|
"{{url}}"
|
||||||
],
|
],
|
||||||
"path": [
|
"path": [
|
||||||
"bsp",
|
|
||||||
"test",
|
|
||||||
"user",
|
|
||||||
"ugs",
|
|
||||||
"auth",
|
|
||||||
"loginByNotBip"
|
"loginByNotBip"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": []
|
"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": []
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -14,80 +14,80 @@ import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
|
||||||
class MQTTClient:
|
class MQTTClient:
|
||||||
def __init__(self, broker_address, topic):
|
def __init__(self, broker_address, topic):
|
||||||
self.broker_address = broker_address
|
self.broker_address = broker_address
|
||||||
self.topic = topic
|
self.topic = topic
|
||||||
|
|
||||||
def on_connect(self, client, userdata, flags, rc):
|
def on_connect(self, client, userdata, flags, rc):
|
||||||
print("Connected with result code " + str(rc))
|
print("Connected with result code " + str(rc))
|
||||||
|
|
||||||
def on_publish(self, client, userdata, mid):
|
def on_publish(self, client, userdata, mid):
|
||||||
print("Message " + str(mid) + " published.")
|
print("Message " + str(mid) + " published.")
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
client = mqtt.Client()
|
client = mqtt.Client()
|
||||||
client.on_connect = self.on_connect
|
client.on_connect = self.on_connect
|
||||||
client.on_publish = self.on_publish
|
client.on_publish = self.on_publish
|
||||||
client.connect(self.broker_address)
|
client.connect(self.broker_address)
|
||||||
client.loop_start()
|
client.loop_start()
|
||||||
client.publish(self.topic, json.dumps(message))
|
client.publish(self.topic, json.dumps(message))
|
||||||
client.loop_stop()
|
client.loop_stop()
|
||||||
|
|
||||||
|
|
||||||
msg = {
|
msg = {
|
||||||
"datapoint": [
|
"datapoint": [
|
||||||
{
|
{
|
||||||
"value": "492875336",
|
"value": "492875336",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"index": "0"
|
"index": "0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": "2023-04-24T15:48:33.128Z",
|
"value": "2023-04-24T15:48:33.128Z",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"index": "6"
|
"index": "6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"type": "byte",
|
"type": "byte",
|
||||||
"index": "7"
|
"index": "7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": "11132.00",
|
"value": "11132.00",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"index": "8"
|
"index": "8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "11",
|
"index": "11",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "粤EJC5V3"
|
"value": "粤EJC5V3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "12",
|
"index": "12",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "1"
|
"value": "1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "13",
|
"index": "13",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "http://192.1.14.19/document/fileStore/viewPicture/08188228a79b42ffa6b32a85f08b38ba"
|
"value": "/08188228a72a85f08b38ba"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "14",
|
"index": "14",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "https://ibs-test.bzlrobot.com/dfs/get?fileName=In-rear-pic.jpg&group=group1&path=M00/0A/4F/CgjLoWDiwteEBoWJAAAAANRLO4A310.jpg"
|
"value": "/CgjLoBoA310.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "18",
|
"index": "18",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "20230423174821"
|
"value": "20230423174821"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"from_id": "492875336",
|
"from_id": "492875336",
|
||||||
"msg_id": "1682243313128531625",
|
"msg_id": "1682243313128531625",
|
||||||
"time": "2023-04-23T19:48:33.128Z",
|
"time": "2023-04-23T19:48:33.128Z",
|
||||||
"type": "SYNC"
|
"type": "SYNC"
|
||||||
}
|
}
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
p = sys.argv[0]
|
p = sys.argv[0]
|
||||||
rab = MQTTClient(broker_address='192.2.3.59', topic='weigh/492875336/rtdata')
|
rab = MQTTClient(broker_address='1.2.3.4', topic='9999999')
|
||||||
rab.send_message(msg)
|
rab.send_message(msg)
|
||||||
|
|
|
@ -13,111 +13,111 @@ import pika
|
||||||
|
|
||||||
|
|
||||||
class RabbitMQClient:
|
class RabbitMQClient:
|
||||||
def __init__(self, host, queue_name=None, exchange_name=None, exchange_type=None, routing_key=None):
|
def __init__(self, host, queue_name=None, exchange_name=None, exchange_type=None, routing_key=None):
|
||||||
"""
|
"""
|
||||||
RabbitMQClient 类的构造函数。AMQP 协议默认
|
RabbitMQClient 类的构造函数。AMQP 协议默认
|
||||||
参数:
|
参数:
|
||||||
- host: RabbitMQ 服务器的主机地址。
|
- host: RabbitMQ 服务器的主机地址。
|
||||||
- queue_name: 队列名称。如果指定了该参数,则消息将被发送到指定的队列。
|
- queue_name: 队列名称。如果指定了该参数,则消息将被发送到指定的队列。
|
||||||
- exchange_name: 主题交换机名称。如果指定了该参数,则消息将被发送到指定的主题交换机。
|
- exchange_name: 主题交换机名称。如果指定了该参数,则消息将被发送到指定的主题交换机。
|
||||||
- exchange_type: 主题交换机类型。如果指定了 exchange_name 参数,则必须指定此参数。例如,'direct' 或 'topic'。
|
- exchange_type: 主题交换机类型。如果指定了 exchange_name 参数,则必须指定此参数。例如,'direct' 或 'topic'。
|
||||||
- routing_key: 路由键。如果指定了 exchange_name 参数,则必须指定此参数。路由键用于将消息路由到特定的队列。
|
- routing_key: 路由键。如果指定了 exchange_name 参数,则必须指定此参数。路由键用于将消息路由到特定的队列。
|
||||||
"""
|
"""
|
||||||
self.host = host
|
self.host = host
|
||||||
self.queue_name = queue_name
|
self.queue_name = queue_name
|
||||||
self.exchange_name = exchange_name
|
self.exchange_name = exchange_name
|
||||||
self.exchange_type = exchange_type
|
self.exchange_type = exchange_type
|
||||||
self.routing_key = routing_key
|
self.routing_key = routing_key
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.channel = None
|
self.channel = None
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""
|
"""
|
||||||
连接到 RabbitMQ 服务器,并根据需要声明队列和交换机。
|
连接到 RabbitMQ 服务器,并根据需要声明队列和交换机。
|
||||||
"""
|
"""
|
||||||
# 连接到 RabbitMQ 服务器
|
# 连接到 RabbitMQ 服务器
|
||||||
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host))
|
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host))
|
||||||
self.channel = self.connection.channel()
|
self.channel = self.connection.channel()
|
||||||
|
|
||||||
# 如果指定了 exchange_name 参数,则声明主题交换机
|
# 如果指定了 exchange_name 参数,则声明主题交换机
|
||||||
if self.exchange_name:
|
if self.exchange_name:
|
||||||
self.channel.exchange_declare(exchange=self.exchange_name, exchange_type=self.exchange_type)
|
self.channel.exchange_declare(exchange=self.exchange_name, exchange_type=self.exchange_type)
|
||||||
|
|
||||||
# 如果指定了 queue_name 参数,则声明队列,并将其绑定到主题交换机上
|
# 如果指定了 queue_name 参数,则声明队列,并将其绑定到主题交换机上
|
||||||
if self.queue_name:
|
if self.queue_name:
|
||||||
self.channel.queue_declare(queue=self.queue_name)
|
self.channel.queue_declare(queue=self.queue_name)
|
||||||
if self.exchange_name:
|
if self.exchange_name:
|
||||||
self.channel.queue_bind(queue=self.queue_name, exchange=self.exchange_name,
|
self.channel.queue_bind(queue=self.queue_name, exchange=self.exchange_name,
|
||||||
routing_key=self.routing_key)
|
routing_key=self.routing_key)
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
"""
|
"""
|
||||||
发送一条消息到指定的队列或主题。
|
发送一条消息到指定的队列或主题。
|
||||||
参数:
|
参数:
|
||||||
- message: 要发送的消息。
|
- message: 要发送的消息。
|
||||||
"""
|
"""
|
||||||
# 如果指定了 queue_name 参数,则将消息发送到指定的队列
|
# 如果指定了 queue_name 参数,则将消息发送到指定的队列
|
||||||
if self.queue_name:
|
if self.queue_name:
|
||||||
self.channel.basic_publish(exchange='', routing_key=self.queue_name, body=message)
|
self.channel.basic_publish(exchange='', routing_key=self.queue_name, body=message)
|
||||||
# 如果指定了 exchange_name 参数,则将消息发送到指定的主题交换机
|
# 如果指定了 exchange_name 参数,则将消息发送到指定的主题交换机
|
||||||
elif self.exchange_name:
|
elif self.exchange_name:
|
||||||
self.channel.basic_publish(exchange=self.exchange_name, routing_key=self.routing_key,
|
self.channel.basic_publish(exchange=self.exchange_name, routing_key=self.routing_key,
|
||||||
body=message)
|
body=message)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
关闭与 RabbitMQ 的连接。
|
关闭与 RabbitMQ 的连接。
|
||||||
"""
|
"""
|
||||||
self.connection.close()
|
self.connection.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
msg = {
|
msg = {
|
||||||
"datapoint": [
|
"datapoint": [
|
||||||
{
|
{
|
||||||
"value": "492875336",
|
"value": "492875336",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"index": "0"
|
"index": "0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": "2023-04-23T17:48:33.128Z",
|
"value": "2023-04-23T17:48:33.128Z",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"index": "6"
|
"index": "6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"type": "byte",
|
"type": "byte",
|
||||||
"index": "7"
|
"index": "7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": "11132.00",
|
"value": "11132.00",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"index": "8"
|
"index": "8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "11",
|
"index": "11",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "粤EJC5V3"
|
"value": "粤EJC5V3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"index": "12",
|
"index": "12",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "1"
|
"value": "1"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"index": "18",
|
"index": "18",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"value": "20230423174821"
|
"value": "20230423174821"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"from_id": "492875336",
|
"from_id": "492875336",
|
||||||
"msg_id": "1682243313128531625",
|
"msg_id": "1682243313128531625",
|
||||||
"time": "2023-04-23T17:48:33.128Z",
|
"time": "2023-04-23T17:48:33.128Z",
|
||||||
"type": "SYNC"
|
"type": "SYNC"
|
||||||
}
|
}
|
||||||
rab = RabbitMQClient(host='192.1.1.59:1883', exchange_name='/bridge/492/rtdata',
|
rab = RabbitMQClient(host='1.1.1.9:18', exchange_name='/rtdata',
|
||||||
# exchange_type='topic',
|
# exchange_type='topic',
|
||||||
# routing_key='connected'
|
# routing_key='connected'
|
||||||
)
|
)
|
||||||
rab.send_message(json.dumps(msg))
|
rab.send_message(json.dumps(msg))
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,11 +3,12 @@
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# Name: bif_datetime.py
|
# Name: bif_datetime.py
|
||||||
# Description:
|
# Description:
|
||||||
# Author: chenyongzhi
|
# Author: kira
|
||||||
# EMAIL: 262667641@qq.com
|
# EMAIL: 262667641@qq.com
|
||||||
# Date: 2021/1/12 14:03
|
# Date: 2021/1/12 14:03
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from common.bif_functions import logger
|
from common.bif_functions import logger
|
||||||
|
|
||||||
__all__ = ['get_current_date', 'get_current_time', 'get_delta_time']
|
__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()
|
@logger.log_decorator()
|
||||||
def get_current_date(fmt="%Y-%m-%d"):
|
def get_current_date(fmt="%Y-%m-%d"):
|
||||||
"""
|
"""
|
||||||
获取当前日期,默认格式为:%Y-%m-%d
|
获取当前日期,默认格式为:%Y-%m-%d
|
||||||
Args:
|
Args:
|
||||||
fmt: 日期格式
|
fmt: 日期格式
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return datetime.now().strftime(fmt)
|
return datetime.now().strftime(fmt)
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def get_current_time(fmt="%Y-%m-%d %H:%M:%S"):
|
def get_current_time(fmt="%Y-%m-%d %H:%M:%S"):
|
||||||
"""
|
"""
|
||||||
获取当前时间:默认格式为:%Y-%m-%d %H:%M:%S
|
获取当前时间:默认格式为:%Y-%m-%d %H:%M:%S
|
||||||
Args:
|
Args:
|
||||||
fmt: 时间格式
|
fmt: 时间格式
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return datetime.now().strftime(fmt)
|
return datetime.now().strftime(fmt)
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def get_delta_time(days=0, hours=0, minutes=0, seconds=0, fmt="%Y-%m-%d %H:%M:%S"):
|
def get_delta_time(days=0, hours=0, minutes=0, seconds=0, fmt="%Y-%m-%d %H:%M:%S"):
|
||||||
"""
|
"""
|
||||||
获取当前时间指定间隔后的时间
|
获取当前时间指定间隔后的时间
|
||||||
Args:
|
Args:
|
||||||
days:距离当前时间多少天
|
days:距离当前时间多少天
|
||||||
hours:距离当前时间多少时
|
hours:距离当前时间多少时
|
||||||
minutes:距离当前时间多少分
|
minutes:距离当前时间多少分
|
||||||
seconds: 距离当前时间多少秒
|
seconds: 距离当前时间多少秒
|
||||||
fmt: 时间格式
|
fmt: 时间格式
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return (datetime.now() + timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)).strftime(fmt)
|
return (datetime.now() + timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)).strftime(fmt)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
get_delta_time(4)
|
get_delta_time(4)
|
||||||
|
|
|
@ -16,17 +16,17 @@ from common.bif_functions import logger
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def md5_encryption(raw_str, sha_str='', toupper=False):
|
def md5_encryption(raw_str, sha_str='', toupper=False):
|
||||||
"""
|
"""
|
||||||
执行md5加密
|
执行md5加密
|
||||||
Args:
|
Args:
|
||||||
raw_str: 原始字符串
|
raw_str: 原始字符串
|
||||||
sha_str: md5加密的盐值
|
sha_str: md5加密的盐值
|
||||||
toupper: 是否将加密后的结果转大写
|
toupper: 是否将加密后的结果转大写
|
||||||
|
|
||||||
Returns: 经md5加密后的字符串
|
Returns: 经md5加密后的字符串
|
||||||
|
|
||||||
"""
|
"""
|
||||||
md5_obj = hashlib.md5(sha_str.encode('utf-8'))
|
md5_obj = hashlib.md5(sha_str.encode('utf-8'))
|
||||||
md5_obj.update(str(raw_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()
|
encrypted_str = md5_obj.hexdigest().upper() if toupper else md5_obj.hexdigest()
|
||||||
return encrypted_str
|
return encrypted_str
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# Name: bif_json.py
|
# Name: bif_json.py
|
||||||
# Description:
|
# Description:
|
||||||
# Author: chenyongzhi
|
# Author: kira
|
||||||
# EMAIL: 262667641@qq.com
|
# EMAIL: 262667641@qq.com
|
||||||
# Date: 2021/1/12 14:02
|
# Date: 2021/1/12 14:02
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
@ -16,25 +16,25 @@ __all__ = ['json_dumps', 'json_loads']
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def json_dumps(obj):
|
def json_dumps(obj):
|
||||||
"""
|
"""
|
||||||
Serialize ``obj`` to a JSON formatted ``str``.
|
Serialize ``obj`` to a JSON formatted ``str``.
|
||||||
Args:
|
Args:
|
||||||
obj:
|
obj:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return json.dumps(obj, ensure_ascii=False)
|
return json.dumps(obj, ensure_ascii=False)
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def json_loads(obj):
|
def json_loads(obj):
|
||||||
"""
|
"""
|
||||||
Deserialize ``obj`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object.
|
Deserialize ``obj`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object.
|
||||||
Args:
|
Args:
|
||||||
obj:
|
obj:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return json.loads(obj)
|
return json.loads(obj)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# Name: bif_list.py
|
# Name: bif_list.py
|
||||||
# Description:
|
# Description:
|
||||||
# Author: chenyongzhi
|
# Author: kira
|
||||||
# EMAIL: 262667641@qq.com
|
# EMAIL: 262667641@qq.com
|
||||||
# Date: 2021/1/12 15:15
|
# Date: 2021/1/12 15:15
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
@ -14,65 +14,65 @@ __all__ = ['list_slice', 'sublist']
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def list_slice(obj, index=None, start=None, end=None, step=1):
|
def list_slice(obj, index=None, start=None, end=None, step=1):
|
||||||
"""
|
"""
|
||||||
切片方法
|
切片方法
|
||||||
Args:
|
Args:
|
||||||
obj:
|
obj:
|
||||||
index: 索引
|
index: 索引
|
||||||
start: 开始索引
|
start: 开始索引
|
||||||
end: 结束索引(不含)
|
end: 结束索引(不含)
|
||||||
step: 步长
|
step: 步长
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(obj, (str, tuple, list)):
|
if isinstance(obj, (str, tuple, list)):
|
||||||
if index is not None:
|
if index is not None:
|
||||||
try:
|
try:
|
||||||
return obj[index]
|
return obj[index]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return obj[start:end:step]
|
return obj[start:end:step]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def sublist(raw_list, start=None, end=None):
|
def sublist(raw_list, start=None, end=None):
|
||||||
"""
|
"""
|
||||||
截取子列表
|
截取子列表
|
||||||
Args:
|
Args:
|
||||||
raw_list: 原始列表
|
raw_list: 原始列表
|
||||||
start: 字符串开始位置
|
start: 字符串开始位置
|
||||||
end: 字符串结束位置
|
end: 字符串结束位置
|
||||||
|
|
||||||
Returns: 截取的字符串或子列表
|
Returns: 截取的字符串或子列表
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(raw_list, (str, list)) and isinstance(start, (int, str)) and isinstance(end, (int, str)):
|
if isinstance(raw_list, (str, list)) and isinstance(start, (int, str)) and isinstance(end, (int, str)):
|
||||||
try:
|
try:
|
||||||
start = int(start) if isinstance(start, str) and start.isdigit() else start
|
start = int(start) if isinstance(start, str) and start.isdigit() else start
|
||||||
end = int(end) if isinstance(end, str) and end.isdigit() else end
|
end = int(end) if isinstance(end, str) and end.isdigit() else end
|
||||||
if isinstance(raw_list, str):
|
if isinstance(raw_list, str):
|
||||||
return list(raw_list[start:end])
|
return list(raw_list[start:end])
|
||||||
else:
|
else:
|
||||||
return raw_list[start:end]
|
return raw_list[start:end]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# lst = [1, 2, 3, 4, 5]
|
# lst = [1, 2, 3, 4, 5]
|
||||||
# print(list_slice(lst, index=2)) # 3
|
# 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)) # [2, 3, 4]
|
||||||
# print(list_slice(lst, start=1, end=4, step=2)) # [2, 4]
|
# print(list_slice(lst, start=1, end=4, step=2)) # [2, 4]
|
||||||
# print(list_slice(123)) # None
|
# print(list_slice(123)) # None
|
||||||
raw_list = ['a', 'b', 'c', 'd', 'e']
|
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='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='x', end='4')) # []
|
||||||
print(sublist(raw_list, start=1, end=10)) # ['b', 'c', 'd', 'e']
|
print(sublist(raw_list, start=1, end=10)) # ['b', 'c', 'd', 'e']
|
||||||
print(sublist('abcdef', start=1, end=4)) # ['b', 'c', 'd']
|
print(sublist('abcdef', start=1, end=4)) # ['b', 'c', 'd']
|
||||||
print(sublist(123, start=1, end=4)) # []
|
print(sublist(123, start=1, end=4)) # []
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# Name: bif_random.py
|
# Name: bif_random.py
|
||||||
# Description:
|
# Description:
|
||||||
# Author: chenyongzhi
|
# Author: kira
|
||||||
# EMAIL: 262667641@qq.com
|
# EMAIL: 262667641@qq.com
|
||||||
# Date: 2021/1/12 14:02
|
# Date: 2021/1/12 14:02
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
|
@ -17,38 +17,38 @@ __all__ = ['random_choice', 'gen_random_num', 'gen_random_str']
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def random_choice(args):
|
def random_choice(args):
|
||||||
"""
|
"""
|
||||||
随机选择
|
随机选择
|
||||||
Args:
|
Args:
|
||||||
args:
|
args:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return random.choice(args)
|
return random.choice(args)
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def gen_random_num(length):
|
def gen_random_num(length):
|
||||||
"""
|
"""
|
||||||
随机生成指定长度的数字
|
随机生成指定长度的数字
|
||||||
Args:
|
Args:
|
||||||
length: 指定长度
|
length: 指定长度
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return random.randint(int('1' + '0' * (length - 1)), int('9' * length))
|
return random.randint(int('1' + '0' * (length - 1)), int('9' * length))
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def gen_random_str(length):
|
def gen_random_str(length):
|
||||||
"""
|
"""
|
||||||
生成指定长度的随机字符串
|
生成指定长度的随机字符串
|
||||||
Args:
|
Args:
|
||||||
length: 指定长度
|
length: 指定长度
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
|
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
|
||||||
|
|
|
@ -17,25 +17,25 @@ __all__ = ['regex_extract']
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def regex_extract(string, pattern, group=None):
|
def regex_extract(string, pattern, group=None):
|
||||||
"""
|
"""
|
||||||
根据正则表达式提取内容
|
根据正则表达式提取内容
|
||||||
Args:
|
Args:
|
||||||
string: 字符串
|
string: 字符串
|
||||||
pattern: 正则表达式
|
pattern: 正则表达式
|
||||||
group: 分组组号
|
group: 分组组号
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not isinstance(string, str):
|
if not isinstance(string, str):
|
||||||
string = json.dumps(string, ensure_ascii=False)
|
string = json.dumps(string, ensure_ascii=False)
|
||||||
re_obj = re.search(pattern, string)
|
re_obj = re.search(pattern, string)
|
||||||
result = None
|
result = None
|
||||||
if re_obj:
|
if re_obj:
|
||||||
result = re_obj.group(0)
|
result = re_obj.group(0)
|
||||||
if group:
|
if group:
|
||||||
try:
|
try:
|
||||||
result = re_obj.group(group)
|
result = re_obj.group(group)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -16,48 +16,48 @@ logger = MyLogger()
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def substr(raw_str, start=None, end=None):
|
def substr(raw_str, start=None, end=None):
|
||||||
"""
|
"""
|
||||||
截取字符串
|
截取字符串
|
||||||
Args:
|
Args:
|
||||||
raw_str: 原始字符串
|
raw_str: 原始字符串
|
||||||
start: 字符串开始位置
|
start: 字符串开始位置
|
||||||
end: 字符串结束位置
|
end: 字符串结束位置
|
||||||
|
|
||||||
Returns: 截取的字符串
|
Returns: 截取的字符串
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
start = int(start) if (isinstance(start, str) and start.isdigit()) else start
|
start = int(start) if (isinstance(start, str) and start.isdigit()) else start
|
||||||
end = int(end) if (isinstance(end, str) and end.isdigit()) else end
|
end = int(end) if (isinstance(end, str) and end.isdigit()) else end
|
||||||
return raw_str[start:end]
|
return raw_str[start:end]
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def str_join(obj, connector=","):
|
def str_join(obj, connector=","):
|
||||||
"""
|
"""
|
||||||
连接任意数量的字符
|
连接任意数量的字符
|
||||||
Args:
|
Args:
|
||||||
obj: 被连接对象,类型:list、tuple
|
obj: 被连接对象,类型:list、tuple
|
||||||
connector: 连接符
|
connector: 连接符
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not isinstance(connector, str):
|
if not isinstance(connector, str):
|
||||||
connector = str(connector)
|
connector = str(connector)
|
||||||
if isinstance(obj, str):
|
if isinstance(obj, str):
|
||||||
return obj
|
return obj
|
||||||
elif isinstance(obj, (list, tuple)):
|
elif isinstance(obj, (list, tuple)):
|
||||||
temp_obj = []
|
temp_obj = []
|
||||||
for item in obj:
|
for item in obj:
|
||||||
if not isinstance(item, str):
|
if not isinstance(item, str):
|
||||||
item = str(item)
|
item = str(item)
|
||||||
temp_obj.append(item)
|
temp_obj.append(item)
|
||||||
return connector.join(temp_obj)
|
return connector.join(temp_obj)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
substr()
|
substr()
|
||||||
str_join()
|
str_join()
|
||||||
|
|
|
@ -16,45 +16,47 @@ __all__ = ['get_timestamp', 'ms_fmt_hms']
|
||||||
|
|
||||||
@logger.log_decorator("错误原因:时间戳的长度只能在10到16位之间,默认返回长度为13位的时间戳")
|
@logger.log_decorator("错误原因:时间戳的长度只能在10到16位之间,默认返回长度为13位的时间戳")
|
||||||
def get_timestamp(length=13):
|
def get_timestamp(length=13):
|
||||||
"""
|
"""
|
||||||
获取时间戳字符串,长度最多为16位;默认13位
|
获取时间戳字符串,长度最多为16位;默认13位
|
||||||
Args:
|
Returns:
|
||||||
length: 时间戳长度
|
|
||||||
|
Args:
|
||||||
Returns:
|
length: 时间戳长度
|
||||||
|
|
||||||
"""
|
Returns:
|
||||||
if isinstance(length, (int,)) and 10 <= length <= 16:
|
|
||||||
power = length - 10
|
"""
|
||||||
timestamp = time.time()
|
if isinstance(length, (int,)) and 10 <= length <= 16:
|
||||||
return int(timestamp * 10 ** power)
|
power = length - 10
|
||||||
else:
|
timestamp = time.time()
|
||||||
get_timestamp(13)
|
return int(timestamp * 10 ** power)
|
||||||
|
else:
|
||||||
|
get_timestamp(13)
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def ms_fmt_hms(ms):
|
def ms_fmt_hms(ms):
|
||||||
"""
|
"""
|
||||||
将毫秒转换成 h:m:s.ms格式字符串
|
将毫秒转换成 h:m:s.ms格式字符串
|
||||||
Args:
|
Args:
|
||||||
ms:
|
ms: 毫秒
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ms = int(ms)
|
ms = int(ms)
|
||||||
sec = ms // 1000
|
sec = ms // 1000
|
||||||
hour = sec // 3600
|
hour = sec // 3600
|
||||||
minute = (sec - hour * 3600) // 60
|
minute = (sec - hour * 3600) // 60
|
||||||
sec = sec % 60
|
sec = sec % 60
|
||||||
ms = ms % 1000
|
ms = ms % 1000
|
||||||
|
|
||||||
hour = str(hour).rjust(2, '0')
|
hour = str(hour).rjust(2, '0')
|
||||||
minute = str(minute).rjust(2, '0')
|
minute = str(minute).rjust(2, '0')
|
||||||
sec = str(sec).rjust(2, '0')
|
sec = str(sec).rjust(2, '0')
|
||||||
ms = str(ms).rjust(2, '0')
|
ms = str(ms).rjust(2, '0')
|
||||||
return f"{hour}:{minute}:{sec}.{ms}"
|
return f"{hour}:{minute}:{sec}.{ms}"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
get_timestamp()
|
get_timestamp()
|
||||||
|
|
|
@ -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 datetime
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
@ -6,109 +14,109 @@ import random
|
||||||
from faker import Faker
|
from faker import Faker
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'random_phone', 'random_gps',
|
'random_phone', 'random_gps',
|
||||||
"random_string", "random_ssn",
|
"random_string", "random_ssn",
|
||||||
"random_email", "random_id_card",
|
"random_email", "random_id_card",
|
||||||
"random_int", "random_male_name",
|
"random_int", "random_male_name",
|
||||||
"random_female_name", "random_current_time"
|
"random_female_name", "random_current_time"
|
||||||
]
|
]
|
||||||
|
|
||||||
f = Faker(locale='Zh-CN')
|
f = Faker(locale='Zh-CN')
|
||||||
|
|
||||||
|
|
||||||
def random_gps(base_log=None, base_lat=None, radius=None):
|
def random_gps(base_log=None, base_lat=None, radius=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
base_log:
|
base_log:
|
||||||
base_lat:
|
base_lat:
|
||||||
radius:
|
radius:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
radius_in_degrees = radius / 111300
|
radius_in_degrees = radius / 111300
|
||||||
u = float(random.uniform(0.0, 1.0))
|
u = float(random.uniform(0.0, 1.0))
|
||||||
v = float(random.uniform(0.0, 1.0))
|
v = float(random.uniform(0.0, 1.0))
|
||||||
w = radius_in_degrees * math.sqrt(u)
|
w = radius_in_degrees * math.sqrt(u)
|
||||||
t = 2 * math.pi * v
|
t = 2 * math.pi * v
|
||||||
x = w * math.cos(t)
|
x = w * math.cos(t)
|
||||||
y = w * math.sin(t)
|
y = w * math.sin(t)
|
||||||
longitude = y + base_log
|
longitude = y + base_log
|
||||||
latitude = x + base_lat
|
latitude = x + base_lat
|
||||||
# 这里是想保留6位小数点
|
# 这里是想保留6位小数点
|
||||||
loga = '%.6f' % longitude
|
loga = '%.6f' % longitude
|
||||||
lat = '%.6f' % latitude
|
lat = '%.6f' % latitude
|
||||||
return loga, lat
|
return loga, lat
|
||||||
|
|
||||||
|
|
||||||
def random_string():
|
def random_string():
|
||||||
"""
|
"""
|
||||||
:return:随机生成字符串,20位
|
:return:随机生成字符串,20位
|
||||||
"""
|
"""
|
||||||
return f.pystr()
|
return f.pystr()
|
||||||
|
|
||||||
|
|
||||||
def random_ssn():
|
def random_ssn():
|
||||||
"""
|
"""
|
||||||
:return:随机生成省份中
|
:return:随机生成省份中
|
||||||
"""
|
"""
|
||||||
return f.ssn()
|
return f.ssn()
|
||||||
|
|
||||||
|
|
||||||
def random_phone(self) -> int:
|
def random_phone(self) -> int:
|
||||||
"""
|
"""
|
||||||
:return: 随机生成手机号码
|
:return: 随机生成手机号码
|
||||||
"""
|
"""
|
||||||
return f.phone_number()
|
return f.phone_number()
|
||||||
|
|
||||||
|
|
||||||
def random_id_card(self) -> int:
|
def random_id_card(self) -> int:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:return: 随机生成身份证号码
|
:return: 随机生成身份证号码
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return f.ssn()
|
return f.ssn()
|
||||||
|
|
||||||
|
|
||||||
def random_female_name(self) -> str:
|
def random_female_name(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:return: 女生姓名
|
:return: 女生姓名
|
||||||
"""
|
"""
|
||||||
return f.name_male()
|
return f.name_male()
|
||||||
|
|
||||||
|
|
||||||
def random_male_name(self) -> str:
|
def random_male_name(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:return: 男生姓名
|
:return: 男生姓名
|
||||||
"""
|
"""
|
||||||
return f.name_female()
|
return f.name_female()
|
||||||
|
|
||||||
|
|
||||||
def random_email() -> str:
|
def random_email() -> str:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:return: 生成邮箱
|
:return: 生成邮箱
|
||||||
"""
|
"""
|
||||||
return f.email()
|
return f.email()
|
||||||
|
|
||||||
|
|
||||||
def random_current_time() -> datetime.datetime:
|
def random_current_time() -> datetime.datetime:
|
||||||
"""
|
"""
|
||||||
计算当前时间
|
计算当前时间
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return datetime.datetime.now()
|
return datetime.datetime.now()
|
||||||
|
|
||||||
|
|
||||||
def random_int():
|
def random_int():
|
||||||
"""随机生成 0 - 9999 的数字"""
|
"""随机生成 0 - 9999 的数字"""
|
||||||
return f.random_int()
|
return f.random_int()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print(random_current_time())
|
print(random_current_time())
|
||||||
|
|
|
@ -9,32 +9,37 @@
|
||||||
"""
|
"""
|
||||||
from common.crypto import logger
|
from common.crypto import logger
|
||||||
from common.crypto.encryption_rsa import Rsa
|
from common.crypto.encryption_rsa import Rsa
|
||||||
|
# from common.crypto.encryption_aes import DoAES
|
||||||
from extensions import sign
|
from extensions import sign
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
class EncryptData:
|
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()
|
def encrypts(self, headers_crypto, headers, request_data_crypto, request_data):
|
||||||
}
|
encryption_methods = {
|
||||||
|
"MD5": sign.md5_sign,
|
||||||
if headers_crypto:
|
"sha1": sign.sha1_sign,
|
||||||
encrypt_func = encryption_methods.get(headers_crypto)
|
"rsa": lambda data: Rsa(data).rsa_encrypt()
|
||||||
if encrypt_func:
|
}
|
||||||
try:
|
|
||||||
headers = encrypt_func(headers)
|
if headers_crypto:
|
||||||
except Exception as e:
|
encrypt_func = encryption_methods.get(headers_crypto)
|
||||||
logger.error(f"{headers_crypto} 加密失败:{e}")
|
if encrypt_func:
|
||||||
|
try:
|
||||||
if request_data_crypto:
|
headers = encrypt_func(headers)
|
||||||
encrypt_func = encryption_methods.get(request_data_crypto)
|
except Exception as e:
|
||||||
if encrypt_func:
|
logger.error(f"{headers_crypto} 加密失败:{e}")
|
||||||
try:
|
|
||||||
request_data = encrypt_func(request_data)
|
if request_data_crypto:
|
||||||
except Exception as e:
|
encrypt_func = encryption_methods.get(request_data_crypto)
|
||||||
logger.error(f"{request_data_crypto} 加密失败:{e}")
|
if encrypt_func:
|
||||||
|
try:
|
||||||
return headers, request_data
|
request_data = encrypt_func(request_data)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{request_data_crypto} 加密失败:{e}")
|
||||||
|
|
||||||
|
return headers, request_data
|
||||||
|
|
|
@ -41,7 +41,7 @@ class DoAES:
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# key = os.urandom(16) #随即产生n个字节的字符串,可以作为随机加密key使用
|
# key = os.urandom(16) #随即产生n个字节的字符串,可以作为随机加密key使用
|
||||||
key = '2l4LoWczlWxlMZJAAp5N0g6EygZZd9A6' # 随即产生n个字节的字符串,可以作为随机加密key使用
|
key = '2l4LoWczlWxlMZJAAp5N0g6EygZZd9C6' # 随即产生n个字节的字符串,可以作为随机加密key使用
|
||||||
text = '4534' # 需要加密的内容
|
text = '4534' # 需要加密的内容
|
||||||
aes_test = DoAES(key)
|
aes_test = DoAES(key)
|
||||||
cipher_text = aes_test.encrypt(text)
|
cipher_text = aes_test.encrypt(text)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -8,10 +8,9 @@
|
||||||
@desc:
|
@desc:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import hashlib
|
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
import rsa
|
import hashlib
|
||||||
|
|
||||||
from pyDes import des, CBC, PAD_PKCS5
|
from pyDes import des, CBC, PAD_PKCS5
|
||||||
|
|
||||||
|
@ -20,117 +19,117 @@ from pyDes import des, CBC, PAD_PKCS5
|
||||||
|
|
||||||
|
|
||||||
def bs64_data_encode(st):
|
def bs64_data_encode(st):
|
||||||
"""
|
"""
|
||||||
base64 加密
|
base64 加密
|
||||||
Args:
|
Args:
|
||||||
st:
|
st:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return base64.b64encode(st.encode("utf-8"))
|
return base64.b64encode(st.encode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
def bs64_data_decode(st):
|
def bs64_data_decode(st):
|
||||||
"""
|
"""
|
||||||
base64 解密
|
base64 解密
|
||||||
Args:
|
Args:
|
||||||
st:
|
st:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return base64.b64decode(st).decode()
|
return base64.b64decode(st).decode()
|
||||||
|
|
||||||
|
|
||||||
def md5(st: str) -> str:
|
def md5(st: str) -> str:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
st:待加密字符串
|
st:待加密字符串
|
||||||
|
|
||||||
Returns: 返回MD5 加密后的字符串
|
Returns: 返回MD5 加密后的字符串
|
||||||
|
|
||||||
"""
|
"""
|
||||||
md = hashlib.md5() # 创建MD5对象
|
md = hashlib.md5() # 创建MD5对象
|
||||||
md.update(st.encode(encoding="utf-8"))
|
md.update(st.encode(encoding="utf-8"))
|
||||||
return md.hexdigest()
|
return md.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def sha1_secret_str(st):
|
def sha1_secret_str(st):
|
||||||
"""
|
"""
|
||||||
使用sha1加密算法,返回str加密后的字符串
|
使用sha1加密算法,返回str加密后的字符串
|
||||||
Args:
|
Args:
|
||||||
st:
|
st:
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sha = hashlib.sha1(st.encode("utf-8"))
|
sha = hashlib.sha1(st.encode("utf-8"))
|
||||||
return sha.hexdigest()
|
return sha.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def sha256_single(st):
|
def sha256_single(st):
|
||||||
"""
|
"""
|
||||||
sha256加密
|
sha256加密
|
||||||
Args:
|
Args:
|
||||||
st: 加密字符串
|
st: 加密字符串
|
||||||
|
|
||||||
Returns:加密结果转换为16进制字符串,并大写
|
Returns:加密结果转换为16进制字符串,并大写
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sha_obj = hashlib.sha256()
|
sha_obj = hashlib.sha256()
|
||||||
sha_obj.update(st.encode("utf-8"))
|
sha_obj.update(st.encode("utf-8"))
|
||||||
return sha_obj.hexdigest().upper()
|
return sha_obj.hexdigest().upper()
|
||||||
|
|
||||||
|
|
||||||
class Des:
|
class Des:
|
||||||
def __init__(self, text, key):
|
def __init__(self, text, key):
|
||||||
self.text = text # 原始字符串
|
self.text = text # 原始字符串
|
||||||
self.KEY = key # 这个key是固定问开发,
|
self.KEY = key # 这个key是固定问开发,
|
||||||
|
|
||||||
def des_encrypt(self):
|
def des_encrypt(self):
|
||||||
"""DES 加密
|
"""DES 加密
|
||||||
Returns:加密后字符串,16进制
|
Returns:加密后字符串,16进制
|
||||||
|
|
||||||
"""
|
"""
|
||||||
secret_key = self.KEY # 密码
|
secret_key = self.KEY # 密码
|
||||||
iv = secret_key # 偏移
|
iv = secret_key # 偏移
|
||||||
# secret_key:加密密钥,CBC:加密模式,iv:偏移, padmode:填充
|
# secret_key:加密密钥,CBC:加密模式,iv:偏移, padmode:填充
|
||||||
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
|
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)
|
secret_bytes = des_obj.encrypt(self.text.encode("utf-8"), padmode=PAD_PKCS5)
|
||||||
# 返回为16进制
|
# 返回为16进制
|
||||||
return binascii.b2a_hex(secret_bytes)
|
return binascii.b2a_hex(secret_bytes)
|
||||||
|
|
||||||
def des_decrypt(self):
|
def des_decrypt(self):
|
||||||
"""
|
"""
|
||||||
DES 解密
|
DES 解密
|
||||||
Returns:解密后的字符串
|
Returns:解密后的字符串
|
||||||
|
|
||||||
"""
|
"""
|
||||||
secret_key = self.KEY
|
secret_key = self.KEY
|
||||||
iv = secret_key
|
iv = secret_key
|
||||||
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
|
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)
|
decrypt_str = des_obj.decrypt(binascii.a2b_hex(self.text), padmode=PAD_PKCS5)
|
||||||
return bytes.decode(decrypt_str) # bytes.decode() 将bit转为str
|
return bytes.decode(decrypt_str) # bytes.decode() 将bit转为str
|
||||||
|
|
||||||
|
|
||||||
def add_to_16(text: str):
|
def add_to_16(text: str):
|
||||||
"""
|
"""
|
||||||
使用空格补足16位数
|
使用空格补足16位数
|
||||||
Args:
|
Args:
|
||||||
text:源字符串
|
text:源字符串
|
||||||
|
|
||||||
Returns:补位后字符串
|
Returns:补位后字符串
|
||||||
|
|
||||||
"""
|
"""
|
||||||
b_text = text.encode("utf-8")
|
b_text = text.encode("utf-8")
|
||||||
add = 0
|
add = 0
|
||||||
# 计算需要补的位数
|
# 计算需要补的位数
|
||||||
if len(b_text) % 16:
|
if len(b_text) % 16:
|
||||||
add = 16 - len(b_text) % 16
|
add = 16 - len(b_text) % 16
|
||||||
return b_text + b'\0' * add
|
return b_text + b'\0' * add
|
||||||
|
|
||||||
# class AesEcb:
|
# class AesEcb:
|
||||||
#
|
#
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
# @Author : kira
|
# @Author : kira
|
||||||
# @Email : 262667641@qq.com
|
# @Email : 262667641@qq.com
|
||||||
# @File : analysis_json.py
|
# @File : analysis_json.py
|
||||||
# @Project : risk_api_project
|
|
||||||
"""
|
"""
|
||||||
接口返回的数据是 列表字典
|
接口返回的数据是 列表字典
|
||||||
新建两个函数 A 和 B,函数 A 处理字典数据,被调用后,判断传循环嵌套 格式的,通过一个 key 值,获取到被包裹了多层的目标数据
|
新建两个函数 A 和 B,函数 A 处理字典数据,被调用后,判断传循环嵌套 格式的,通过一个 key 值,获取到被包裹了多层的目标数据
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
# @Author : kira
|
# @Author : kira
|
||||||
# @Email : 262667641@qq.com
|
# @Email : 262667641@qq.com
|
||||||
# @File : assert_dict.py
|
# @File : assert_dict.py
|
||||||
# @Project : risk_api_project
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.append("../")
|
sys.path.append("../")
|
||||||
|
@ -14,103 +13,103 @@ from common.utils.singleton import singleton
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
class AssertDict(object):
|
class AssertDict(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_contain(expect_result, response_result):
|
def is_contain(expect_result, response_result):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
response_result:
|
response_result:
|
||||||
expect_result:
|
expect_result:
|
||||||
expect_result:
|
expect_result:
|
||||||
"""
|
"""
|
||||||
assert expect_result.items() <= response_result.items()
|
assert expect_result.items() <= response_result.items()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def assert_value(expect_result, response_result):
|
def assert_value(expect_result, response_result):
|
||||||
"""
|
"""
|
||||||
:param expect_result: 预期结果
|
:param expect_result: 预期结果
|
||||||
:param response_result: 响应结果
|
:param response_result: 响应结果
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
contain_expect_key_dict = [] # 所有预期结果的字典key
|
contain_expect_key_dict = [] # 所有预期结果的字典key
|
||||||
expect_value_list = [] # 所有预期结果的字典value
|
expect_value_list = [] # 所有预期结果的字典value
|
||||||
tmp_list = []
|
tmp_list = []
|
||||||
need_search_key = []
|
need_search_key = []
|
||||||
res_list = {}
|
res_list = {}
|
||||||
for key, value in expect_result.items():
|
for key, value in expect_result.items():
|
||||||
expect_value_list.append(value)
|
expect_value_list.append(value)
|
||||||
need_search_key.append(key)
|
need_search_key.append(key)
|
||||||
for expect_value in need_search_key:
|
for expect_value in need_search_key:
|
||||||
# 接收由预期key在实际响应中的所有值,返回的是一个[]
|
# 接收由预期key在实际响应中的所有值,返回的是一个[]
|
||||||
try:
|
try:
|
||||||
contain_expect_key_dict = (AnalysisJson().get_target_value(
|
contain_expect_key_dict = (AnalysisJson().get_target_value(
|
||||||
expect_value, response_result, tmp_list))
|
expect_value, response_result, tmp_list))
|
||||||
except Exception as identifier:
|
except Exception as identifier:
|
||||||
print("查找值异常:{}".format(contain_expect_key_dict))
|
print("查找值异常:{}".format(contain_expect_key_dict))
|
||||||
raise identifier
|
raise identifier
|
||||||
for each_value in expect_value_list:
|
for each_value in expect_value_list:
|
||||||
# 判断是否每一个由预期结果组成的列表中,每一个值都存在由预期key组成的实际结果列表中
|
# 判断是否每一个由预期结果组成的列表中,每一个值都存在由预期key组成的实际结果列表中
|
||||||
try:
|
try:
|
||||||
if each_value in contain_expect_key_dict:
|
if each_value in contain_expect_key_dict:
|
||||||
res_list["${}".format(each_value)] = True
|
res_list["${}".format(each_value)] = True
|
||||||
else:
|
else:
|
||||||
res_list["${}".format(each_value)] = False
|
res_list["${}".format(each_value)] = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("字典的key异常{}".format(each_value))
|
print("字典的key异常{}".format(each_value))
|
||||||
raise e
|
raise e
|
||||||
if False in res_list.values():
|
if False in res_list.values():
|
||||||
flag = 0
|
flag = 0
|
||||||
else:
|
else:
|
||||||
flag = 1
|
flag = 1
|
||||||
return flag, res_list
|
return flag, res_list
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
first = {
|
first = {
|
||||||
"data": [{
|
"data": [{
|
||||||
"saleRatio": "14.29",
|
"saleRatio": "14.29",
|
||||||
"weekDate": "2021-04-15"
|
"weekDate": "2021-04-15"
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
"weekDate": "2021-04-16",
|
"weekDate": "2021-04-16",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}, {
|
}, {
|
||||||
"weekDate": "2021-04-17",
|
"weekDate": "2021-04-17",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}, {
|
}, {
|
||||||
"weekDate": "2021-04-18",
|
"weekDate": "2021-04-18",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}, {
|
}, {
|
||||||
"weekDate": "2021-04-19",
|
"weekDate": "2021-04-19",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}, {
|
}, {
|
||||||
"weekDate": "2021-04-20",
|
"weekDate": "2021-04-20",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}, {
|
}, {
|
||||||
"weekDate": "2021-04-21",
|
"weekDate": "2021-04-21",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}],
|
}],
|
||||||
"status": 200
|
"status": 200
|
||||||
}
|
}
|
||||||
second = {"data": [{
|
second = {"data": [{
|
||||||
"weekDate": "2021-04-19",
|
"weekDate": "2021-04-19",
|
||||||
"saleRatio": "14.29"
|
"saleRatio": "14.29"
|
||||||
}], "status": 200}
|
}], "status": 200}
|
||||||
|
|
||||||
expect = {
|
expect = {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"code": 200,
|
"code": 200,
|
||||||
"message": "OK"
|
"message": "OK"
|
||||||
}
|
}
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"code": 200,
|
"code": 200,
|
||||||
"message": "OK",
|
"message": "OK",
|
||||||
"data": {
|
"data": {
|
||||||
"id": 123,
|
"id": 123,
|
||||||
"name": "John"
|
"name": "John"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print(AssertDict().assert_value(second, first))
|
print(AssertDict().assert_value(second, first))
|
||||||
print(AssertDict().assert_value(expect, response))
|
print(AssertDict().assert_value(expect, response))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Time: 2020/6/1/001 15:29
|
Time: 2020/6/1/001 15:29
|
||||||
Author: 陈勇志
|
Author: kira
|
||||||
Email:262667641@qq.com
|
Email:262667641@qq.com
|
||||||
Project:api_project
|
Project:api_project
|
||||||
"""
|
"""
|
||||||
|
@ -15,135 +15,137 @@ from jsonpath_ng import parse
|
||||||
from common.variables import Variables
|
from common.variables import Variables
|
||||||
from common.data_extraction import logger
|
from common.data_extraction import logger
|
||||||
|
|
||||||
# from common.http_client.http_client import Pyt
|
|
||||||
|
|
||||||
REPLACE_DICT = {
|
REPLACE_DICT = {
|
||||||
"null": None,
|
"null": None,
|
||||||
"True": True,
|
"True": True,
|
||||||
"false": False
|
"false": False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# d = Variables()
|
|
||||||
|
|
||||||
|
|
||||||
class DataExtractor(Variables):
|
class DataExtractor(Variables):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
# self.PATTERN = getattr(Variables, "PATTERN") # 预编译正则表达式
|
@logger.log_decorator("提取参数出现了意想不到的错误!!")
|
||||||
|
def substitute_data(self, response, regex=None, keys=None, deps=None, jp_dict=None):
|
||||||
@logger.log_decorator("提取参数出现了意想不到的错误!!")
|
"""
|
||||||
def substitute_data(self, response, regex=None, keys=None, deps=None, jp_dict=None):
|
方法接收一个正则表达式 regex 和一个关联参数表 deps,用于从接口返回的数据中提取关联参数。
|
||||||
"""
|
它会从接口返回的数据中使用正则表达式 regex 和正则表达式返回结果的键列表 keys 提取数据,并将其更新到关联参数表中。
|
||||||
方法接收一个正则表达式 regex 和一个关联参数表 deps,用于从接口返回的数据中提取关联参数。
|
然后,它会使用 subs_deps 和 subs_lists 方法提取更多的关联参数。最后,它将更新后的关联参数表设置为 Variables 类的静态变量,并将其返回
|
||||||
它会从接口返回的数据中使用正则表达式 regex 和正则表达式返回结果的键列表 keys 提取数据,并将其更新到关联参数表中。
|
Args:
|
||||||
然后,它会使用 subs_deps 和 subs_lists 方法提取更多的关联参数。最后,它将更新后的关联参数表设置为 Variables 类的静态变量,并将其返回
|
response: 被提取数据对象
|
||||||
Args:
|
regex: 正则表达式: r'"id": (\d+), "name": "(\w+)",'
|
||||||
response: 被提取数据对象
|
keys: 接收正则表达式返回结果的key: ["a", "b"]
|
||||||
regex: 正则表达式: r'"id": (\d+), "name": "(\w+)",'
|
deps: "name=data[0].name;ok=data[0].id;an=data[0].age[3].a"
|
||||||
keys: 接收正则表达式返回结果的key: ["a", "b"]
|
jp_dict: jsonpath 提取方式入参:{"k": "$.data", "x": "$.data[0].age[3].a"}
|
||||||
deps: "name=data[0].name;ok=data[0].id;an=data[0].age[3].a"
|
Returns:
|
||||||
jp_dict: jsonpath 提取方式入参:{"k": "$.data", "x": "$.data[0].age[3].a"}
|
"""
|
||||||
Returns:
|
|
||||||
"""
|
response = response
|
||||||
|
if not isinstance(response, (dict, str, list)):
|
||||||
response = response
|
logger.error(f"被提取对象非字典、非字符串、非列表,不执行jsonpath提取,被提取对象: {response}")
|
||||||
if not isinstance(response, (dict, str, list)):
|
return {}
|
||||||
logger.error(f"被提取对象非字典、非字符串、非列表,不执行jsonpath提取,被提取对象: {response}")
|
if regex and keys:
|
||||||
return {}
|
self.substitute_regex(response, regex, keys)
|
||||||
if regex and keys:
|
response = response if isinstance(response, (dict, list)) else json.loads(response)
|
||||||
self.substitute_regex(response, regex, keys)
|
if deps:
|
||||||
response = response if isinstance(response, (dict, list)) else json.loads(response)
|
self.substitute_route(response, deps)
|
||||||
if deps:
|
if jp_dict:
|
||||||
self.substitute_route(response, deps)
|
self.substitute_jsonpath(response, jp_dict)
|
||||||
if jp_dict:
|
|
||||||
self.substitute_jsonpath(response, jp_dict)
|
def substitute_regex(self, response, regex, keys):
|
||||||
|
"""
|
||||||
def substitute_regex(self, response, regex, keys):
|
方法用于使用正则表达式 regex 和正则表达式返回结果的键列表 keys 从接口返回的数据中提取数据,并将其更新到关联参数表中。
|
||||||
"""
|
Args:
|
||||||
方法用于使用正则表达式 regex 和正则表达式返回结果的键列表 keys 从接口返回的数据中提取数据,并将其更新到关联参数表中。
|
response:
|
||||||
Args:
|
regex: 正则表达式:r'"id": (\d+), "name": "(\w+)",'
|
||||||
response:
|
keys:结果键列表:["a", "b"],
|
||||||
regex: 正则表达式:r'"id": (\d+), "name": "(\w+)",'
|
Returns:
|
||||||
keys:结果键列表:["a", "b"],
|
|
||||||
Returns:
|
"""
|
||||||
|
response = json.dumps(response) if isinstance(response, (dict, list)) else response
|
||||||
"""
|
match = re.search(regex, response)
|
||||||
response = json.dumps(response) if isinstance(response, (dict, list)) else response
|
if not match:
|
||||||
match = re.search(regex, response)
|
return {}
|
||||||
if not match:
|
groups = match.groups()
|
||||||
return {}
|
for i, key in enumerate(keys):
|
||||||
groups = match.groups()
|
try:
|
||||||
for i, key in enumerate(keys):
|
self.update_variable(key, groups[i])
|
||||||
try:
|
except:
|
||||||
self.update_variable(key, groups[i])
|
self.update_variable(key, None)
|
||||||
except:
|
|
||||||
self.update_variable(key, None)
|
def substitute_route(self, response, route_str):
|
||||||
|
"""
|
||||||
def substitute_route(self, response, route_str):
|
想字典一样取值:name=data[0].name;ok=data[0].id;an=data[0].age
|
||||||
deps_list = re.sub(f"[\r\n]+", "", route_str).split(";")
|
Args:
|
||||||
for dep_item in deps_list:
|
response:
|
||||||
key, value_path = dep_item.split("=")
|
route_str:
|
||||||
value_path_parts = re.findall(r'\w+', value_path)
|
|
||||||
temp = response
|
Returns:
|
||||||
for part in value_path_parts:
|
|
||||||
if isinstance(temp, dict):
|
"""
|
||||||
temp = temp.get(part)
|
deps_list = re.sub(f"[\r\n]+", "", route_str).split(";")
|
||||||
elif isinstance(temp, list):
|
for dep_item in deps_list:
|
||||||
if part.isdigit():
|
key, value_path = dep_item.split("=")
|
||||||
index = int(part)
|
value_path_parts = re.findall(r'\w+', value_path)
|
||||||
if index < len(temp):
|
temp = response
|
||||||
temp = temp[index]
|
for part in value_path_parts:
|
||||||
else:
|
if isinstance(temp, dict):
|
||||||
temp = None
|
temp = temp.get(part)
|
||||||
break
|
elif isinstance(temp, list):
|
||||||
else:
|
if part.isdigit():
|
||||||
temp = None
|
index = int(part)
|
||||||
break
|
if index < len(temp):
|
||||||
else:
|
temp = temp[index]
|
||||||
temp = None
|
else:
|
||||||
break
|
temp = None
|
||||||
if isinstance(temp, (dict, list)):
|
break
|
||||||
continue
|
else:
|
||||||
else:
|
temp = None
|
||||||
break
|
break
|
||||||
if temp is not None:
|
else:
|
||||||
self.update_variable(key, temp)
|
temp = None
|
||||||
|
break
|
||||||
def substitute_jsonpath(self, response, json_path_dict):
|
if isinstance(temp, (dict, list)):
|
||||||
"""
|
continue
|
||||||
jsonpath 提取参数
|
else:
|
||||||
Args:
|
break
|
||||||
response: 响应结果
|
if temp is not None:
|
||||||
json_path_dict: {"k": "$.data", "x": "$.data[0].age[3].a"}
|
self.update_variable(key, temp)
|
||||||
|
|
||||||
Returns: 字符串或者list
|
def substitute_jsonpath(self, response, json_path_dict):
|
||||||
|
"""
|
||||||
"""
|
jsonpath 提取参数
|
||||||
|
Args:
|
||||||
json_path_dict = json_path_dict if isinstance(json_path_dict, dict) else json.loads(json_path_dict)
|
response: 响应结果
|
||||||
for key, expression in json_path_dict.items():
|
json_path_dict: {"k": "$.data", "x": "$.data[0].age[3].a"}
|
||||||
try:
|
|
||||||
parsed_expression = parse(expression)
|
Returns: 字符串或者list
|
||||||
data = response
|
|
||||||
# 使用解析器对象进行匹配和提取
|
"""
|
||||||
match = parsed_expression.find(data)
|
|
||||||
result = [m.value for m in match]
|
json_path_dict = json_path_dict if isinstance(json_path_dict, dict) else json.loads(json_path_dict)
|
||||||
self.update_variable(key, result[0]) if len(result) == 1 else self.update_variable(key,
|
for key, expression in json_path_dict.items():
|
||||||
result)
|
try:
|
||||||
except Exception as e:
|
parsed_expression = parse(expression)
|
||||||
logger.error(f"jsonpath表达式错误'{expression}': {e}")
|
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__':
|
if __name__ == '__main__':
|
||||||
# 测试subs函数
|
# 测试subs函数
|
||||||
res = '{"code": 1,"data": [{"id": 1, "name": "Alice", "age": [20, 21, 22, {"a": "b"}]}]}'
|
res = '{"code": 1,"data": [{"id": 1, "name": "Alice", "age": [20, 21, 22, {"a": "b"}]}]}'
|
||||||
lists = {"k": "$..code", "x": "$.data[0].age[3].a"}
|
lists = {"k": "$..code", "x": "$.data[0].age[3].a"}
|
||||||
dep_str = "name=data[0].name;ok=data[0].id;an=data[0].age"
|
dep_str = "name=data[0].name;ok=data[0].id;an=data[0].age"
|
||||||
regex_str = r'"id": (\d+), "name": "(\w+)",'
|
regex_str = r'"id": (\d+), "name": "(\w+)",'
|
||||||
regex_key = ["a", "b"]
|
regex_key = ["a", "b"]
|
||||||
t = DataExtractor()
|
t = DataExtractor()
|
||||||
t.substitute_data(res, regex=regex_str, keys=regex_key, deps=dep_str, jp_dict=lists)
|
t.substitute_data(res, regex=regex_str, keys=regex_key, deps=dep_str, jp_dict=lists)
|
||||||
print("-------->res:", t.get_variable())
|
print("-------->res:", t.get_variable())
|
||||||
|
|
|
@ -3,60 +3,59 @@
|
||||||
# @Author : kira
|
# @Author : kira
|
||||||
# @Email : 262667641@qq.com
|
# @Email : 262667641@qq.com
|
||||||
# @File : dict_get.py
|
# @File : dict_get.py
|
||||||
# @Project : api_project
|
|
||||||
|
|
||||||
|
|
||||||
def dict_get(dic, locators, default=None):
|
def dict_get(dic, locators, default=None):
|
||||||
"""
|
"""
|
||||||
以参数形式获取字典中特定的值
|
以参数形式获取字典中特定的值
|
||||||
:param dic: 输入需要在其中取值的原始字典 <dict>
|
:param dic: 输入需要在其中取值的原始字典 <dict>
|
||||||
:param locators: 输入取值定位器, 如:['result', 'msg', '-1', 'status'] <list>
|
:param locators: 输入取值定位器, 如:['result', 'msg', '-1', 'status'] <list>
|
||||||
:param default: 进行取值中报错时所返回的默认值 (default: None)
|
:param default: 进行取值中报错时所返回的默认值 (default: None)
|
||||||
:return: 返回根据参数locators找出的值
|
:return: 返回根据参数locators找出的值
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not isinstance(dic, dict) or not isinstance(locators, list):
|
if not isinstance(dic, dict) or not isinstance(locators, list):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
for locator in locators:
|
for locator in locators:
|
||||||
if not type(value) in [dict, list] and isinstance(locator, str) and not can_convert_to_int(locator):
|
if not type(value) in [dict, list] and isinstance(locator, str) and not can_convert_to_int(locator):
|
||||||
try:
|
try:
|
||||||
value = dic[locator]
|
value = dic[locator]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return default
|
return default
|
||||||
continue
|
continue
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
try:
|
try:
|
||||||
value = dict_get(value, [locator])
|
value = dict_get(value, [locator])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return default
|
return default
|
||||||
continue
|
continue
|
||||||
if isinstance(value, list) and can_convert_to_int(locator):
|
if isinstance(value, list) and can_convert_to_int(locator):
|
||||||
try:
|
try:
|
||||||
value = value[int(locator)]
|
value = value[int(locator)]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return default
|
return default
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def can_convert_to_int(input_s):
|
def can_convert_to_int(input_s):
|
||||||
try:
|
try:
|
||||||
int(input_s)
|
int(input_s)
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# dict_test = {"result": {"code": "110002", "msg": [{'status': 'ok'}, {'status': 'failed'}]}}
|
# dict_test = {"result": {"code": "110002", "msg": [{'status': 'ok'}, {'status': 'failed'}]}}
|
||||||
# result = dict_get(dict_test, ['result', 'msg', '-1', 'status'])
|
# result = dict_get(dict_test, ['result', 'msg', '-1', 'status'])
|
||||||
dict_test = {
|
dict_test = {
|
||||||
"data": {"result": [{"taskId": 1, "taskName": "2020-01-23 调研任务", "taskStatus": 2}], "totalCount": 1,
|
"data": {"result": [{"taskId": 1, "taskName": "2020-01-23 调研任务", "taskStatus": 2}], "totalCount": 1,
|
||||||
"pageSize": 20}, "taskId": 2, "msg": "操作成功!", "status": 200}
|
"pageSize": 20}, "taskId": 2, "msg": "操作成功!", "status": 200}
|
||||||
result = dict_get(dict_test, ['data', 'result', 0, 'taskId'])
|
result = dict_get(dict_test, ['data', 'result', 0, 'taskId'])
|
||||||
print(result)
|
print(result)
|
||||||
|
|
|
@ -8,43 +8,42 @@ from common.database import logger
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def execute_sql_files(sql_path, db_config):
|
def execute_sql_files(sql_path, db_config):
|
||||||
"""
|
"""
|
||||||
批量执行sql语句
|
批量执行sql语句
|
||||||
Args:
|
Args:
|
||||||
sql_path:文件夹
|
sql_path:文件夹
|
||||||
db_config: 数据库配置
|
db_config: 数据库配置
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
connection = pymysql.connect(**db_config)
|
connection = pymysql.connect(**db_config)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with connection.cursor() as cur:
|
with connection.cursor() as cur:
|
||||||
# 获取指定目录下的所有SQL文件
|
# 获取指定目录下的所有SQL文件
|
||||||
sql_files = glob.glob(os.path.join(sql_path, "*.sql"))
|
sql_files = glob.glob(os.path.join(sql_path, "*.sql"))
|
||||||
|
|
||||||
for file in sql_files:
|
for file in sql_files:
|
||||||
with open(file, "r", encoding="utf-8") as f:
|
with open(file, "r", encoding="utf-8") as f:
|
||||||
sql_statements = f.read().strip().split(";")
|
sql_statements = f.read().strip().split(";")
|
||||||
|
|
||||||
for sql_statement in sql_statements:
|
for sql_statement in sql_statements:
|
||||||
if sql_statement:
|
if sql_statement:
|
||||||
cur.execute(sql_statement)
|
cur.execute(sql_statement)
|
||||||
|
connection.commit()
|
||||||
connection.commit()
|
|
||||||
|
finally:
|
||||||
finally:
|
connection.close()
|
||||||
connection.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
config = {
|
config = {
|
||||||
"host": "xxxx.xxx.xxx.xx",
|
"host": "xxxx.xxx.xxx.xx",
|
||||||
"port": 3306,
|
"port": 3306,
|
||||||
"database": "db_name",
|
"database": "db_name",
|
||||||
"user": "root",
|
"user": "root",
|
||||||
"password": "xxxx"
|
"password": "xxxx"
|
||||||
}
|
}
|
||||||
|
|
||||||
execute_sql_files('./sql.sql', config)
|
execute_sql_files('./sql.sql', config)
|
||||||
|
|
|
@ -19,151 +19,144 @@ from common.utils.singleton import singleton
|
||||||
|
|
||||||
@singleton
|
@singleton
|
||||||
class MysqlClient:
|
class MysqlClient:
|
||||||
def __init__(self, db_config):
|
def __init__(self, db_config):
|
||||||
"""
|
"""
|
||||||
初始化连接配置
|
初始化连接配置
|
||||||
Args:
|
Args:
|
||||||
db_config: 数据库连接配置字典
|
db_config: 数据库连接配置字典
|
||||||
{
|
"""
|
||||||
"host": "xxxx.xxx.xxx.xx",
|
if not db_config:
|
||||||
"port": 3306,
|
return
|
||||||
"database": "db_name",
|
|
||||||
"user": "root",
|
try:
|
||||||
"password": "xxxx"
|
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:
|
||||||
if not db_config:
|
logger.error(f"数据库链接失败: {e}")
|
||||||
return
|
raise
|
||||||
|
|
||||||
try:
|
@logger.log_decorator()
|
||||||
self.db_base = db_config if isinstance(db_config, dict) else json.loads(db_config)
|
def execute_sql(self, sql):
|
||||||
self.pool = PooledDB(creator=pymysql, maxconnections=10, **self.db_base)
|
"""
|
||||||
except Exception as e:
|
执行 SQL 语句
|
||||||
logger.error(f"数据库链接失败: {e}")
|
|
||||||
raise
|
Args:
|
||||||
|
sql: SQL 语句字典
|
||||||
@logger.log_decorator()
|
{
|
||||||
def execute_sql(self, sql):
|
"delete": {
|
||||||
"""
|
"sql_name": "DELETE FROM table_name WHERE condition"
|
||||||
执行 SQL 语句
|
},
|
||||||
|
"update": {
|
||||||
Args:
|
"sql_name": "UPDATE table_name SET column1=value1 WHERE condition"
|
||||||
sql: SQL 语句字典
|
},
|
||||||
{
|
"insert": {
|
||||||
"delete": {
|
"sql_name": "INSERT INTO table_name (column1, column2) VALUES (value1, value2)"
|
||||||
"sql_name": "DELETE FROM table_name WHERE condition"
|
},
|
||||||
},
|
"select": {
|
||||||
"update": {
|
"sql_name": "SELECT * FROM table_name WHERE condition"
|
||||||
"sql_name": "UPDATE table_name SET column1=value1 WHERE condition"
|
}
|
||||||
},
|
}
|
||||||
"insert": {
|
|
||||||
"sql_name": "INSERT INTO table_name (column1, column2) VALUES (value1, value2)"
|
Returns:
|
||||||
},
|
执行结果字典
|
||||||
"select": {
|
{
|
||||||
"sql_name": "SELECT * FROM table_name WHERE condition"
|
"sql_name": [result1, result2, ...]
|
||||||
}
|
}
|
||||||
}
|
"""
|
||||||
|
if not sql:
|
||||||
Returns:
|
return
|
||||||
执行结果字典
|
|
||||||
{
|
try:
|
||||||
"sql_name": [result1, result2, ...]
|
conn = self.pool.connection()
|
||||||
}
|
cur = conn.cursor(DictCursor)
|
||||||
"""
|
|
||||||
if not sql:
|
result = {}
|
||||||
return
|
for method, sql_data in sql.items():
|
||||||
|
execute_method = getattr(self, f"_execute_{method}", None)
|
||||||
try:
|
if not execute_method:
|
||||||
conn = self.pool.connection()
|
logger.error("sql字典集编写格式不符合规范")
|
||||||
cur = conn.cursor(DictCursor)
|
raise ValueError("Invalid SQL method")
|
||||||
|
|
||||||
result = {}
|
execute_method(cur, sql_data, result)
|
||||||
for method, sql_data in sql.items():
|
|
||||||
execute_method = getattr(self, f"_execute_{method}", None)
|
cur.close()
|
||||||
if not execute_method:
|
conn.close()
|
||||||
logger.error("sql字典集编写格式不符合规范")
|
|
||||||
raise ValueError("Invalid SQL method")
|
return result
|
||||||
|
|
||||||
execute_method(cur, sql_data, result)
|
except Exception as e:
|
||||||
|
logger.error(f"数据库操作异常: {e}")
|
||||||
cur.close()
|
raise
|
||||||
conn.close()
|
|
||||||
|
def _execute_delete(self, cursor, sql_data, result):
|
||||||
return result
|
"""
|
||||||
|
执行 DELETE 语句
|
||||||
except Exception as e:
|
"""
|
||||||
logger.error(f"数据库操作异常: {e}")
|
for sql_name, sql_ in sql_data.items():
|
||||||
raise
|
try:
|
||||||
|
cursor.execute(str(sql_))
|
||||||
def _execute_delete(self, cursor, sql_data, result):
|
except Exception as err:
|
||||||
"""
|
logger.error(f"执行 SQL 异常: {sql_}")
|
||||||
执行 DELETE 语句
|
raise err
|
||||||
"""
|
cursor.connection.commit()
|
||||||
for sql_name, sql_ in sql_data.items():
|
|
||||||
try:
|
def _execute_update(self, cursor, sql_data, result):
|
||||||
cursor.execute(str(sql_))
|
"""
|
||||||
except Exception as err:
|
执行 UPDATE 语句
|
||||||
logger.error(f"执行 SQL 异常: {sql_}")
|
"""
|
||||||
raise err
|
self.execute_delete(cursor, sql_data, result)
|
||||||
cursor.connection.commit()
|
|
||||||
|
def _execute_insert(self, cursor, sql_data, result):
|
||||||
def _execute_update(self, cursor, sql_data, result):
|
"""
|
||||||
"""
|
执行 INSERT 语句
|
||||||
执行 UPDATE 语句
|
"""
|
||||||
"""
|
self.execute_delete(cursor, sql_data, result)
|
||||||
self.execute_delete(cursor, sql_data, result)
|
|
||||||
|
def _execute_select(self, cursor, sql_data, result):
|
||||||
def _execute_insert(self, cursor, sql_data, result):
|
"""
|
||||||
"""
|
执行 SELECT 语句
|
||||||
执行 INSERT 语句
|
|
||||||
"""
|
Args:
|
||||||
self.execute_delete(cursor, sql_data, result)
|
cursor: 数据库游标
|
||||||
|
sql_data: SQL 语句数据字典
|
||||||
def _execute_select(self, cursor, sql_data, result):
|
{
|
||||||
"""
|
"sql_name": "SELECT * FROM table_name WHERE condition"
|
||||||
执行 SELECT 语句
|
}
|
||||||
|
result: 字典结果
|
||||||
Args:
|
|
||||||
cursor: 数据库游标
|
Raises:
|
||||||
sql_data: SQL 语句数据字典
|
Exception: 执行异常
|
||||||
{
|
"""
|
||||||
"sql_name": "SELECT * FROM table_name WHERE condition"
|
for sql_name, sql_ in sql_data.items():
|
||||||
}
|
try:
|
||||||
result: 字典结果
|
cursor.execute(sql_)
|
||||||
|
result[sql_name] = cursor.fetchall()
|
||||||
Raises:
|
except Exception as err:
|
||||||
Exception: 执行异常
|
logger.error(f"查询异常 sql: {sql_}")
|
||||||
"""
|
raise err
|
||||||
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__':
|
if __name__ == '__main__':
|
||||||
sql_2 = {
|
sql_2 = {
|
||||||
"select":
|
"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": "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;"
|
"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 = {
|
database_2 = {
|
||||||
"host": "10.8.203.25",
|
"host": "10.10.10.10",
|
||||||
"port": 3306,
|
"port": 3306,
|
||||||
"database": "ibs_lms_base",
|
"database": "base",
|
||||||
"user": "root",
|
"user": "root",
|
||||||
"password": "gd1234"
|
"password": "roottttttttttttttttttttest"
|
||||||
}
|
}
|
||||||
res = MysqlClient(database_2).execute_sql(sql_2)
|
res = MysqlClient(database_2).execute_sql(sql_2)
|
||||||
print("数据执行结果", res)
|
print("数据执行结果", res)
|
||||||
from common.data_extraction.data_extractor import DataExtractor
|
from common.data_extraction.data_extractor import DataExtractor
|
||||||
from common.variables import Variables
|
from common.variables import Variables
|
||||||
|
|
||||||
t = DataExtractor()
|
t = DataExtractor()
|
||||||
t.substitute_data(res, jp_dict={"total": "$.select_sale[0].total", "total_1": "$..total"})
|
t.substitute_data(res, jp_dict={"total": "$.select_sale[0].total", "total_1": "$..total"})
|
||||||
print(Variables.get_variable())
|
print(Variables.get_variable())
|
||||||
|
|
|
@ -8,83 +8,87 @@ import redis
|
||||||
|
|
||||||
|
|
||||||
class RedisClient:
|
class RedisClient:
|
||||||
def __init__(self):
|
"""
|
||||||
self.redis = redis.Redis(host='10.8.203.25', port=6379, password='test2020')
|
redis数据库
|
||||||
|
"""
|
||||||
def set_data(self, key, value, expire_time=None):
|
|
||||||
self.redis.set(key, value)
|
def __init__(self):
|
||||||
if expire_time is not None:
|
self.redis = redis.Redis(host='1.1.3.5', port=6379, password='test')
|
||||||
self.redis.expire(key, expire_time)
|
|
||||||
|
def set_data(self, key, value, expire_time=None):
|
||||||
def get_data(self, key):
|
self.redis.set(key, value)
|
||||||
return self.redis.get(key)
|
if expire_time is not None:
|
||||||
|
self.redis.expire(key, expire_time)
|
||||||
def delete_data(self, key):
|
|
||||||
self.redis.delete(key)
|
def get_data(self, key):
|
||||||
|
return self.redis.get(key)
|
||||||
def hash_set_field(self, key, field, value):
|
|
||||||
self.redis.hset(key, field, value)
|
def delete_data(self, key):
|
||||||
|
self.redis.delete(key)
|
||||||
def hash_get_field(self, key, field):
|
|
||||||
return self.redis.hget(key, field)
|
def hash_set_field(self, key, field, value):
|
||||||
|
self.redis.hset(key, field, value)
|
||||||
def hash_delete_field(self, key, field):
|
|
||||||
self.redis.hdel(key, field)
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
# r = redis.Redis(host='10.8.203.25', port=6379, password='test2020')
|
# r = redis.Redis(host='10.8.203.25', port=6379, password='test2020')
|
||||||
|
|
||||||
# print(r.select(1)) # 切数据库1
|
# print(r.select(1)) # 切数据库1
|
||||||
# print(r.dbsize()) # 看 db 大小
|
# print(r.dbsize()) # 看 db 大小
|
||||||
#
|
#
|
||||||
# # 设置键为"key1"的字符串值为"Hello, Redis!"
|
# # 设置键为"key1"的字符串值为"Hello, Redis!"
|
||||||
# r.set('key1', 'Hello, Redis!')
|
# r.set('key1', 'Hello, Redis!')
|
||||||
#
|
#
|
||||||
# # 获取键为"key1"的字符串值
|
# # 获取键为"key1"的字符串值
|
||||||
# value = r.get('key1')
|
# value = r.get('key1')
|
||||||
# print(value) # 输出: b'Hello, Redis!'
|
# print(value) # 输出: b'Hello, Redis!'
|
||||||
#
|
#
|
||||||
# # 向名为"list1"的列表左侧插入元素
|
# # 向名为"list1"的列表左侧插入元素
|
||||||
# r.lpush('list1', 'item1')
|
# r.lpush('list1', 'item1')
|
||||||
# r.lpush('list1', 'item2')
|
# r.lpush('list1', 'item2')
|
||||||
# r.lpush('list1', 'item3')
|
# r.lpush('list1', 'item3')
|
||||||
#
|
#
|
||||||
# # 获取名为"list1"的列表所有元素
|
# # 获取名为"list1"的列表所有元素
|
||||||
# items = r.lrange('list1', 0, -1)
|
# items = r.lrange('list1', 0, -1)
|
||||||
# print(items) # 输出: [b'item3', b'item2', b'item1']
|
# print(items) # 输出: [b'item3', b'item2', b'item1']
|
||||||
#
|
#
|
||||||
# # 设置名为"hash1"的哈希表字段和值
|
# # 设置名为"hash1"的哈希表字段和值
|
||||||
# r.hset('hash1', 'field1', 'value1')
|
# r.hset('hash1', 'field1', 'value1')
|
||||||
# r.hset('hash1', 'field2', 'value2')
|
# r.hset('hash1', 'field2', 'value2')
|
||||||
#
|
#
|
||||||
# # 获取名为"hash1"的哈希表字段和值
|
# # 获取名为"hash1"的哈希表字段和值
|
||||||
# value1 = r.hget('hash1', 'field1')
|
# value1 = r.hget('hash1', 'field1')
|
||||||
# value2 = r.hget('hash1', 'field2')
|
# value2 = r.hget('hash1', 'field2')
|
||||||
# values = r.hgetall('hash1')
|
# values = r.hgetall('hash1')
|
||||||
# print(value1, value2) # 输出: b'value1' b'value2
|
# print(value1, value2) # 输出: b'value1' b'value2
|
||||||
# print(values) # 输出:{b'field1': b'value1', b'field2': b'value2'}
|
# print(values) # 输出:{b'field1': b'value1', b'field2': b'value2'}
|
||||||
#
|
#
|
||||||
# # 向名为"set1"的集合添加元素
|
# # 向名为"set1"的集合添加元素
|
||||||
# r.sadd('set1', 'item1')
|
# r.sadd('set1', 'item1')
|
||||||
# r.sadd('set1', 'item2')
|
# r.sadd('set1', 'item2')
|
||||||
# r.sadd('set1', 'item3')
|
# r.sadd('set1', 'item3')
|
||||||
#
|
#
|
||||||
# # 获取名为"set1"的集合所有元素
|
# # 获取名为"set1"的集合所有元素
|
||||||
# items = r.smembers('set1')
|
# items = r.smembers('set1')
|
||||||
# print(items) # 输出: {b'item1', b'item2', b'item3'}
|
# print(items) # 输出: {b'item1', b'item2', b'item3'}
|
||||||
redis_client = RedisClient()
|
redis_client = RedisClient()
|
||||||
|
|
||||||
redis_client.set_data('user1', '100', 3600)
|
redis_client.set_data('user1', '100', 3600)
|
||||||
|
|
||||||
|
|
||||||
def get_user_info(user_id):
|
def get_user_info(user_id):
|
||||||
cache_key = f'user1:{user_id}'
|
cache_key = f'user1:{user_id}'
|
||||||
user_info = redis_client.get_data(cache_key)
|
user_info = redis_client.get_data(cache_key)
|
||||||
if not user_info:
|
if not user_info:
|
||||||
print("--")
|
print("--")
|
||||||
print(f'{user_info}')
|
print(f'{user_info}')
|
||||||
|
|
||||||
|
|
||||||
get_user_info(100)
|
get_user_info(100)
|
||||||
|
|
|
@ -29,36 +29,10 @@ class DoExcel:
|
||||||
# def __exit__(self, exc_type, exc_val, exc_tb):
|
# def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
# self.wb.save(self.file_name)
|
# self.wb.save(self.file_name)
|
||||||
# self.wb.close()
|
# 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):
|
def do_excel_yield(self):
|
||||||
"""
|
"""
|
||||||
读取excel数据的生成器
|
读取excel数据
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,10 +8,8 @@ import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# 把当前目录加入到系统环境变量中
|
|
||||||
sys.path.append(os.path.split(os.path.dirname(os.path.abspath(__file__)))[0])
|
sys.path.append(os.path.split(os.path.dirname(os.path.abspath(__file__)))[0])
|
||||||
sys.path.append("../..")
|
sys.path.append("../..")
|
||||||
# sys.path.append('venv/Lib/site-packages')
|
|
||||||
from openpyxl import load_workbook, Workbook
|
from openpyxl import load_workbook, Workbook
|
||||||
from common.file_handling import logger
|
from common.file_handling import logger
|
||||||
|
|
||||||
|
|
|
@ -16,156 +16,156 @@ import yaml
|
||||||
|
|
||||||
|
|
||||||
class FileUtils:
|
class FileUtils:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_all_path(open_file_path):
|
def get_all_path(open_file_path):
|
||||||
"""
|
"""
|
||||||
递归获取目录下所有的文件的路径
|
递归获取目录下所有的文件的路径
|
||||||
Args:
|
Args:
|
||||||
open_file_path: 指定目录路径
|
open_file_path: 指定目录路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
包含所有文件路径的列表
|
包含所有文件路径的列表
|
||||||
"""
|
"""
|
||||||
path_list = []
|
path_list = []
|
||||||
for root, dirs, files in os.walk(open_file_path):
|
for root, dirs, files in os.walk(open_file_path):
|
||||||
path_list.extend([os.path.join(root, file) for file in files])
|
path_list.extend([os.path.join(root, file) for file in files])
|
||||||
return path_list
|
return path_list
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_files_in_folder(folder_path):
|
def get_files_in_folder(folder_path):
|
||||||
"""
|
"""
|
||||||
获取指定文件夹内的所有文件
|
获取指定文件夹内的所有文件
|
||||||
Args:
|
Args:
|
||||||
folder_path: 指定文件夹路径
|
folder_path: 指定文件夹路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
包含所有文件名的列表
|
包含所有文件名的列表
|
||||||
"""
|
"""
|
||||||
if not os.path.isdir(folder_path):
|
if not os.path.isdir(folder_path):
|
||||||
raise ValueError("Invalid folder path")
|
raise ValueError("Invalid folder path")
|
||||||
file_list = []
|
file_list = []
|
||||||
for filename in os.listdir(folder_path):
|
for filename in os.listdir(folder_path):
|
||||||
file_path = os.path.join(folder_path, filename)
|
file_path = os.path.join(folder_path, filename)
|
||||||
if os.path.isfile(file_path):
|
if os.path.isfile(file_path):
|
||||||
file_list.append(filename)
|
file_list.append(filename)
|
||||||
return file_list
|
return file_list
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_folders_in_path(dir_path):
|
def get_folders_in_path(dir_path):
|
||||||
"""
|
"""
|
||||||
获取指定路径下的所有文件夹
|
获取指定路径下的所有文件夹
|
||||||
Args:
|
Args:
|
||||||
dir_path: 指定路径
|
dir_path: 指定路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
包含所有文件夹名的列表
|
包含所有文件夹名的列表
|
||||||
"""
|
"""
|
||||||
if not os.path.isdir(dir_path):
|
if not os.path.isdir(dir_path):
|
||||||
raise ValueError("Invalid directory path")
|
raise ValueError("Invalid directory path")
|
||||||
folder_list = []
|
folder_list = []
|
||||||
for foldername in os.listdir(dir_path):
|
for foldername in os.listdir(dir_path):
|
||||||
folder_path = os.path.join(dir_path, foldername)
|
folder_path = os.path.join(dir_path, foldername)
|
||||||
if os.path.isdir(folder_path):
|
if os.path.isdir(folder_path):
|
||||||
folder_list.append(foldername)
|
folder_list.append(foldername)
|
||||||
return folder_list
|
return folder_list
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_file(file_path):
|
def read_file(file_path):
|
||||||
"""
|
"""
|
||||||
读取文件内容
|
读取文件内容
|
||||||
Args:
|
Args:
|
||||||
file_path: 文件路径
|
file_path: 文件路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
文件内容的字符串
|
文件内容的字符串
|
||||||
"""
|
"""
|
||||||
if not os.path.isfile(file_path):
|
if not os.path.isfile(file_path):
|
||||||
raise ValueError("Invalid file path")
|
raise ValueError("Invalid file path")
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_json_file(file_path):
|
def read_json_file(file_path):
|
||||||
"""
|
"""
|
||||||
读取 JSON 文件
|
读取 JSON 文件
|
||||||
Args:
|
Args:
|
||||||
file_path: JSON 文件路径
|
file_path: JSON 文件路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
解析后的 JSON 数据
|
解析后的 JSON 数据
|
||||||
"""
|
"""
|
||||||
content = FileUtils.read_file(file_path)
|
content = FileUtils.read_file(file_path)
|
||||||
try:
|
try:
|
||||||
return json.loads(content)
|
return json.loads(content)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
raise ValueError("Invalid JSON file: {}".format(e))
|
raise ValueError("Invalid JSON file: {}".format(e))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_yaml_file(file_path):
|
def read_yaml_file(file_path):
|
||||||
"""
|
"""
|
||||||
读取 YAML 文件
|
读取 YAML 文件
|
||||||
Args:
|
Args:
|
||||||
file_path: YAML 文件路径
|
file_path: YAML 文件路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
解析后的 YAML 数据
|
解析后的 YAML 数据
|
||||||
"""
|
"""
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
return yaml.safe_load(f)
|
return yaml.safe_load(f)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_value_from_dict(data, key_path):
|
def get_value_from_dict(data, key_path):
|
||||||
"""
|
"""
|
||||||
从嵌套字典中获取指定键路径的值
|
从嵌套字典中获取指定键路径的值
|
||||||
Args:
|
Args:
|
||||||
data: 嵌套字典
|
data: 嵌套字典
|
||||||
key_path: 键路径,可以是用点分隔的字符串或字符串列表
|
key_path: 键路径,可以是用点分隔的字符串或字符串列表
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
指定键路径的值,如果路径不存在则返回 None
|
指定键路径的值,如果路径不存在则返回 None
|
||||||
"""
|
"""
|
||||||
if isinstance(key_path, str):
|
if isinstance(key_path, str):
|
||||||
key_path = key_path.split('.')
|
key_path = key_path.split('.')
|
||||||
|
|
||||||
for key in key_path:
|
for key in key_path:
|
||||||
if isinstance(data, dict) and key in data:
|
if isinstance(data, dict) and key in data:
|
||||||
data = data[key]
|
data = data[key]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_config_data(file_path, section, option):
|
def read_config_data(file_path, section, option):
|
||||||
"""
|
"""
|
||||||
读取配置文件中的数据
|
读取配置文件中的数据
|
||||||
Args:
|
Args:
|
||||||
file_path: 配置文件路径
|
file_path: 配置文件路径
|
||||||
section: 文件中的 section
|
section: 文件中的 section
|
||||||
option: 文件中的 option
|
option: 文件中的 option
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
配置文件中指定数据的值
|
配置文件中指定数据的值
|
||||||
"""
|
"""
|
||||||
cf = RawConfigParser()
|
cf = RawConfigParser()
|
||||||
cf.read(file_path, encoding="UTF-8")
|
cf.read(file_path, encoding="UTF-8")
|
||||||
return eval(cf.get(section, option))
|
return eval(cf.get(section, option))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_json_data(file_path):
|
def read_json_data(file_path):
|
||||||
"""
|
"""
|
||||||
读取 JSON 文件中的数据
|
读取 JSON 文件中的数据
|
||||||
Args:
|
Args:
|
||||||
file_path: JSON 文件路径
|
file_path: JSON 文件路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
JSON 文件中的数据
|
JSON 文件中的数据
|
||||||
"""
|
"""
|
||||||
with open(file_path, "r", encoding="utf-8") as fb:
|
with open(file_path, "r", encoding="utf-8") as fb:
|
||||||
return json.load(fb)
|
return json.load(fb)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
fu = FileUtils()
|
fu = FileUtils()
|
||||||
rest = fu.read_yaml_file(r'../../config.yaml')
|
rest = fu.read_yaml_file(r'../../config.yaml')
|
||||||
print(rest)
|
print(rest)
|
||||||
|
|
|
@ -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)
|
|
|
@ -10,90 +10,79 @@ sys.path.append("../")
|
||||||
sys.path.append("./common")
|
sys.path.append("./common")
|
||||||
|
|
||||||
from common.http_client import logger
|
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
|
from common.validation.load_modules_from_folder import LoadModulesFromFolder
|
||||||
|
|
||||||
|
|
||||||
# @singleton
|
|
||||||
class Pyt(LoadModulesFromFolder):
|
class Pyt(LoadModulesFromFolder):
|
||||||
# 类属性,保存一个会话对象,防止每次都创建一个新的会话,节省资源
|
# 类属性,保存一个会话对象,防止每次都创建一个新的会话,节省资源
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.request = None
|
self.request = None
|
||||||
self.response = None
|
self.response = None
|
||||||
|
|
||||||
# @staticmethod
|
# @staticmethod
|
||||||
def log_decorator(msg="请求异常"):
|
def log_decorator(msg="请求异常"):
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
try:
|
try:
|
||||||
print(f"发送请求的参数: {kwargs}")
|
print(f"发送请求的参数: {kwargs}")
|
||||||
response = func(*args, **kwargs)
|
response = func(*args, **kwargs)
|
||||||
print(f"请求地址 --> {response.request.url}")
|
print(f"请求地址 --> {response.request.url}")
|
||||||
print(f"请求头 --> {response.request.headers}")
|
print(f"请求头 --> {response.request.headers}")
|
||||||
print(f"请求 body --> {response.request.body}")
|
print(f"请求 body --> {response.request.body}")
|
||||||
print(f"接口状态--> {response.status_code}")
|
print(f"接口状态--> {response.status_code}")
|
||||||
print(f"接口耗时--> {response.elapsed}")
|
print(f"接口耗时--> {response.elapsed}")
|
||||||
print(f"接口响应--> {response.text}")
|
print(f"接口响应--> {response.text}")
|
||||||
return response
|
return response
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"发送请求失败: {e}")
|
logger.error(f"发送请求失败: {e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
# @log_decorator()
|
# @log_decorator()
|
||||||
def http_client(self, host, url, method, **kwargs):
|
def http_client(self, host, url, method, **kwargs):
|
||||||
"""
|
"""
|
||||||
发送 http 请求
|
发送 http 请求
|
||||||
@param host: 域名
|
@param host: 域名
|
||||||
@param __url: 接口 __url
|
@param url: 接口 __url
|
||||||
@param method: http 请求方法
|
@param method: http 请求方法
|
||||||
# @param request_data_type: 请求数据类型
|
@param kwargs: 接受 requests 原生的关键字参数
|
||||||
# @param headers: 请求头部信息,默认为 None
|
@return: 响应对象
|
||||||
@param kwargs: 接受 requests 原生的关键字参数
|
"""
|
||||||
@return: 响应对象
|
# 关闭 https 警告信息
|
||||||
"""
|
urllib3.disable_warnings()
|
||||||
# 关闭 https 警告信息
|
|
||||||
urllib3.disable_warnings()
|
if not url:
|
||||||
|
raise ValueError("URL cannot be None")
|
||||||
if not url:
|
__url = f'{host}{url}' if not re.match(r"https?", url) else url
|
||||||
raise ValueError("URL cannot be None")
|
|
||||||
__url = f'{host}{url}' if not re.match(r"https?", url) else url
|
# 增加兼容
|
||||||
# 获取session 中的请求方法
|
# 处理 headers 参数为字符串类型的情况
|
||||||
# func = getattr(session, method.lower())
|
if 'headers' in kwargs and isinstance(kwargs['headers'], str):
|
||||||
|
kwargs['headers'] = json.loads(kwargs['headers'])
|
||||||
# 增加兼容
|
|
||||||
# 处理 headers 参数为字符串类型的情况
|
# 处理 json 参数为字符串类型的情况
|
||||||
if 'headers' in kwargs and isinstance(kwargs['headers'], str):
|
if 'json' in kwargs and isinstance(kwargs['json'], str):
|
||||||
kwargs['headers'] = json.loads(kwargs['headers'])
|
kwargs['json'] = json.loads(kwargs['json'])
|
||||||
|
|
||||||
# 处理 json 参数为字符串类型的情况
|
# 发送请求
|
||||||
if 'json' in kwargs and isinstance(kwargs['json'], str):
|
self.request = requests.Request(method, __url, **kwargs)
|
||||||
kwargs['json'] = json.loads(kwargs['json'])
|
self.response = self.session.send(self.request.prepare(), timeout=30, verify=True)
|
||||||
|
|
||||||
# 发送请求
|
return self.response
|
||||||
# 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__':
|
if __name__ == '__main__':
|
||||||
hst = 'https://ibs-test.bzlrobot.com'
|
hst = 'https://baidu.com'
|
||||||
url = '/api/ibs-auth/ibs_platform/login?t=168672334'
|
url = '/login?t=168672334'
|
||||||
method = 'post'
|
method = 'post'
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'json': '{"account": "luoshunwen005", "grantType": "password", "isBip": "false","password": "o+t2SnEEylblxlfIspJUvGFa0gCDNrU2dC34LjVFqIiTmxa855YDBE/6J7eRVBGaQwR7mozSKComk9n6kjSNRjSX1m574dRZdESIeYsmM/xk2Nt5n5dqB268qCMivJMXpHQMygpT4RpDiYoOiEqlOi9eG5G7v/5rixHiZ9xv98m34xVD1VdlaCbphoB9JI7T9HmVFJniSWt01ruC5t+aFUvfxLjOpRmYmfz8GwtSd5XXKaKr29ce1C39Fg+PtqOkQ3cOLVS9hXgzz6s2zud0++T4vwgVtrHx86aMrrozhCdKzrQuWPEO1cSsaEaNVdSUsT54je+4O+xKzxkJhoGMnQ=="}',
|
'json': '{"account": "kira","password": "9999999"}',
|
||||||
'headers': None}
|
'headers': None}
|
||||||
pyt = Pyt()
|
pyt = Pyt()
|
||||||
pyt.http_client(hst, url, method, **kwargs)
|
pyt.http_client(hst, url, method, **kwargs)
|
||||||
# print(pyt.request.json)
|
|
||||||
# print(pyt.request.headers)
|
|
||||||
# print(pyt.response.text)
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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())
|
|
|
@ -8,7 +8,6 @@ class Hooks:
|
||||||
注册 before_request 钩子函数,将其添加到 before_request_funcs 列表中
|
注册 before_request 钩子函数,将其添加到 before_request_funcs 列表中
|
||||||
"""
|
"""
|
||||||
self.before_request_funcs.append(func)
|
self.before_request_funcs.append(func)
|
||||||
print(self.before_request_funcs)
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def after_request(self, func):
|
def after_request(self, func):
|
||||||
|
@ -16,7 +15,6 @@ class Hooks:
|
||||||
注册 after_request 钩子函数,将其添加到 after_request_funcs 列表中
|
注册 after_request 钩子函数,将其添加到 after_request_funcs 列表中
|
||||||
"""
|
"""
|
||||||
self.after_request_funcs.append(func)
|
self.after_request_funcs.append(func)
|
||||||
print(self.after_request_funcs)
|
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def run_before_request_funcs(self, request):
|
def run_before_request_funcs(self, request):
|
||||||
|
|
|
@ -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 or sha1
|
|
||||||
else:
|
|
||||||
request.data = dep_par.replace_dependent_parameter(request.data)
|
|
||||||
if request.encryption:
|
|
||||||
request.data = do_encrypt(request.encryption, request.data) # 数据加密:MD5 or sha1
|
|
||||||
|
|
||||||
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
|
|
|
@ -23,8 +23,7 @@ class WxWorkSms:
|
||||||
self.send_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={key}"
|
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"
|
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,
|
def send_markdown(self, project_name, project_port, total_cases, pass_rate, success_cases, fail_cases, skip_cases,
|
||||||
skip_cases,
|
|
||||||
error_cases, report_url):
|
error_cases, report_url):
|
||||||
"""
|
"""
|
||||||
发送markdown 请求
|
发送markdown 请求
|
||||||
|
@ -107,4 +106,4 @@ class WxWorkSms:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
dirs = r'D:\apk_api\api-test-project\OutPut\Reports'
|
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_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)
|
||||||
|
|
|
@ -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
|
|
|
@ -17,14 +17,15 @@ class ScriptNotFoundError(Exception):
|
||||||
class LoadScript:
|
class LoadScript:
|
||||||
# @logger.log_decorator()
|
# @logger.log_decorator()
|
||||||
def load_script(self, script_path):
|
def load_script(self, script_path):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
加载脚本文件并返回模块对象
|
加载脚本文件并返回模块对象
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
script_path (str): 脚本文件的路径
|
script_path (str): 脚本文件的路径
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
module: 脚本文件对应的模块对象
|
module: 脚本文件对应的模块对象
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
spec = importlib.util.spec_from_file_location(os.path.basename(script_path), script_path)
|
spec = importlib.util.spec_from_file_location(os.path.basename(script_path), script_path)
|
||||||
|
@ -33,17 +34,17 @@ class LoadScript:
|
||||||
return script_module
|
return script_module
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
raise ScriptNotFoundError(script_path)
|
raise ScriptNotFoundError(script_path)
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def load_and_execute_script(self, script_directory, script_name, method_name, request):
|
def load_and_execute_script(self, script_directory, script_name, method_name, request):
|
||||||
"""
|
"""
|
||||||
加载并执行脚本文件中的指定方法
|
加载并执行脚本文件中的指定方法
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request: 请求数据
|
request: 请求数据
|
||||||
script_directory (str): 脚本文件所在的目录
|
script_directory (str): 脚本文件所在的目录
|
||||||
script_name (str): 脚本文件的名称
|
script_name (str): 脚本文件的名称
|
||||||
method_name (str): 要执行的方法的名称
|
method_name (str): 要执行的方法的名称
|
||||||
"""
|
"""
|
||||||
script_path = os.path.join(script_directory, script_name)
|
script_path = os.path.join(script_directory, script_name)
|
||||||
try:
|
try:
|
||||||
|
@ -57,7 +58,7 @@ class LoadScript:
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from common.config import Config
|
from common.config import Config
|
||||||
|
|
||||||
SCRIPTS_DIR = Config.SCRIPTS_DIR
|
SCRIPTS_DIR = Config.SCRIPTS_DIR
|
||||||
load_and_exe_s = LoadScript()
|
load_and_exe_s = LoadScript()
|
||||||
load_and_exe_s.load_and_execute_script(SCRIPTS_DIR, 'request_script_sheetname_id.py', 'setup', {"y": "z"})
|
load_and_exe_s.load_and_execute_script(SCRIPTS_DIR, 'request_script_sheetname_id.py', 'setup', {"y": "z"})
|
||||||
|
|
|
@ -21,7 +21,7 @@ class MyLog:
|
||||||
"error": logging.ERROR,
|
"error": logging.ERROR,
|
||||||
"critic": logging.CRITICAL
|
"critic": logging.CRITICAL
|
||||||
} # 日志级别关系映射
|
} # 日志级别关系映射
|
||||||
|
|
||||||
def my_log(self, msg, level="error", when="D", back_count=10):
|
def my_log(self, msg, level="error", when="D", back_count=10):
|
||||||
"""
|
"""
|
||||||
实例化 TimeRotatingFileHandler
|
实例化 TimeRotatingFileHandler
|
||||||
|
@ -34,10 +34,10 @@ class MyLog:
|
||||||
midnight 每天凌晨
|
midnight 每天凌晨
|
||||||
"""
|
"""
|
||||||
file_name = Config.log_path
|
file_name = Config.log_path
|
||||||
|
|
||||||
my_logger = logging.getLogger() # 定义日志收集器 my_logger
|
my_logger = logging.getLogger() # 定义日志收集器 my_logger
|
||||||
my_logger.setLevel(self.level_relations.get(level)) # 设置日志级别
|
my_logger.setLevel(self.level_relations.get(level)) # 设置日志级别
|
||||||
|
|
||||||
format_str = logging.Formatter(
|
format_str = logging.Formatter(
|
||||||
"%(asctime)s-%(levelname)s-%(filename)s-[ line:%(lineno)d ] - 日志信息:%(message)s") # 设置日志格式
|
"%(asctime)s-%(levelname)s-%(filename)s-[ line:%(lineno)d ] - 日志信息:%(message)s") # 设置日志格式
|
||||||
# 创建输出渠道
|
# 创建输出渠道
|
||||||
|
@ -45,19 +45,16 @@ class MyLog:
|
||||||
sh.setFormatter(format_str) # 设置屏幕上显示的格式
|
sh.setFormatter(format_str) # 设置屏幕上显示的格式
|
||||||
current = time.strftime("%Y-%m-%d", time.localtime()) # 设置当前日期
|
current = time.strftime("%Y-%m-%d", time.localtime()) # 设置当前日期
|
||||||
if level == "error":
|
if level == "error":
|
||||||
th = handlers.TimedRotatingFileHandler(filename=f'{file_name}/{current}_{level}.logger',
|
th = handlers.TimedRotatingFileHandler(filename=f'{file_name}/{current}_{level}.logger', when=when,
|
||||||
when=when,
|
|
||||||
backupCount=back_count, encoding="utf-8")
|
backupCount=back_count, encoding="utf-8")
|
||||||
else:
|
else:
|
||||||
th = handlers.TimedRotatingFileHandler(filename=file_name + "/{}_info.logger".format(current),
|
th = handlers.TimedRotatingFileHandler(filename=file_name + "/{}_info.logger".format(current), when=when,
|
||||||
when=when,
|
backupCount=back_count, encoding="utf-8") # 往文件里写日志
|
||||||
backupCount=back_count,
|
|
||||||
encoding="utf-8") # 往文件里写日志
|
|
||||||
|
|
||||||
th.setFormatter(format_str) # 设置文件里写入的格式
|
th.setFormatter(format_str) # 设置文件里写入的格式
|
||||||
my_logger.addHandler(sh) # 将对象加入logger里
|
my_logger.addHandler(sh) # 将对象加入logger里
|
||||||
my_logger.addHandler(th)
|
my_logger.addHandler(th)
|
||||||
|
|
||||||
if level == "debug":
|
if level == "debug":
|
||||||
my_logger.debug(msg)
|
my_logger.debug(msg)
|
||||||
elif level == "error":
|
elif level == "error":
|
||||||
|
@ -68,11 +65,11 @@ class MyLog:
|
||||||
my_logger.warning(msg)
|
my_logger.warning(msg)
|
||||||
else:
|
else:
|
||||||
my_logger.critical(msg)
|
my_logger.critical(msg)
|
||||||
|
|
||||||
my_logger.removeHandler(sh)
|
my_logger.removeHandler(sh)
|
||||||
my_logger.removeHandler(th)
|
my_logger.removeHandler(th)
|
||||||
logging.shutdown()
|
logging.shutdown()
|
||||||
|
|
||||||
def decorator_log(self, msg=None):
|
def decorator_log(self, msg=None):
|
||||||
def warp(fun):
|
def warp(fun):
|
||||||
def inner(*args, **kwargs):
|
def inner(*args, **kwargs):
|
||||||
|
@ -80,9 +77,9 @@ class MyLog:
|
||||||
return fun(*args, **kwargs)
|
return fun(*args, **kwargs)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.my_log(f"{msg}: {e}", "error")
|
self.my_log(f"{msg}: {e}", "error")
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
return warp
|
return warp
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,6 +91,6 @@ if __name__ == '__main__':
|
||||||
def add():
|
def add():
|
||||||
print("试一下")
|
print("试一下")
|
||||||
raise "不好使,异常了。"
|
raise "不好使,异常了。"
|
||||||
|
|
||||||
|
|
||||||
add()
|
add()
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from common.utils import logger
|
|
||||||
|
|
||||||
|
|
||||||
# @logger.log_decorator()
|
# @logger.log_decorator()
|
||||||
def parsing_openapi(file_path):
|
def parsing_openapi(file_path):
|
||||||
|
@ -13,30 +11,30 @@ def parsing_openapi(file_path):
|
||||||
for path, methods in paths.items():
|
for path, methods in paths.items():
|
||||||
for method, details in methods.items():
|
for method, details in methods.items():
|
||||||
test_case = {
|
test_case = {
|
||||||
"id": count,
|
"Id": count,
|
||||||
"name": "openapi",
|
"Name": "openapi",
|
||||||
"description": details.get("summary"),
|
"Description": details.get("summary"),
|
||||||
"Run": "yes",
|
"Run": "yes",
|
||||||
"Time": "0.1",
|
"Time": "0.1",
|
||||||
'method': method,
|
'Method': method,
|
||||||
'url': path,
|
'Url': path,
|
||||||
'headers': json.dumps(extract_parameters(details.get('parameters', []), 'header')),
|
'Headers': json.dumps(extract_parameters(details.get('parameters', []), 'header')),
|
||||||
'Headers是否加密': "",
|
'Headers Crypto': "",
|
||||||
'params': json.dumps(extract_parameters(details.get('parameters', []), 'query')),
|
'Query Str': json.dumps(extract_parameters(details.get('parameters', []), 'query')),
|
||||||
'request_data_type': determine_request_type(details.get('requestBody')),
|
'Request Data Type': determine_request_type(details.get('requestBody')),
|
||||||
'request_data': json.dumps(extract_request_body(details.get('requestBody'))),
|
'Request Data': json.dumps(extract_request_body(details.get('requestBody'))),
|
||||||
'请求参数是否加密': '',
|
'Request Data Crypto': '',
|
||||||
'提取请求参数': '',
|
'Extract Request Data': '',
|
||||||
'Jsonpath': '',
|
'Jsonpath': '',
|
||||||
'正则表达式': '',
|
'Regex': '',
|
||||||
'正则变量': '',
|
'Regex Params List': '',
|
||||||
'绝对路径表达式': '',
|
'Retrieve Value': '',
|
||||||
'SQL': '',
|
'SQL': '',
|
||||||
'sql变量': '',
|
'Sql Params Dict': '',
|
||||||
'预期结果': '',
|
'Expected': '',
|
||||||
'响应结果': '',
|
'Response': '',
|
||||||
'断言结果': '',
|
'Assertion': '',
|
||||||
'报错日志': ''}
|
'Error Log': ''}
|
||||||
test_cases.append(test_case)
|
test_cases.append(test_case)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
@ -105,3 +103,9 @@ if __name__ == '__main__':
|
||||||
file = f'../../cases/temporary_file/openapi.json'
|
file = f'../../cases/temporary_file/openapi.json'
|
||||||
res = parsing_openapi(file)
|
res = parsing_openapi(file)
|
||||||
print(res)
|
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)
|
||||||
|
|
|
@ -8,7 +8,7 @@ result = []
|
||||||
|
|
||||||
def parsing_postman(path):
|
def parsing_postman(path):
|
||||||
"""
|
"""
|
||||||
解析postman到处的json文件
|
解析postman导出的json文件 转为excel测试用例
|
||||||
Args:
|
Args:
|
||||||
path:
|
path:
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ def parsing_postman(path):
|
||||||
_parse_api(content=content.get('item'))
|
_parse_api(content=content.get('item'))
|
||||||
elif 'request' in content.keys():
|
elif 'request' in content.keys():
|
||||||
id_count += 1
|
id_count += 1
|
||||||
api['id'] = id_count
|
api['Id'] = id_count
|
||||||
api['name'] = 'postman'
|
api['Name'] = 'postman'
|
||||||
api['description'] = content.get('name')
|
api['Description'] = content.get('name')
|
||||||
request = content.get('request')
|
request = content.get('request')
|
||||||
api['Run'] = 'yes'
|
api['Run'] = 'yes'
|
||||||
api['Time'] = 0.5
|
api['Time'] = 0.5
|
||||||
|
@ -39,14 +39,12 @@ def parsing_postman(path):
|
||||||
# api请求方法
|
# api请求方法
|
||||||
api['Method'] = request.get('method', 'GET').upper()
|
api['Method'] = request.get('method', 'GET').upper()
|
||||||
header = request.get('header')
|
header = request.get('header')
|
||||||
header = {item.get('key'): item.get('value') for item in
|
header = {item.get('key'): item.get('value') for item in header} if header else {}
|
||||||
header} if header else {}
|
|
||||||
auth = request.get('auth')
|
auth = request.get('auth')
|
||||||
if auth:
|
if auth:
|
||||||
auth_type = auth.get('type')
|
auth_type = auth.get('type')
|
||||||
if auth.get(auth_type):
|
if auth.get(auth_type):
|
||||||
auth_value = {item.get('key'): item.get('value') for item in
|
auth_value = {item.get('key'): item.get('value') for item in auth.get(auth_type) if
|
||||||
auth.get(auth_type) if
|
|
||||||
(item and item.get('key'))}
|
(item and item.get('key'))}
|
||||||
header.update(auth_value)
|
header.update(auth_value)
|
||||||
# api 请求地址
|
# api 请求地址
|
||||||
|
@ -63,51 +61,46 @@ def parsing_postman(path):
|
||||||
# [item.get('key') + '=' + (item.get('value') or '') for item in url.get('query') if item])
|
# [item.get('key') + '=' + (item.get('value') or '') for item in url.get('query') if item])
|
||||||
# api请求头
|
# api请求头
|
||||||
api['Headers'] = json.dumps(header, ensure_ascii=False)
|
api['Headers'] = json.dumps(header, ensure_ascii=False)
|
||||||
api['Headers是否加密'] = ''
|
api['Headers Crypto'] = ''
|
||||||
api['params'] = ''
|
api['Query Str'] = ''
|
||||||
body = request.get('body')
|
body = request.get('body')
|
||||||
if body:
|
if body:
|
||||||
# api接口请求参数类型
|
# api接口请求参数类型
|
||||||
request_mode = body.get('mode')
|
request_mode = body.get('mode')
|
||||||
if 'raw' == request_mode:
|
if 'raw' == request_mode:
|
||||||
api['request_data_type'] = 'json'
|
api['Request Data Type'] = 'json'
|
||||||
elif 'formdata' == request_mode:
|
elif 'formdata' == request_mode:
|
||||||
api['request_data_type'] = 'data'
|
api['Request Data Type'] = 'data'
|
||||||
elif 'urlencoded' == request_mode:
|
elif 'urlencoded' == request_mode:
|
||||||
api['request_data_type'] = 'data'
|
api['Request Data Type'] = 'data'
|
||||||
|
|
||||||
# api接口请求参数
|
# api接口请求参数
|
||||||
request_data = body.get(request_mode)
|
request_data = body.get(request_mode)
|
||||||
api['Request Data'] = {}
|
api['Request Data'] = {}
|
||||||
if request_data and 'raw' == request_mode:
|
if request_data and 'raw' == request_mode:
|
||||||
api['Request Data'].update(
|
api['Request Data'].update(
|
||||||
json.loads(request_data.replace('\t', '').replace('\n',
|
json.loads(request_data.replace('\t', '').replace('\n', '').replace('\r', '')))
|
||||||
'').replace(
|
|
||||||
'\r', '')))
|
|
||||||
elif request_data and 'formdata' == request_mode:
|
elif request_data and 'formdata' == request_mode:
|
||||||
if isinstance(request_data, list):
|
if isinstance(request_data, list):
|
||||||
for item in request_data:
|
for item in request_data:
|
||||||
if item.get("type") == "text":
|
if item.get("type") == "text":
|
||||||
api['Request Data'].update({item.get(
|
api['Request Data'].update({item.get('key'): item.get("value", "")})
|
||||||
'key'): item.get("value", "")})
|
|
||||||
elif item.get("type") == "file":
|
elif item.get("type") == "file":
|
||||||
api["Request Data"].update({item.get(
|
api["Request Data"].update({item.get('key'): item.get("src", "")})
|
||||||
'key'): item.get("src", "")})
|
api["Request Data Type"] = "files"
|
||||||
api["request_data_type"] = "files"
|
api["Request Data"] = json.dumps(api["Request Data"], ensure_ascii=False)
|
||||||
api["Request Data"] = json.dumps(api["Request Data"],
|
api['Request Data Crypto'] = ''
|
||||||
ensure_ascii=False)
|
api['Extract Request Data'] = ''
|
||||||
api['请求参数是否加密'] = ''
|
|
||||||
api['提取请求参数'] = ''
|
|
||||||
api['Jsonpath'] = ''
|
api['Jsonpath'] = ''
|
||||||
api['正则表达式'] = ''
|
api['Regex'] = ''
|
||||||
api['正则变量'] = ''
|
api['Regex Params List'] = ''
|
||||||
api['绝对路径表达式'] = ''
|
api['Retrieve Value'] = ''
|
||||||
api['SQL'] = ''
|
api['SQL'] = ''
|
||||||
api['sql变量'] = ''
|
api['Sql Params Dict'] = ''
|
||||||
api['预期结果'] = ''
|
api['Expected'] = ''
|
||||||
api['响应结果'] = ''
|
api['Response'] = ''
|
||||||
api['断言结果'] = ''
|
api['Assertion'] = ''
|
||||||
api['报错日志'] = ''
|
api['Error Log'] = ''
|
||||||
|
|
||||||
result.append(api)
|
result.append(api)
|
||||||
|
|
||||||
|
@ -117,7 +110,7 @@ def parsing_postman(path):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pat = r'E:\apitest\cases\temporary_file\postman.json'
|
pat = r'..\..\cases\temporary_file\postman.json'
|
||||||
res = parsing_postman(pat)
|
res = parsing_postman(pat)
|
||||||
from common.file_handling.excel import DoExcel
|
from common.file_handling.excel import DoExcel
|
||||||
from common.config import Config
|
from common.config import Config
|
||||||
|
|
|
@ -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
|
|
|
@ -12,12 +12,9 @@ from functools import wraps
|
||||||
|
|
||||||
def singleton(cls):
|
def singleton(cls):
|
||||||
"""
|
"""
|
||||||
单例模式类装饰器
|
|
||||||
Args:
|
Args:
|
||||||
cls:被装饰类
|
cls:被装饰类
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
instance = {}
|
instance = {}
|
||||||
|
|
||||||
|
|
|
@ -5,43 +5,44 @@ from dataclasses import dataclass
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Variables:
|
class Variables:
|
||||||
variables = {} # 定义依赖表
|
variables = {} # 定义依赖表
|
||||||
pattern_l = re.compile(r"{{\s*([^}\s]+)\s*}}(?:\[(\d+)\])?")
|
# 预编译正则表达式
|
||||||
PATTERN = re.compile(r"{{(.*?)}}") # 预编译正则表达式
|
pattern_l = re.compile(r"{{\s*([^}\s]+)\s*}}(?:\[(\d+)\])?")
|
||||||
pattern = re.compile(r'({)')
|
PATTERN = re.compile(r"{{(.*?)}}")
|
||||||
pattern_fun = re.compile(r"{{(\w+\(\))}}")
|
pattern = re.compile(r'({)')
|
||||||
|
pattern_fun = re.compile(r"{{(\w+\(\))}}")
|
||||||
@classmethod
|
|
||||||
def update_variable(cls, key, value):
|
@classmethod
|
||||||
"""更新依赖表"""
|
def update_variable(cls, key, value):
|
||||||
cls.variables[f"{{{{{key}}}}}"] = value
|
"""更新依赖表"""
|
||||||
|
cls.variables[f"{{{{{key}}}}}"] = value
|
||||||
@classmethod
|
|
||||||
def get_variable(cls, key=None):
|
@classmethod
|
||||||
"""获取依赖表 或 依赖表中key对应的值"""
|
def get_variable(cls, key=None):
|
||||||
return cls.variables if not key else cls.variables.get(key)
|
"""获取依赖表 或 依赖表中key对应的值"""
|
||||||
|
return cls.variables if not key else cls.variables.get(key)
|
||||||
@classmethod
|
|
||||||
def set_variable(cls, value):
|
@classmethod
|
||||||
"""设置依赖表"""
|
def set_variable(cls, value):
|
||||||
cls.variables = value
|
"""设置依赖表"""
|
||||||
|
cls.variables = value
|
||||||
@classmethod
|
|
||||||
def reset(cls):
|
@classmethod
|
||||||
"""重置"""
|
def reset(cls):
|
||||||
cls.variables.clear()
|
"""重置"""
|
||||||
cls.request = None
|
cls.variables.clear()
|
||||||
cls.response = None
|
cls.request = None
|
||||||
|
cls.response = None
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from common.file_handling.get_excel_init import get_init
|
# from common.file_handling.get_excel_init import get_init
|
||||||
from common.config import Config
|
from common.config import Config
|
||||||
|
|
||||||
test_file = Config.test_case
|
test_file = Config.test_case
|
||||||
excel_handle, init_data, test_case = get_init(test_file)
|
# excel_handle, init_data, test_case = get_init(test_file)
|
||||||
initialize_data = eval(init_data.get("initialize_data"))
|
# initialize_data = eval(init_data.get("initialize_data"))
|
||||||
print(initialize_data)
|
# print(initialize_data)
|
||||||
d = Variables
|
# d = Variables
|
||||||
d.set_variable(initialize_data) # 初始化依赖表
|
# d.set_variable(initialize_data)
|
||||||
print("--------------------->", d.get_variable())
|
# print("--------------------->", d.get_variable())
|
||||||
|
|
Binary file not shown.
|
@ -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.")
|
|
|
@ -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()
|
|
38
debug/fs.py
38
debug/fs.py
|
@ -1,38 +0,0 @@
|
||||||
import gc
|
|
||||||
|
|
||||||
|
|
||||||
# 引用计数示例
|
|
||||||
# a = [1, 2, 3]
|
|
||||||
# b = a
|
|
||||||
# print(sys.getrefcount(a)-1) # 输出2,a和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()) # 输出对象的代信息
|
|
16
debug/myf.py
16
debug/myf.py
|
@ -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)
|
|
59
debug/rt.py
59
debug/rt.py
|
@ -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)
|
|
|
@ -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()
|
|
|
@ -2,8 +2,8 @@ import os.path
|
||||||
|
|
||||||
from common.config import Config
|
from common.config import Config
|
||||||
from common.file_handling.excel import DoExcel
|
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_openapi import parsing_openapi
|
||||||
|
from common.utils.parsing_postman import parsing_postman
|
||||||
|
|
||||||
|
|
||||||
class ExcelConverter:
|
class ExcelConverter:
|
||||||
|
@ -37,10 +37,8 @@ class ExcelConverter:
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
postman_to_json = r'.\data\temporary_file\postman.json' # postman导出的json文件
|
postman_to_json = r'.\data\temporary_file\postman.json' # postman导出的json文件
|
||||||
postman_out_file = os.path.join(Config.base_path, 'cases', 'test_cases',
|
postman_out_file = os.path.join(Config.base_path, 'cases', 'test_cases', 'test_postman_cases.xlsx') # 转化后的文件保存的位置
|
||||||
'test_postman_cases.xlsx') # 转化后的文件保存的位置
|
|
||||||
openapi_to_json = r'.\data\temporary_file\openapi.json' # postman导出的json文件
|
openapi_to_json = r'.\data\temporary_file\openapi.json' # postman导出的json文件
|
||||||
openapi_out_file = os.path.join(Config.base_path, 'cases', 'test_cases',
|
openapi_out_file = os.path.join(Config.base_path, 'cases', 'test_cases', 'test_openapi_cases.xlsx') # 转化后的文件保存的位置
|
||||||
'test_openapi_cases.xlsx') # 转化后的文件保存的位置
|
|
||||||
ExcelConverter('postman', postman_to_json, postman_out_file).main()
|
ExcelConverter('postman', postman_to_json, postman_out_file).main()
|
||||||
ExcelConverter('postman', openapi_to_json, openapi_out_file).main()
|
ExcelConverter('postman', openapi_to_json, openapi_out_file).main()
|
||||||
|
|
|
@ -11,5 +11,7 @@
|
||||||
__all__ = ["online_function"]
|
__all__ = ["online_function"]
|
||||||
|
|
||||||
|
|
||||||
|
# 用户自定义扩展函数文件。
|
||||||
|
|
||||||
def online_function():
|
def online_function():
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -20,45 +20,45 @@ from extensions import logger
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def md5_sign(data: dict):
|
def md5_sign(data: dict):
|
||||||
"""
|
"""
|
||||||
数据加签
|
数据加签
|
||||||
Args:
|
Args:
|
||||||
**data:需要加钱的数据
|
**data:需要加钱的数据
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sorted_list = []
|
sorted_list = []
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
try:
|
try:
|
||||||
sorted_params = str(key) + str(value)
|
sorted_params = str(key) + str(value)
|
||||||
sorted_list.append(sorted_params)
|
sorted_list.append(sorted_params)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise
|
raise
|
||||||
sort = natsorted(sorted_list) # 列表自然排序
|
sort = natsorted(sorted_list) # 列表自然排序
|
||||||
argument = "加签所需要的密钥"
|
argument = "加签所需要的密钥"
|
||||||
keystore = argument + ("".join(sort)) # 生成加带密钥的新字符串
|
keystore = argument + ("".join(sort)) # 生成加带密钥的新字符串
|
||||||
sign_value = md5(keystore)
|
sign_value = md5(keystore)
|
||||||
return {**data, **{"sign": sign_value}}
|
return {**data, **{"sign": sign_value}}
|
||||||
|
|
||||||
|
|
||||||
@logger.log_decorator()
|
@logger.log_decorator()
|
||||||
def sha1_sign(post_data: dict):
|
def sha1_sign(post_data: dict):
|
||||||
timestamp = int(round(time.time() * 1000)) # 毫秒级时间戳
|
timestamp = int(round(time.time() * 1000)) # 毫秒级时间戳
|
||||||
argument = {"secretKey": "", "timestamp": timestamp} # 加密加盐参数
|
argument = {"secretKey": "", "timestamp": timestamp} # 加密加盐参数
|
||||||
res = {**post_data, **argument}
|
res = {**post_data, **argument}
|
||||||
sorted_list = []
|
sorted_list = []
|
||||||
for key, value in res.items():
|
for key, value in res.items():
|
||||||
try:
|
try:
|
||||||
value = json.dumps(value, ensure_ascii=False) if isinstance(value, list) or isinstance(value,
|
value = json.dumps(value, ensure_ascii=False) if isinstance(value, list) or isinstance(value,
|
||||||
dict) else str(
|
dict) else str(
|
||||||
value)
|
value)
|
||||||
sorted_params = str(key) + "=" + value
|
sorted_params = str(key) + "=" + value
|
||||||
sorted_list.append(sorted_params)
|
sorted_list.append(sorted_params)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
sort = natsorted(sorted_list) # 列表自然排序 返回[(key,value),(key,value)]
|
sort = natsorted(sorted_list) # 列表自然排序 返回[(key,value),(key,value)]
|
||||||
splicing_str = "&".join(sort) # 排序结果 key=value&key=value 拼接
|
splicing_str = "&".join(sort) # 排序结果 key=value&key=value 拼接
|
||||||
encrypted_str = sha1_secret_str(splicing_str) # sha1加密
|
encrypted_str = sha1_secret_str(splicing_str) # sha1加密
|
||||||
sign = {"signature": encrypted_str}
|
sign = {"signature": encrypted_str}
|
||||||
return {**res, **sign} # request 中使用json入参,则传dict
|
return {**res, **sign} # request 中使用json入参,则传dict
|
||||||
|
|
|
@ -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
Binary file not shown.
|
@ -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)
|
|
|
@ -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
|
|
|
@ -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)
|
|
|
@ -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)
|
|
|
@ -42,3 +42,23 @@ class Hooks:
|
||||||
response = func(response)
|
response = func(response)
|
||||||
|
|
||||||
return 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
|
|
@ -1,12 +1,4 @@
|
||||||
#!/usr/bin/env python
|
# !/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
|
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
"""
|
"""
|
||||||
@author: kira
|
@author: kira
|
||||||
|
@ -15,7 +7,7 @@
|
||||||
@time: 2023/6/16 16:58
|
@time: 2023/6/16 16:58
|
||||||
@desc:
|
@desc:
|
||||||
"""
|
"""
|
||||||
from temp.extent.hooks_decorator import hooks # 导入hooks对象
|
from temp.hooks import hooks
|
||||||
|
|
||||||
|
|
||||||
@hooks.before_request
|
@hooks.before_request
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -4,8 +4,8 @@ import unittest
|
||||||
from ddt import ddt, data
|
from ddt import ddt, data
|
||||||
|
|
||||||
from common import bif_functions
|
from common import bif_functions
|
||||||
from common.config import Config
|
|
||||||
from common.action import Action
|
from common.action import Action
|
||||||
|
from common.config import Config
|
||||||
from common.database.mysql_client import MysqlClient
|
from common.database.mysql_client import MysqlClient
|
||||||
from common.file_handling.do_excel import DoExcel
|
from common.file_handling.do_excel import DoExcel
|
||||||
from common.utils.mylogger import MyLogger
|
from common.utils.mylogger import MyLogger
|
||||||
|
@ -36,8 +36,7 @@ class TestProjectApi(unittest.TestCase):
|
||||||
def test_api(self, item):
|
def test_api(self, item):
|
||||||
# f"""用例:{item.get("name")}_{item.get("desc")}"""
|
# f"""用例:{item.get("name")}_{item.get("desc")}"""
|
||||||
|
|
||||||
sheet, iid, condition, st, name, desc, headers_crypto, request_crypto, method = self.__base_info(
|
sheet, iid, condition, st, name, desc, headers_crypto, request_crypto, method = self.__base_info(item)
|
||||||
item)
|
|
||||||
regex, keys, deps, jp_dict, extract_request_data = self.__extractor_info(item)
|
regex, keys, deps, jp_dict, extract_request_data = self.__extractor_info(item)
|
||||||
|
|
||||||
if self.__is_run(condition):
|
if self.__is_run(condition):
|
||||||
|
@ -70,10 +69,7 @@ class TestProjectApi(unittest.TestCase):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 执行请求操作
|
# 执行请求操作
|
||||||
kwargs = {
|
kwargs = {request_data_type: request_data, 'headers': headers}
|
||||||
request_data_type: request_data,
|
|
||||||
'headers': headers
|
|
||||||
}
|
|
||||||
response = self.action.http_client(host, url, method, **kwargs)
|
response = self.action.http_client(host, url, method, **kwargs)
|
||||||
# 执行后置代码片段
|
# 执行后置代码片段
|
||||||
self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "teardown", response)
|
self.action.load_and_execute_script(Config.SCRIPTS_DIR, prepost_script, "teardown", response)
|
||||||
|
|
|
@ -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()
|
|
|
@ -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¤t=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)
|
|
Loading…
Reference in New Issue