Skip to content

Commit 79e95ba

Browse files
committed
Update dev version
* Comments * Improve Code
1 parent 3a3f5ef commit 79e95ba

File tree

27 files changed

+988
-699
lines changed

27 files changed

+988
-699
lines changed

je_api_testka/gui/api_testka_gui_thread.py

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,48 @@
55
from je_api_testka.httpx_wrapper.httpx_method import test_api_method_httpx
66

77

8+
def _process_response(response_data: dict):
9+
"""
10+
Process API response and push results into UI queue
11+
處理 API 回應並將結果推送到 UI 佇列
12+
"""
13+
# 定義要輸出的欄位 (避免重複程式碼)
14+
response_fields = [
15+
"status_code", "text", "headers", "content", "history",
16+
"encoding", "cookies", "elapsed", "request_method",
17+
"request_url", "request_body"
18+
]
19+
20+
for field in response_fields:
21+
# 取得多語言字典中的對應文字
22+
label = language_wrapper.language_word_dict.get(field, "")
23+
value = response_data.get(field)
24+
api_testka_ui_queue.put(f"{label}{value}")
25+
26+
827
class APITestkaGUIThread(QThread):
28+
"""
29+
GUI Thread for executing API tests asynchronously
30+
GUI 執行緒,用於非同步執行 API 測試
31+
"""
932

1033
def __init__(self):
1134
super().__init__()
12-
self.url = None
13-
self.test_method = None
14-
self.param = None
35+
self.url: str | None = None
36+
self.test_method: str | None = None
37+
self.param: dict | None = None
1538

1639
def run(self):
40+
"""
41+
Run the API test in a separate thread
42+
在獨立執行緒中執行 API 測試
43+
"""
1744
test_response = test_api_method_httpx(
1845
http_method=self.test_method,
1946
test_url=self.url,
2047
params=self.param
2148
)
22-
if test_response is not None and isinstance(test_response, dict):
23-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("status_code") +
24-
str(test_response.get("response_data").get("status_code")))
25-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("text") +
26-
str(test_response.get("response_data").get("text")))
27-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("headers") +
28-
str(test_response.get("response_data").get("headers")))
29-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("content") +
30-
str(test_response.get("response_data").get("content")))
31-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("history") +
32-
str(test_response.get("response_data").get("history")))
33-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("encoding") +
34-
str(test_response.get("response_data").get("encoding")))
35-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("cookies") +
36-
str(test_response.get("response_data").get("cookies")))
37-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("elapsed") +
38-
str(test_response.get("response_data").get("elapsed")))
39-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("request_method") +
40-
str(test_response.get("response_data").get("request_method")))
41-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("request_url") +
42-
str(test_response.get("response_data").get("request_url")))
43-
api_testka_ui_queue.put(language_wrapper.language_word_dict.get("request_body") +
44-
str(test_response.get("response_data").get("request_body")))
49+
50+
if test_response and isinstance(test_response, dict):
51+
_process_response(test_response.get("response_data", {}))
52+

je_api_testka/gui/main_widget.py

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
11
import json
22

33
from PySide6.QtCore import QTimer
4-
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QTabWidget, QFormLayout, \
5-
QPushButton, QTextEdit
4+
from PySide6.QtWidgets import (
5+
QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit,
6+
QComboBox, QTabWidget, QFormLayout, QPushButton, QTextEdit
7+
)
68

79
from je_api_testka.gui.api_testka_gui_thread import APITestkaGUIThread
810
from je_api_testka.gui.language_wrapper.multi_language_wrapper import language_wrapper
911
from je_api_testka.gui.message_queue import api_testka_ui_queue
1012

1113

1214
class APITestkaWidget(QWidget):
15+
"""
16+
API Testka 主視窗元件
17+
Main widget for API Testka GUI
18+
"""
1319

1420
def __init__(self, parent=None):
1521
super().__init__(parent)
1622

23+
# 建立主版面配置
24+
# Create main layout
1725
main_layout = QVBoxLayout()
18-
# URL row
26+
27+
# -------------------------------
28+
# URL 與 Method 選擇區
29+
# URL and HTTP Method selection
30+
# -------------------------------
1931
url_layout = QHBoxLayout()
2032
url_layout.addWidget(QLabel(language_wrapper.language_word_dict.get("url")))
33+
2134
self.url_input = QLineEdit()
2235
url_layout.addWidget(self.url_input)
36+
2337
self.method_combobox = QComboBox()
2438
self.method_combobox.addItems([
2539
language_wrapper.language_word_dict.get("get"),
@@ -33,60 +47,86 @@ def __init__(self, parent=None):
3347
url_layout.addWidget(self.method_combobox)
3448
main_layout.addLayout(url_layout)
3549

50+
# -------------------------------
3651
# Tabs for Param, Auth, Header, Body
52+
# -------------------------------
3753
self.tabs = QTabWidget()
3854
self.param_tab = QWidget()
3955
self.auth_tab = QWidget()
4056
self.header_tab = QWidget()
4157
self.body_tab = QWidget()
58+
4259
self.tabs.addTab(self.param_tab, language_wrapper.language_word_dict.get("param"))
60+
# 可依需求開啟其他 Tab
61+
# Uncomment if needed
4362
# self.tabs.addTab(self.auth_tab, "Auth")
4463
# self.tabs.addTab(self.header_tab, "Header")
4564
# self.tabs.addTab(self.body_tab, "Body")
4665

47-
layout = QFormLayout()
66+
# Param Tab layout
67+
param_layout = QFormLayout()
4868
self.param_input = QLineEdit()
49-
layout.addRow(language_wrapper.language_word_dict.get("param"), self.param_input)
50-
self.param_tab.setLayout(layout)
69+
param_layout.addRow(language_wrapper.language_word_dict.get("param"), self.param_input)
70+
self.param_tab.setLayout(param_layout)
5171

5272
main_layout.addWidget(self.tabs)
5373

54-
# Send button
74+
# -------------------------------
75+
# Send Button
76+
# -------------------------------
5577
self.send_button = QPushButton(language_wrapper.language_word_dict.get("send"))
5678
self.send_button.clicked.connect(self.start_api_request)
5779
main_layout.addWidget(self.send_button)
5880

59-
# Log panel
81+
# -------------------------------
82+
# Log Panel
83+
# -------------------------------
6084
self.log_panel = QTextEdit()
6185
self.log_panel.setReadOnly(True)
6286
main_layout.addWidget(QLabel(language_wrapper.language_word_dict.get("response_and_log")))
6387
main_layout.addWidget(self.log_panel)
6488

65-
# Param
66-
self.test_api_thread = None
89+
# -------------------------------
90+
# Thread + Timer
91+
# -------------------------------
92+
self.test_api_thread: APITestkaGUIThread | None = None
6793
self.pull_log_timer = QTimer()
68-
self.pull_log_timer.setInterval(20)
94+
self.pull_log_timer.setInterval(20) # 每 20ms 檢查一次佇列
6995
self.pull_log_timer.timeout.connect(self.pull_log)
7096

7197
self.setLayout(main_layout)
7298

7399
def start_api_request(self):
100+
"""
101+
開始 API 測試請求
102+
Start API request in a separate thread
103+
"""
74104
self.log_panel.clear()
75105
self.pull_log_timer.stop()
76106
self.pull_log_timer.start()
107+
77108
self.test_api_thread = APITestkaGUIThread()
78109
self.test_api_thread.url = self.url_input.text()
79110
self.test_api_thread.test_method = self.method_combobox.currentText().lower()
80-
param = self.param_input.text()
81-
if param.strip() != "":
111+
112+
# 嘗試解析 JSON 參數
113+
# Try to parse JSON parameters
114+
param_text = self.param_input.text().strip()
115+
if param_text:
82116
try:
83-
self.test_api_thread.param = json.loads(param)
84-
except json.decoder.JSONDecodeError:
85-
pass
86-
self.test_api_thread.start()
117+
self.test_api_thread.param = json.loads(param_text)
118+
except json.JSONDecodeError:
119+
# 若 JSON 格式錯誤,忽略並繼續
120+
# Ignore invalid JSON and continue
121+
self.test_api_thread.param = None
87122

123+
self.test_api_thread.start()
88124

89125
def pull_log(self):
90-
if not api_testka_ui_queue.empty():
126+
"""
127+
從佇列中拉取訊息並顯示在 Log Panel
128+
Pull messages from queue and display in log panel
129+
"""
130+
while not api_testka_ui_queue.empty():
91131
message = api_testka_ui_queue.get_nowait()
92-
self.log_panel.append(str(message))
132+
self.log_panel.append(str(message))

je_api_testka/gui/main_window.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,40 @@
88

99

1010
class APITestkaUI(QMainWindow, QtStyleTools):
11+
"""
12+
API Testka 主視窗
13+
Main window for API Testka application
14+
"""
1115

1216
def __init__(self):
1317
super().__init__()
14-
self.id = language_wrapper.language_word_dict.get("application_name")
18+
19+
# 設定應用程式 ID (Windows 平台需要,讓工作列顯示正確圖示與名稱)
20+
# Set application ID (required on Windows for correct taskbar icon and name)
21+
self.id: str = language_wrapper.language_word_dict.get("application_name")
22+
1523
if sys.platform in ["win32", "cygwin", "msys"]:
1624
from ctypes import windll
1725
windll.shell32.SetCurrentProcessExplicitAppUserModelID(self.id)
26+
27+
# 設定字體樣式
28+
# Set font style
1829
self.setStyleSheet(
19-
f"font-size: 12pt;"
20-
f"font-family: 'Lato';"
30+
"font-size: 12pt;"
31+
"font-family: 'Lato';"
2132
)
33+
34+
# 套用 Material Design 主題
35+
# Apply Material Design theme
2236
self.apply_stylesheet(self, "dark_amber.xml")
23-
self.api_testka_widget = APITestkaWidget()
37+
38+
# 建立並設定主控件
39+
# Create and set main widget
40+
self.api_testka_widget: APITestkaWidget = APITestkaWidget()
2441
self.setCentralWidget(self.api_testka_widget)
42+
43+
if "__main__" == __name__:
44+
app = QApplication(sys.argv)
45+
window = APITestkaUI()
46+
window.show()
47+
sys.exit(app.exec())

0 commit comments

Comments
 (0)