You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于基于Playwright Python实现Chrome浏览器下Swagger API自动化及Ansible Tower自动化Python框架的技术需求与建议征集

Got it, let's tackle your two requirements step by step—first building a Playwright Python script for Swagger API automation in Chrome, then creating a Python framework that plays nicely with Ansible Tower.

1. Playwright Python Script for Swagger API Automation in Chrome

Swagger UI is a web interface, so we'll use Playwright's browser automation to interact with it just like a human would. Here's a practical implementation:

Prerequisites

First, set up your environment:

  • Install Playwright and Chrome dependencies:
    pip install playwright
    playwright install chrome
    

Core Automation Script

This script targets a sample Swagger UI, navigates to a specific API endpoint, fills in parameters, executes the request, and validates the response:

from playwright.sync_api import sync_playwright
import logging
import json

# Configure logging for debugging (critical for Ansible Tower integration)
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)

def automate_swagger_api(swagger_url: str, api_operation_id: str, request_body: dict):
    with sync_playwright() as p:
        # Launch Chrome in headless mode (ideal for server environments like Ansible Tower)
        browser = p.chromium.launch(headless=True, channel="chrome")
        page = browser.new_page()
        
        try:
            # Navigate to Swagger UI and wait for full load
            page.goto(swagger_url, wait_until="networkidle")
            logger.info(f"Successfully loaded Swagger UI at {swagger_url}")

            # Expand the target API operation using its unique operation ID (more stable than text)
            expand_button = page.locator(f'[data-operation-id="{api_operation_id}"]').locator('button')
            expand_button.click()
            logger.info(f"Expanded API operation: {api_operation_id}")

            # Click "Try it out" to enable parameter editing
            try_it_button = page.locator(f'[data-operation-id="{api_operation_id}"] button:has-text("Try it out")')
            try_it_button.click()
            logger.info("Enabled API parameter editing via 'Try it out'")

            # Fill in request body (adjust selector if your Swagger UI uses a different layout)
            body_textarea = page.locator(f'[data-operation-id="{api_operation_id}"] textarea[name="body"]')
            body_textarea.fill(json.dumps(request_body))
            logger.info(f"Filled request body: {json.dumps(request_body)}")

            # Execute the API request
            execute_button = page.locator(f'[data-operation-id="{api_operation_id}"] button:has-text("Execute")')
            execute_button.click()

            # Wait for response and extract status code
            response_status = page.locator(f'[data-operation-id="{api_operation_id}"] .response-col_status')
            response_status.wait_for(timeout=10000)
            status_code = response_status.text_content().strip()
            logger.info(f"API executed successfully, status code: {status_code}")

            # Extract and return response details
            response_body = page.locator(f'[data-operation-id="{api_operation_id}"] .response-col_body pre').text_content()
            return {"status": "success", "status_code": status_code, "response_body": json.loads(response_body)}

        except Exception as e:
            logger.error(f"Automation failed: {str(e)}", exc_info=True)
            # Capture screenshot for debugging (saved to Tower's execution directory)
            page.screenshot(path=f"swagger_error_{api_operation_id}.png")
            raise  # Re-raise to let Ansible Tower mark the job as failed
        finally:
            browser.close()

# Example direct execution
if __name__ == "__main__":
    automate_swagger_api(
        swagger_url="https://petstore.swagger.io/v2/swagger.json",
        api_operation_id="addPet",
        request_body={"id": 123, "name": "TestPet", "status": "available"}
    )

Key Reliability Tips

  • Use operation IDs instead of text selectors: Swagger generates unique data-operation-id attributes for each endpoint, making your script resistant to UI text changes.
  • Headless mode: Non-negotiable for Ansible Tower's server environment (no GUI required).
  • Timeouts & retries: Add wait_for calls with reasonable timeouts to handle slow-loading Swagger UIs.
2. Ansible Tower-Friendly Python Framework

To make your automation work seamlessly with Ansible Tower, focus on configurability, compatibility with Tower's execution model, and clear error handling. Here's how to structure the framework:

Core Framework Components

a. Configurability (No Hardcoding!)

Use command-line arguments and environment variables to pass parameters—Tower can inject these via job templates:

import argparse
import os
import json

def parse_args():
    parser = argparse.ArgumentParser(description="Swagger API Automation for Ansible Tower")
    parser.add_argument("--swagger-url", default=os.getenv("SWAGGER_URL"), required=True, help="URL of Swagger UI")
    parser.add_argument("--api-operation-id", default=os.getenv("API_OPERATION_ID"), required=True, help="Target API operation ID")
    parser.add_argument("--request-body", default=os.getenv("REQUEST_BODY"), required=True, help="JSON request body")
    return parser.parse_args()

# In your main execution flow
args = parse_args()
request_body = json.loads(args.request_body)
automate_swagger_api(args.swagger_url, args.api_operation_id, request_body)

b. Ansible Tower Compatibility

  • Proper exit codes: Tower uses exit codes to mark jobs as success/failure. Re-raising exceptions (like in the script above) ensures non-zero exit codes on failure.
  • Log to stdout/stderr: Tower captures console logs, so use Python's logging module with StreamHandler to send all logs directly to the console.
  • Dependency management: Create a requirements.txt file for your dependencies:
    playwright==1.40.0
    
    Add a pre-run step in your Tower job template to install them:
    pip install -r requirements.txt && playwright install chrome --with-deps
    

c. Integration with Tower's Ecosystem

  • Use Tower environment variables: If you need to interact with Tower's API post-execution, leverage built-in variables like TOWER_HOST and TOWER_OAUTH_TOKEN.
  • Idempotent operations: Ensure your API automation is idempotent (running it multiple times doesn't cause unintended side effects)—critical for repeatable Tower jobs.

Example Tower Job Setup

  1. Store code in Git: Push your framework and scripts to a Git repo (Tower can pull this directly via a project).
  2. Create a Job Template:
    • Select "Python" as the execution environment.
    • Set the command to:
      python swagger_automation.py --swagger-url "{{ swagger_url }}" --api-operation-id "{{ api_operation_id }}" --request-body "{{ request_body }}"
      
    • Add Extra Variables for swagger_url, api_operation_id, and request_body (set defaults or prompt users at runtime).
  3. Configure Environment Variables:
    • Add PLAYWRIGHT_BROWSERS_PATH=0 to force Playwright to use the system-installed Chrome (avoids downloading browsers in Tower's temporary space).

Bonus Tips

  • Isolated execution: Run your script in a Docker container pre-configured with Playwright and Chrome to avoid dependency conflicts in Tower.
  • Notifications: Add logic to trigger Tower's built-in notifications (Slack, email, etc.) on success/failure.
  • Result storage: Push automation results (like response data) to Tower's custom facts or a external datastore for auditing.

内容的提问来源于stack exchange,提问作者Ali Haider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 09:22:29