Giao diện dòng lệnh & Chế độ tương tác
Bài học này phân tích cách guide_ai.py xây dựng giao diện dòng lệnh (CLI) linh hoạt, hỗ trợ cả chế độ tương tác và tham số dòng lệnh.
1. Tổng quan điểm vào
guide_ai.py là điểm vào chính của ứng dụng, hỗ trợ 2 chế độ:
| Chế độ | Khi nào | Ưu điểm |
|---|---|---|
| Tương tác | Không có đủ tham số | Dễ sử dụng, có hướng dẫn |
| Dòng lệnh | Có đầy đủ tham số | Tự động hóa, scripting |
python
# Xác định chế độ chạy
run_interactive = args.interactive or (args.provider is None and not args.no_ai)2. Bộ phân tích tham số
2.1. Cấu trúc tham số
python
parser = argparse.ArgumentParser(
description="Guide Generator - Tạo tài liệu hướng dẫn tự động",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Ví dụ:
python guide_ai.py # Chế độ tương tác
python guide_ai.py --provider gemini --name free # Dùng Gemini
python guide_ai.py --no-ai --name test # Không dùng AI
"""
)2.2. Các nhóm tham số
Tham số chính:
python
parser.add_argument("--url", "-u", help="URL bắt đầu")
parser.add_argument("--name", "-n", help="Tên guide")
parser.add_argument("--title", "-t", help="Tiêu đề")
parser.add_argument("--provider", "-p", choices=["gemini", "openai", "none"])
parser.add_argument("--no-ai", action="store_true")Tham số xác thực:
python
parser.add_argument("--save-auth", action="store_true",
help="Mở browser để đăng nhập và lưu session")
parser.add_argument("--clear-auth", action="store_true")
parser.add_argument("--auth-status", action="store_true")Tham số tạo test:
python
parser.add_argument("--generate-tests", action="store_true")
parser.add_argument("--test-type", choices=["unit", "integration", "both"])
parser.add_argument("--run-tests", action="store_true")3. Hệ thống menu tương tác
3.1. Menu chính
python
def interactive_menu() -> dict:
"""Menu tương tác để cấu hình."""
# Hiển thị header
print("=" * 60)
print("📚 GUIDE GENERATOR - Tạo tài liệu hướng dẫn tự động")
print("=" * 60)
# Hiển thị trạng thái auth
print(f"🔐 {get_auth_status()}")
# Hỏi mode: Tạo mới hay Replay
mode_choice = prompt_choice(
"🎯 Bạn muốn:",
["Tạo guide mới (record từ đầu)", "Dùng lại script đã record (replay)"],
default=1
)3.2. Các hàm hỗ trợ
Hỏi Có/Không:
python
def prompt_yes_no(question: str, default: bool = True) -> bool:
"""Hỏi người dùng yes/no với default value."""
suffix = " (Y/n): " if default else " (y/N): "
while True:
response = input(question + suffix).strip().lower()
if not response:
return default
if response in ('y', 'yes', 'có', 'co'):
return True
if response in ('n', 'no', 'không', 'khong'):
return FalseHỏi lựa chọn:
python
def prompt_choice(question: str, choices: list, default: int = 1) -> int:
"""Hỏi người dùng chọn từ danh sách."""
print(question)
for i, choice in enumerate(choices, 1):
marker = " (mặc định)" if i == default else ""
print(f" [{i}] {choice}{marker}")
while True:
response = input(f" Chọn [1-{len(choices)}]: ").strip()
if not response:
return default
# Validate input...4. Tính năng phát lại
4.1. Liệt kê các hướng dẫn đã tạo
python
def list_existing_guides() -> list:
"""Liệt kê tất cả các guides đã tạo trước đó."""
output_dir = Path("output")
guides = []
# Duyệt qua hostname directories
for hostname_dir in output_dir.iterdir():
for guide_dir in hostname_dir.iterdir():
script_path = guide_dir / "recorded_script.py"
if script_path.exists():
created_time = datetime.fromtimestamp(script_path.stat().st_mtime)
guides.append((hostname_dir.name, guide_dir.name, script_path, created_time))
# Sắp xếp theo thời gian (mới nhất trước)
guides.sort(key=lambda x: x[3], reverse=True)
return guides4.2. Chọn hướng dẫn để phát lại
python
def select_existing_guide() -> dict:
"""Cho phép người dùng chọn guide để replay."""
guides = list_existing_guides()
print("📚 CÁC GUIDE ĐÃ TẠO:")
for i, (hostname, guide_name, _, created_time) in enumerate(guides, 1):
print(f" [{i}] {hostname}/{guide_name}")
print(f" 📅 {created_time.strftime('%Y-%m-%d %H:%M')}")
# User chọn → Return config dict
return {
'mode': 'replay',
'hostname': hostname,
'guide_name': guide_name,
'script_path': script_path,
# ...
}5. Luồng cấu hình
5.1. Mẫu trả về Dict
Cả interactive_menu() và CLI đều trả về dict cùng format:
python
{
'mode': 'new' | 'replay',
'url': str,
'name': str,
'title': str,
'provider': 'gemini' | 'openai' | 'none',
'generate_tests': bool,
'test_type': 'unit' | 'integration' | 'both',
'run_tests': bool
}5.2. Xử lý theo chế độ
python
if mode == 'replay':
# Replay existing guide
from src.orchestrator import replay_and_regenerate
success = replay_and_regenerate(config, script_path)
else:
# Create new guide
success = orchestrate(config)6. Tích hợp tạo test
6.1. Cấu hình test
python
def generate_tests_from_config(script_path, output_dir, test_type, provider, run_tests):
"""Generate tests từ recorded script."""
# Convert string to enum
test_type_enum = {
"unit": TestType.UNIT,
"integration": TestType.INTEGRATION,
"both": TestType.BOTH
}[test_type]
# Create config
test_config = TestGenerationConfig(
script_path=script_path,
output_dir=output_dir / "tests",
test_type=test_type_enum,
use_ai=(provider != "none"),
# ...
)
# Generate
orchestrator = TestOrchestrator()
result = orchestrator.generate_tests_from_script(script_path, test_config)7. Thực hành tốt
7.1. Nguyên tắc trải nghiệm người dùng
| Nguyên tắc | Áp dụng |
|---|---|
| Giá trị mặc định hợp lý | URL mặc định, tên tự động theo timestamp |
| Tiết lộ dần dần | Hỏi từng bước, không làm người dùng choáng ngợp |
| Xác nhận | Hiển thị tóm tắt trước khi bắt đầu |
| Thoát nhẹ nhàng | Cho phép hủy ở mọi bước |
7.2. Tổ chức mã nguồn
guide_ai.py
├── Argument Parser (CLI)
├── Helper Functions
│ ├── prompt_yes_no()
│ ├── prompt_choice()
│ └── list_existing_guides()
├── Interactive Menu
│ ├── interactive_menu()
│ └── select_existing_guide()
├── Test Generation
│ └── generate_tests_from_config()
└── Main Entry Point
└── main()8. Ví dụ sử dụng
Chế độ dòng lệnh
bash
# Tạo guide mới với Gemini
python guide_ai.py --provider gemini --name login_guide --url https://example.com
# Không dùng AI
python guide_ai.py --no-ai --name quick_test
# Tạo guide + tests
python guide_ai.py --provider gemini --name full_guide --generate-tests --run-testsLệnh xác thực
bash
# Lưu session đăng nhập
python guide_ai.py --save-auth --url https://portal.inet.vn
# Kiểm tra trạng thái
python guide_ai.py --auth-status
# Xóa session
python guide_ai.py --clear-authTổng kết
guide_ai.py thiết kế CLI theo nguyên tắc:
- Hai chế độ: Tương tác cho người mới, dòng lệnh cho tự động hóa
- Module hóa: Tách biệt phân tích, hỏi đáp, thực thi
- Mở rộng được: Dễ thêm tùy chọn mới (xác thực, test)
- Thân thiện: Giao diện tiếng Việt, phản hồi rõ ràng