import wx
import requests
import json
class APIDebuggerFrame(wx.Frame):
def init (self):
super().init (None, title="API 调试器", size=(800, 600))
self.panel = wx.Panel(self)
self.init_ui()
self.Centre()
self.Show()
def init_ui(self):
main_sizer = wx.BoxSizer(wx.VERTICAL)
# === 第一行:Method + URL ===
top_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.method_choice = wx.Choice(self.panel, choices=["GET", "POST"])
self.method_choice.SetSelection(0)
top_sizer.Add(wx.StaticText(self.panel, label="方法:"), 0, wx.ALL | wx.ALIGN_CENTER, 5)
top_sizer.Add(self.method_choice, 0, wx.ALL, 5)
top_sizer.Add(wx.StaticText(self.panel, label=" URL:"), 0, wx.ALL | wx.ALIGN_CENTER, 5)
self.url_input = wx.TextCtrl(self.panel, value="https://httpbin.org/get", size=(400, -1))
top_sizer.Add(self.url_input, 1, wx.ALL | wx.EXPAND, 5)
send_btn = wx.Button(self.panel, label="发送")
send_btn.Bind(wx.EVT_BUTTON, self.on_send_request)
top_sizer.Add(send_btn, 0, wx.ALL, 5)
main_sizer.Add(top_sizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10)
# === 请求区域:Headers / Params / Data ===
nb = wx.Notebook(self.panel)
self.headers_text = wx.TextCtrl(nb, style=wx.TE_MULTILINE)
self.params_text = wx.TextCtrl(nb, style=wx.TE_MULTILINE)
self.data_text = wx.TextCtrl(nb, style=wx.TE_MULTILINE)
nb.AddPage(self.headers_text, "请求头 (Headers)")
nb.AddPage(self.params_text, "查询参数 (Params)")
nb.AddPage(self.data_text, "POST数据 (Data)")
main_sizer.Add(nb, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
# === 响应区域 ===
result_label = wx.StaticText(self.panel, label="响应结果:")
main_sizer.Add(result_label, 0, wx.LEFT | wx.TOP, 10)
self.result_text = wx.TextCtrl(
self.panel, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL
)
self.result_text.SetFont(wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
main_sizer.Add(self.result_text, 3, wx.EXPAND | wx.ALL, 10)
self.panel.SetSizer(main_sizer)
def on_send_request(self, event):
url = self.url_input.GetValue().strip()
if not url:
wx.MessageBox("请输入URL", "错误", wx.OK | wx.ICON_ERROR)
return
method = self.method_choice.GetStringSelection()
try:
# 解析 Headers
headers = self.parse_key_value(self.headers_text.GetValue())
# 解析 Params
params = self.parse_key_value(self.params_text.GetValue())
data_content = self.data_text.GetValue().strip()
data = {}
json_data = None
if method == "POST" and data_content:
# 尝试解析为 JSON
try:
json_data = json.loads(data_content)
except json.JSONDecodeError:
# 否则作为 form 表单处理(key=value&... 格式)
data = {}
for line in data_content.splitlines():
line = line.strip()
if line and "=" in line:
k, v = line.split("=", 1)
data[k.strip()] = v.strip()
# 发送请求
response = requests.request(
method=method,
url=url,
headers=headers,
params=params,
json=json_data,
data=data if data else None,
timeout=10
)
# 构建响应输出
output = [
f"状态码: {response.status_code}",
f"URL: {response.url}",
"\n--- 响应头 ---"
]
for k, v in response.headers.items():
output.append(f"{k}: {v}")
output.append("\n\n--- 响应体 ---")
try:
json_body = response.json()
output.append(json.dumps(json_body, indent=2, ensure_ascii=False))
except json.JSONDecodeError:
body = response.text
if not body.strip():
body = "<空>"
output.append(body)
self.result_text.SetValue("\n".join(output))
except requests.exceptions.RequestException as e:
wx.MessageBox(f"请求失败:\n{str(e)}", "错误", wx.OK | wx.ICON_ERROR)
except Exception as e:
wx.MessageBox(f"发生错误:\n{str(e)}", "错误", wx.OK | wx.ICON_ERROR)
def parse_key_value(self, text):
"""将多行 key: value 或 key=value 转为字典"""
result = {}
for line in text.splitlines():
line = line.strip()
if not line:
continue
if ":" in line:
k, v = line.split(":", 1)
elif "=" in line:
k, v = line.split("=", 1)
else:
continue
result[k.strip()] = v.strip()
return result
主程序
if name == "main ":
app = wx.App(False)
frame = APIDebuggerFrame()
app.MainLoop()