Update documentation.

This commit is contained in:
2026-03-28 17:42:37 +05:30
parent 01662f7e0e
commit 79b120ff91
25 changed files with 109 additions and 109 deletions

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent AI chat sidebar panel (persistent, context-aware)."""
"""APIClient - Agent - AI chat sidebar panel (persistent, context-aware)."""
import re
from PyQt6.QtWidgets import (
@@ -124,7 +124,7 @@ class MessageBubble(QFrame):
self._text_lbl.setText(self._full_text)
def finalize(self):
"""Called when streaming ends strip apply blocks and render them."""
"""Called when streaming ends - strip apply blocks and render them."""
if self._finalized:
return
self._finalized = True

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent AI Assistant Dialog."""
"""APIClient - Agent - AI Assistant Dialog."""
import json
from PyQt6.QtWidgets import (
@@ -43,7 +43,7 @@ class AnalysisWorker(QThread):
self.progress.emit("Checking for OpenAPI/Swagger spec…")
spec = openapi_parser.detect_spec(content)
if spec:
self.progress.emit("OpenAPI spec detected parsing directly…")
self.progress.emit("OpenAPI spec detected - parsing directly…")
result = openapi_parser.parse_spec(spec)
if self.base_url:
result["base_url"] = self.base_url
@@ -136,7 +136,7 @@ class AIAssistantDialog(QDialog):
layout.addWidget(footer)
# ══════════════════════════════════════════════════════════════════════════
# Tab 1 EKIKA Odoo API Framework (dedicated, no AI tokens needed)
# Tab 1 - EKIKA Odoo API Framework (dedicated, no AI tokens needed)
# ══════════════════════════════════════════════════════════════════════════
def _build_ekika_tab(self) -> QWidget:
@@ -303,7 +303,7 @@ class AIAssistantDialog(QDialog):
self.ek_preview.setFont(QFont("JetBrains Mono, Fira Code, Consolas", 10))
self.ek_preview.setPlaceholderText(
"Fill in the form above and click Generate Collection to preview.\n\n"
"No API key required collection is generated instantly from the\n"
"No API key required - collection is generated instantly from the\n"
"EKIKA Odoo API Framework documentation."
)
self.ek_preview.setMaximumHeight(180)
@@ -380,7 +380,7 @@ class AIAssistantDialog(QDialog):
self.ek_import_btn.setEnabled(True)
self.ek_env_btn.setEnabled(True)
self.ek_both_btn.setEnabled(True)
self.status_label.setText(f"{len(eps)} endpoint(s) ready click Import to save")
self.status_label.setText(f"{len(eps)} endpoint(s) ready - click Import to save")
def _ekika_import(self):
if not self._result:
@@ -399,7 +399,7 @@ class AIAssistantDialog(QDialog):
self._do_create_env(self._result)
# ══════════════════════════════════════════════════════════════════════════
# Tab 2 Generic AI analysis (OpenAPI / any docs URL)
# Tab 2 - Generic AI analysis (OpenAPI / any docs URL)
# ══════════════════════════════════════════════════════════════════════════
def _build_generic_tab(self) -> QWidget:
@@ -543,10 +543,10 @@ class AIAssistantDialog(QDialog):
lines = [
f"✓ Parsed via: {src_label}",
f"✓ Collection: {result.get('collection_name', 'Unnamed')}",
f"✓ Base URL: {result.get('base_url', '')}",
f"✓ Base URL: {result.get('base_url', '-')}",
f"✓ Auth type: {result.get('auth_type', 'none')}",
f"✓ Endpoints: {len(endpoints)} found",
f"✓ Env vars: {list(env_vars.keys()) or ''}",
f"✓ Env vars: {list(env_vars.keys()) or '-'}",
]
if notes:
lines += ["", "── Notes ─────────────────", notes]
@@ -565,7 +565,7 @@ class AIAssistantDialog(QDialog):
self.analyze_btn.setEnabled(True)
self.progress_bar.setVisible(False)
self.result_view.setPlainText(f"✗ Error:\n\n{msg}")
self.status_label.setText("Error see results panel")
self.status_label.setText("Error - see results panel")
def _set_generic_action_buttons(self, enabled: bool):
self.import_btn.setEnabled(enabled)
@@ -586,7 +586,7 @@ class AIAssistantDialog(QDialog):
self._do_create_env(self._generic_result)
# ══════════════════════════════════════════════════════════════════════════
# Tab 3 Settings
# Tab 3 - Settings
# ══════════════════════════════════════════════════════════════════════════
def _build_settings_tab(self) -> QWidget:
@@ -598,7 +598,7 @@ class AIAssistantDialog(QDialog):
hint = QLabel(
"EKIKA AI Assistant uses Claude by Anthropic to analyze plain-text API documentation.\n"
"OpenAPI/Swagger specs and EKIKA Odoo Framework collections are generated locally "
"OpenAPI/Swagger specs and EKIKA Odoo Framework collections are generated locally - "
"no API key required for those."
)
hint.setObjectName("hintText")
@@ -683,7 +683,7 @@ class AIAssistantDialog(QDialog):
def _do_create_env(self, result: dict):
env_vars = result.get("environment_variables", {})
col_name = result.get("collection_name", "AI Import")
env_name = f"{col_name} Environment"
env_name = f"{col_name} - Environment"
if not env_vars:
QMessageBox.information(self, "No Variables", "No environment variables detected.")

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Code Generation Dialog."""
"""APIClient - Agent - Code Generation Dialog."""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QComboBox,
QTextEdit, QPushButton, QLabel, QApplication, QWidget

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Collection Runner dialog."""
"""APIClient - Agent - Collection Runner dialog."""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
QTreeWidget, QTreeWidgetItem, QComboBox, QHeaderView, QProgressBar, QWidget
@@ -168,7 +168,7 @@ class CollectionRunnerDialog(QDialog):
status_str = str(result.status)
row_color = Colors.SUCCESS if result.status < 400 else Colors.ERROR
test_str = f"{passed}/{total}" if total > 0 else ""
test_str = f"{passed}/{total}" if total > 0 else "-"
item = QTreeWidgetItem([
f"{result.method} {result.request_name}",
status_str,
@@ -189,6 +189,6 @@ class CollectionRunnerDialog(QDialog):
def _on_finished(self):
self.run_btn.setEnabled(True)
self.summary_label.setText(
f"Completed: {self._done} request(s) "
f"Completed: {self._done} request(s) - "
f"Tests: {self._passed_tests}/{self._total_tests} passed"
)

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Environment Manager Dialog."""
"""APIClient - Agent - Environment Manager Dialog."""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QListWidget, QListWidgetItem,
QPushButton, QTableWidget, QTableWidgetItem, QHeaderView,

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Import Dialog."""
"""APIClient - Agent - Import Dialog."""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTabWidget, QWidget,
QTextEdit, QPushButton, QLabel, QFileDialog, QMessageBox
@@ -76,7 +76,7 @@ class ImportDialog(QDialog):
layout.setContentsMargins(16, 12, 16, 12)
layout.setSpacing(8)
hint = QLabel("Paste a cURL command it will open as a new request tab:")
hint = QLabel("Paste a cURL command - it will open as a new request tab:")
hint.setObjectName("hintText")
layout.addWidget(hint)

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Main Window."""
"""APIClient - Agent - Main Window."""
from PyQt6.QtWidgets import (
QMainWindow, QSplitter, QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QComboBox, QPushButton, QStatusBar, QTabWidget,
@@ -147,7 +147,7 @@ class MainWindow(QMainWindow):
self.chat_panel = AIChatPanel()
splitter.addWidget(self.chat_panel)
splitter.setSizes([260, 940, 360]) # give chat panel real size first
self.chat_panel.hide() # THEN hide splitter remembers 360
self.chat_panel.hide() # THEN hide - splitter remembers 360
self._main_splitter = splitter
# Wire apply signals
@@ -163,7 +163,7 @@ class MainWindow(QMainWindow):
self._status_bar = QStatusBar()
self._status_bar.setFixedHeight(26)
self.setStatusBar(self._status_bar)
self._status_bar.showMessage(f"Ready {APP_NAME} v{APP_VERSION}")
self._status_bar.showMessage(f"Ready - {APP_NAME} v{APP_VERSION}")
def _build_http_workspace(self) -> QWidget:
w = QWidget()

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Mock Server Panel."""
"""APIClient - Agent - Mock Server Panel."""
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel,
QTableWidget, QTableWidgetItem, QHeaderView, QDialog,

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Request Panel."""
"""APIClient - Agent - Request Panel."""
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QComboBox, QLineEdit,
QPushButton, QTabWidget, QTableWidget, QTableWidgetItem,
@@ -227,7 +227,7 @@ class RequestPanel(QWidget):
self.url_input = QLineEdit()
self.url_input.setObjectName("urlBar")
self.url_input.setPlaceholderText("Enter URL e.g. https://api.example.com/v1/users")
self.url_input.setPlaceholderText("Enter URL - e.g. https://api.example.com/v1/users")
self.url_input.returnPressed.connect(self._send)
self.send_btn = QPushButton("Send")
@@ -359,7 +359,7 @@ class RequestPanel(QWidget):
# ── Slots ────────────────────────────────────────────────────────────────
def _on_method_changed(self, method: str):
# Inline style is intentional here color is dynamic per method value
# Inline style is intentional here - color is dynamic per method value
color = method_color(method)
self.method_combo.setStyleSheet(f"QComboBox#methodCombo {{ color: {color}; }}")
@@ -377,7 +377,7 @@ class RequestPanel(QWidget):
parsed = json.loads(text)
self.body_editor.setPlainText(json.dumps(parsed, indent=2, ensure_ascii=False))
except json.JSONDecodeError:
pass # not valid JSON leave as-is
pass # not valid JSON - leave as-is
def _send(self):
self.send_requested.emit(self._build_request())

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Response Panel."""
"""APIClient - Agent - Response Panel."""
import json
from PyQt6.QtWidgets import (
@@ -25,13 +25,13 @@ def _fmt_size(n: int) -> str:
class StatusBadge(QLabel):
def __init__(self, parent=None):
super().__init__("", parent)
super().__init__("-", parent)
self.setFixedHeight(26)
self._apply_style(Colors.TEXT_MUTED)
self.setFont(QFont("Segoe UI", 11, QFont.Weight.Bold))
def _apply_style(self, color: str):
# Inline style intentional badge color is dynamic per status code
# Inline style intentional - badge color is dynamic per status code
self.setStyleSheet(f"""
QLabel {{
color: {color};
@@ -53,7 +53,7 @@ class StatusBadge(QLabel):
self._apply_style(Colors.ERROR)
def clear(self):
self.setText("")
self.setText("-")
self._apply_style(Colors.TEXT_MUTED)
@@ -174,8 +174,8 @@ class ResponsePanel(QWidget):
self._loading_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
ll.addWidget(self._loading_label)
self._stack.addWidget(self.tabs) # index 0 normal view
self._stack.addWidget(loading_widget) # index 1 loading
self._stack.addWidget(self.tabs) # index 0 - normal view
self._stack.addWidget(loading_widget) # index 1 - loading
layout.addWidget(self._stack, 1)
@@ -203,7 +203,7 @@ class ResponsePanel(QWidget):
size = resp.size_bytes or len(resp.body.encode())
self.size_label.setText(_fmt_size(size))
# Body pretty-print JSON if possible
# Body - pretty-print JSON if possible
try:
parsed = json.loads(resp.body)
self.body_view.setPlainText(json.dumps(parsed, indent=2, ensure_ascii=False))

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Request Search Dialog."""
"""APIClient - Agent - Request Search Dialog."""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QLineEdit,
QPushButton, QListWidget, QListWidgetItem, QLabel, QWidget

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Collections Sidebar."""
"""APIClient - Agent - Collections Sidebar."""
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QTreeWidget, QTreeWidgetItem,
QPushButton, QInputDialog, QMenu, QLineEdit, QLabel, QMessageBox

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent Multi-tab request manager."""
"""APIClient - Agent - Multi-tab request manager."""
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QTabWidget, QPushButton, QTabBar
from PyQt6.QtCore import pyqtSignal, Qt

View File

@@ -1,7 +1,7 @@
"""
APIClient - Agent Central Theme Engine
APIClient - Agent - Central Theme Engine
All styling lives here in the global QSS.
UI widgets use setObjectName() selectors never inline setStyleSheet() for static colors.
UI widgets use setObjectName() selectors - never inline setStyleSheet() for static colors.
Only truly dynamic values (per-request method color, status badge) stay inline.
"""
from PyQt6.QtGui import QColor, QPalette

View File

@@ -1,4 +1,4 @@
"""APIClient - Agent WebSocket client panel."""
"""APIClient - Agent - WebSocket client panel."""
import asyncio
import queue
import time