什么都不用说,先上效果截图
上图是实现的最终效果,是不是觉得很cool
1.实现一个可视化页面来接收用户输入curl请求
2.将curl请求传给后端进行数据处理
3.将处理好的数据再返回给前端页面
pywebio
yapf
1.通过浏览器F12复制curl请求
2.拿到curl请求内容,针对curl请求去做关键数据的转化
3.自定义一套python脚本模板
4.动态替换python脚本模板中的动态参数
def run():
with use_scope("index", clear=True):
put_row([put_text("测试常用调试工具").style(title_style)])
show_curl_2_python()
def clear_case(file_name):
if os.path.exists(file_name):
os.remove(file_name)
def write_to_file(file_name, data):
with open(file_name, mode="w", encoding="utf-8") as f:
f.write(data)
def read_file(file_name):
if os.path.exists(file_name):
with open(file_name, mode="r", encoding="utf-8") as f:
data_str = f.read()
# print(data_str)
return data_str
else:
return "请输入数据,再进行操作"
@use_scope("request", clear=True)
def show_curl_2_python():
put_row(
[
None,
put_column([
put_html("
"),
put_text("复制curl请求: 打开浏览器 --> F12--> 选中请求 --> copy --> Copy as cURL(bash)").style(title_style),
put_text("请输入curl请求:"),
put_button("转化", onclick=show_curl_to_python_result),
put_textarea(name="curl_data", rows=40, value="", code={
'mode': "curl",
'theme': 'darcula'
})
], size="50px 50px 50px 50px 100%")
,
None,
put_column([
put_html("
"),
None,
None,
put_text("转化为python脚本后:"),
put_textarea(name="python_data", rows=40, value="", code={
'mode': "python",
'theme': 'darcula'
})
], size="50px 50px 50px 50px 100%")
,
None
],
size="20px 48% 4% 48% 20px"
)
@use_scope("request", clear=False)
def show_curl_to_python_result():
curl_to_python()
pin.pin_update("python_data", value=read_file(files["py_template"]))
def curl_to_python():
try:
curl_data = pin.pin.curl_data
# print(curl_data)
curl_re_expression = re.compile("curl(.*?)--compressed", re.S) or re.compile("curl(.*?)--insecure", re.S)
curl_result_list = re.findall(curl_re_expression, curl_data)
# print(curl_result_list)
if not curl_result_list:
for file_name in files.values():
clear_case(file_name)
if curl_result_list:
curl_result = curl_result_list[0]
url_re_expression = re.compile("(http.*?)'", re.S)
url_result_list = re.findall(url_re_expression, curl_result)
url = url_result_list[0]
headers_re_expression = re.compile("-H '(.*?)'", re.S)
headers_result_list = re.findall(headers_re_expression, curl_result)
# print(headers_result_list)
headers = {}
for header_str in headers_result_list:
if ":" in header_str:
key = header_str.replace(" ", "").split(":")[0]
value = header_str.replace(" ", "").split(":")[1]
headers[key] = value
# print(headers)
method_re_expression = re.compile("-X '(.*?)'", re.S)
# print(method_re_expression)
method_result_list = re.findall(method_re_expression, curl_result)
# print(method_result_list)
content_type_re_expression = re.compile("-H 'Content-Type: (.*?)'", re.S)
content_type_result_list = re.findall(content_type_re_expression, curl_result)
# print(content_type_result_list)
data = None
method = None
if not method_result_list and not content_type_result_list:
method = "get"
if method_result_list:
method = str(method_result_list[0]).lower()
if content_type_result_list:
# print(method)
if "application" in content_type_result_list[0] or "multipart" in content_type_result_list[0]:
if not method:
method = "post"
# print(method)
if "application" in content_type_result_list[0]:
data_re_expression = re.compile("--data-raw '(.*?)'", re.S)
data_result_list = re.findall(data_re_expression, curl_result)
# print(data_result_list)
if data_result_list:
data = json.loads(data_result_list[0])
if "multipart" in content_type_result_list[0]:
data_re_expression = re.compile("--data-raw \$'(.*?)'", re.S)
data_result_list = re.findall(data_re_expression, curl_result)
if data_result_list:
data = data_result_list[0]
py_json_template = """import requests
headers = {{headers}}
json_data = {{data}}
response = requests.{{method}}('{{url}}', headers=headers, json=json_data, verify=False)
print(response.text)
"""
py_template = """import requests
headers = {{headers}}
data = '{{data}}'
response = requests.{{method}}('{{url}}', headers=headers, data=str(data).encode("utf-8"), verify=False)
print(response.text)
"""
if data and (isinstance(data, dict) or isinstance(data, list)):
py_template = py_json_template.replace("{{headers}}", str(headers)).replace(
"{{data}}", str(data)).replace("{{method}}", method).replace("{{url}}", url)
elif data and isinstance(data, str):
py_template = py_template.replace("{{headers}}", str(headers)).replace(
"{{data}}", data).replace("{{method}}", method).replace("{{url}}", url)
else:
# print("我执行了吗")
py_template = str(py_template).replace("{{headers}}", str(headers)).replace(
"data = '{{data}}'", "").replace("{{method}}", method).replace("{{url}}", url).replace(
'data=str(data).encode("utf-8"), ', "")
py_template = str(FormatCode(py_template)[0])
space_re_expression = re.compile("(:\n\s*?)'", re.S)
space_result_list = re.findall(space_re_expression, py_template)
# print(space_result_list)
for space in space_result_list:
# print(space)
py_template = py_template.replace(space, ": ")
# print(py_template)
write_to_file("py_template.py", py_template)
# print("我执行到底了")
except:
write_to_file("py_template.py", "curl请求格式错误,请重新复制")
使用的接口地址
http://httpbin.org/
curl
curl 'http://httpbin.org/get' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Pragma: no-cache' \
-H 'Referer: http://httpbin.org/' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
-H 'accept: application/json' \
--compressed \
--insecure
python
import requests
headers = {
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Referer': 'http',
'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
'accept': 'application/json'
}
response = requests.get('http://httpbin.org/get',
headers=headers,
verify=False)
print(response.text)
curl
curl 'http://httpbin.org/post' \
-X 'POST' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Length: 0' \
-H 'Origin: http://httpbin.org' \
-H 'Pragma: no-cache' \
-H 'Referer: http://httpbin.org/' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
-H 'accept: application/json' \
--compressed \
--insecure
python
import requests
headers = {
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Length': '0',
'Origin': 'http',
'Pragma': 'no-cache',
'Referer': 'http',
'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
'accept': 'application/json'
}
response = requests.post('http://httpbin.org/post',
headers=headers,
verify=False)
print(response.text)
curl
curl 'http://httpbin.org/put' \
-X 'PUT' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Length: 0' \
-H 'Origin: http://httpbin.org' \
-H 'Pragma: no-cache' \
-H 'Referer: http://httpbin.org/' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' \
-H 'accept: application/json' \
--compressed \
--insecure
python
import requests
headers = {
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Length': '0',
'Origin': 'http',
'Pragma': 'no-cache',
'Referer': 'http',
'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/107.0.0.0Safari/537.36',
'accept': 'application/json'
}
response = requests.put('http://httpbin.org/put',
headers=headers,
verify=False)
print(response.text)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Copyright © 版权所有
# @Time : 2022/11/16 12:01
# @Author : 胡浩浩
# @Email : [email protected]
# @File : curl2python.py
# @IDE : PyCharm
# @description :
import json
import os
import re
from pywebio import *
from pywebio.output import *
from screeninfo import get_monitors
from pywebio.pin import put_textarea
from pywebio.platform.tornado_http import start_server
from ruamel import yaml
from yapf.yapflib.yapf_api import FormatCode
css = """
.container {
margin-top: 0;
max-width: 100%;
}
.CodeMirror {
font-size: 13px;
width: {{width}};
overflow: scroll;
}
"""
title_style = """
color: red;
"""
code_mirror_width = str(get_monitors()[0].width / 2)
css = css.replace("{{width}}", code_mirror_width + "px")
config(title="curl2python", theme="minty", css_style=css)
files = {
"py_template": "py_template.py",
}
def clear_case(file_name):
if os.path.exists(file_name):
os.remove(file_name)
def write_to_file(file_name, data):
with open(file_name, mode="w", encoding="utf-8") as f:
f.write(data)
def read_file(file_name):
if os.path.exists(file_name):
with open(file_name, mode="r", encoding="utf-8") as f:
data_str = f.read()
# print(data_str)
return data_str
else:
return "请输入数据,再进行操作"
@use_scope("request", clear=True)
def show_curl_2_python():
put_row(
[
put_column([
put_html("
"),
put_text("复制curl请求: 打开浏览器 --> F12--> 选中请求 --> copy --> Copy as cURL(bash)").style(title_style),
put_text("请输入curl请求:"),
put_button("转化", onclick=show_curl_to_python_result),
put_textarea(name="curl_data", rows=40, value="", code={
'mode': "curl",
'theme': 'darcula'
})
], size="50px 50px 50px 50px 100%"),
None,
put_column([
put_html("
"),
None,
None,
put_text("转化为python脚本后:"),
put_textarea(name="python_data", rows=40, value="", code={
'mode': "python",
'theme': 'darcula'
})
], size="50px 50px 50px 50px 100%")
,
None
],
size="48% 4% 48% 20px"
)
@use_scope("request", clear=False)
def show_curl_to_python_result():
curl_to_python()
pin.pin_update("python_data", value=read_file(files["py_template"]))
def curl_to_python():
try:
curl_data = pin.pin.curl_data
# print(curl_data)
curl_re_expression = re.compile("curl(.*?)--compressed", re.S) or re.compile("curl(.*?)--insecure", re.S)
curl_result_list = re.findall(curl_re_expression, curl_data)
# print(curl_result_list)
if not curl_result_list:
for file_name in files.values():
clear_case(file_name)
if curl_result_list:
curl_result = curl_result_list[0]
url_re_expression = re.compile("(http.*?)'", re.S)
url_result_list = re.findall(url_re_expression, curl_result)
url = url_result_list[0]
headers_re_expression = re.compile("-H '(.*?)'", re.S)
headers_result_list = re.findall(headers_re_expression, curl_result)
# print(headers_result_list)
headers = {}
for header_str in headers_result_list:
if ":" in header_str:
key = header_str.replace(" ", "").split(":")[0]
value = header_str.replace(" ", "").split(":")[1]
headers[key] = value
# print(headers)
method_re_expression = re.compile("-X '(.*?)'", re.S)
# print(method_re_expression)
method_result_list = re.findall(method_re_expression, curl_result)
# print(method_result_list)
content_type_re_expression = re.compile("-H 'Content-Type: (.*?)'", re.S)
content_type_result_list = re.findall(content_type_re_expression, curl_result)
# print(content_type_result_list)
data = None
method = None
if not method_result_list and not content_type_result_list:
method = "get"
if method_result_list:
method = str(method_result_list[0]).lower()
if content_type_result_list:
# print(method)
if "application" in content_type_result_list[0] or "multipart" in content_type_result_list[0]:
if not method:
method = "post"
# print(method)
if "application" in content_type_result_list[0]:
data_re_expression = re.compile("--data-raw '(.*?)'", re.S)
data_result_list = re.findall(data_re_expression, curl_result)
# print(data_result_list)
if data_result_list:
data = json.loads(data_result_list[0])
if "multipart" in content_type_result_list[0]:
data_re_expression = re.compile("--data-raw \$'(.*?)'", re.S)
data_result_list = re.findall(data_re_expression, curl_result)
if data_result_list:
data = data_result_list[0]
py_json_template = """import requests
headers = {{headers}}
json_data = {{data}}
response = requests.{{method}}('{{url}}', headers=headers, json=json_data, verify=False)
print(response.text)
"""
py_template = """import requests
headers = {{headers}}
data = '{{data}}'
response = requests.{{method}}('{{url}}', headers=headers, data=str(data).encode("utf-8"), verify=False)
print(response.text)
"""
if data and (isinstance(data, dict) or isinstance(data, list)):
py_template = py_json_template.replace("{{headers}}", str(headers)).replace(
"{{data}}", str(data)).replace("{{method}}", method).replace("{{url}}", url)
elif data and isinstance(data, str):
py_template = py_template.replace("{{headers}}", str(headers)).replace(
"{{data}}", data).replace("{{method}}", method).replace("{{url}}", url)
else:
# print("我执行了吗")
py_template = str(py_template).replace("{{headers}}", str(headers)).replace(
"data = '{{data}}'", "").replace("{{method}}", method).replace("{{url}}", url).replace(
'data=str(data).encode("utf-8"), ', "")
py_template = str(FormatCode(py_template)[0])
space_re_expression = re.compile("(:\n\s*?)'", re.S)
space_result_list = re.findall(space_re_expression, py_template)
# print(space_result_list)
for space in space_result_list:
# print(space)
py_template = py_template.replace(space, ": ")
# print(py_template)
write_to_file("py_template.py", py_template)
# print("我执行到底了")
except:
write_to_file("py_template.py", "curl请求格式错误,请重新复制")
def run():
with use_scope("index", clear=True):
put_row([put_text("测试常用调试工具").style(title_style)])
show_curl_2_python()
if __name__ == '__main__':
for file_name in files.values():
clear_case(file_name)
start_server(run, port=8897)