Receber por email
← Voltar para o catálogo

happyflow-generator

Automatically generate and execute Python test scripts from OpenAPI specifications and GraphQL schemas with enhanced features

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/happyflow-generator/svg)](https://www.skillteca.com.br/skills/happyflow-generator)

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

HappyFlow Generator Skill

Metadata

  • Skill Name: HappyFlow Generator
  • Version: 2.0.0
  • Category: API Testing & Automation
  • Required Capabilities: Code execution, web requests, file operations
  • Estimated Duration: 2-5 minutes per API spec
  • Difficulty: Intermediate

Description

Automatically generate and execute Python test scripts from OpenAPI specifications and GraphQL schemas that successfully call all API endpoints in dependency-correct order, ensuring all requests return 2xx status codes.

Input: OpenAPI/GraphQL spec (URL/file) + authentication credentials Output: Working Python script that executes complete API happy path flow

Key Features:

  • Multi-format support: OpenAPI 3.0+ and GraphQL schemas
  • Enhanced execution: Parallel execution, detailed reporting, connection pooling
  • Advanced testing: File upload support, response schema validation, rate limiting handling
  • Modular architecture: Well-organized codebase with proper error handling

Complete Workflow

Phase 1: Authentication Setup

Execute this code to prepare authentication headers:

import base64
import requests
from typing import Dict, Any

def setup_authentication(auth_type: str, credentials: Dict[str, Any]) -> Dict[str, str]:
    """Prepare authentication headers based on auth type"""

    if auth_type == "bearer":
        return {"Authorization": f"Bearer {credentials['token']}"}

    elif auth_type == "api_key":
        header_name = credentials.get('header_name', 'X-API-Key')
        return {header_name: credentials['api_key']}

    elif auth_type == "basic":
        auth_string = f"{credentials['username']}:{credentials['password']}"
        encoded = base64.b64encode(auth_string.encode()).decode()
        return {"Authorization": f"Basic {encoded}"}

    elif auth_type == "oauth2_client_credentials":
        token_url = credentials['token_url']
        data = {
            'grant_type': 'client_credentials',
            'client_id': credentials['client_id'],
            'client_secret': credentials['client_secret']
        }
        if 'scopes' in credentials:
            data['scope'] = ' '.join(credentials['scopes'])

        response = requests.post(token_url, data=data)
        response.raise_for_status()
        token_data = response.json()

        return {"Authorization": f"Bearer {token_data['access_token']}"}

    return {}

# Example usage:
# auth_headers = setup_authentication("bearer", {"token": "abc123"})

Phase 2: Specification Parsing

Execute this code to parse API specifications (OpenAPI or GraphQL):

import requests
import yaml
import json
import re
from typing import Dict, List, Any, Union
from pathlib import Path

def parse_specification(spec_source: Union[str, Path], spec_type: str = "auto", **kwargs) -> Dict[str, Any]:
    """Parse API specification and extract structured information
    
    Args:
        spec_source: Path or URL to API specification
        spec_type: Type of specification ('openapi', 'graphql', or 'auto')
        **kwargs: Additional arguments for specific parsers
        
    Returns:
        Dictionary containing parsed specification data
    """
    
    # Auto-detect specification type if not specified
    if spec_type == "auto":
        if isinstance(spec_source, str):
            if spec_source.endswith(".graphql") or "graphql" in spec_source.lower():
                spec_type = "graphql"
            else:
                spec_type = "openapi"
        else:
            # For file paths, check extension
            path = Path(spec_source)
            if path.suffix.lower() in [".graphql", ".gql"]:
                spec_type = "graphql"
            else:
                spec_type = "openapi"

    # Parse based on detected type
    if spec_type == "openapi":
        return parse_openapi_spec(spec_source, **kwargs)
    elif spec_type == "graphql":
        return parse_graphql_spec(spec_source, **kwargs)
    else:
        raise ValueError(f"Unsupported specification type: {spec_type}")

def parse_openapi_spec(spec_source: Union[str, Path], headers: Dict[str, str] = None) -> Dict[str, Any]:
    """Parse OpenAPI specification and extract structured information"""

    # Fetch spec
    if isinstance(spec_source, str) and spec_source.startswith('http'):
        response = requests.get(spec_source, headers=headers or {})
        response.raise_for_status()
        content = response.text
        try:
            spec = json.loads(content)
        except json.JSONDecodeError:
            spec = yaml.safe_load(content)
    else:
        with open(spec_source, 'r') as f:
            content = f.read()
            try:
                spec = json.loads(content)
            except json.JSONDecodeError:
                spec = yaml.safe_load(content)

    # Extract base information
    openapi_version = spec.get('openapi', spec.get('swagger', 'unknown'))
    base_url = ""

    if 'servers' in spec and spec['servers']:
        base_url = spec['servers'][0]['url']
    elif 'host' in spec:
        scheme = spec.get('schemes', ['https'])[0]
        base_path = spec.get('basePath', '')
        base_url = f"{scheme}://{spec['host']}{base_path}"

    # Extract endpoints
    endpoints = []
    paths = spec.get('paths', {})

    for path, path_item in paths.items():
        for method in ['get', 'post', 'put', 'patch', 'delete']:
            if method not in path_item:
                continue

            operation = path_item[method]

            # Extract parameters
            parameters = []
            for param in operation.get('parameters', []):
                parameters.append({
                    'name': param.get('name'),
                    'in': param.get('in'),
                    'required': param.get('required', False),
                    'schema': param.get('schema', {}),
                    'example': param.get('example')
                })

            # Extract request body
            request_body = None
            if 'requestBody' in operation:
                rb = operation['requestBody']
                content = rb.get('content', {})

                if 'application/json' in content:
                    json_content = content['application/json']
                    request_body = {
                        'required': rb.get('required', False),
                        'content_type': 'application/json',
                        'schema': json_content.get('schema', {}),
                        'example': json_content.get('example')
                    }
                elif 'multipart/form-data' in content:
                    form_content = content['multipart/form-data']
                    request_body = {
                        'required': rb.get('required', False),
                        'content_type': 'multipart/form-data',
                        'schema': form_content.get('schema', {}),
                        'example': form_content.get('example')
                    }

            # Extract responses
            responses = {}
            for status_code, response_data in operation.get('responses', {}).items():
                if status_code.startswith('2'):
                    content = response_data.get('content', {})
                    if 'application/json' in content:
                        json_content = content['application/json']
                        responses[status_code] = {
                            'description': response_data.get('description', ''),
                            'schema': json_content.get('schema', {}),
                            'example': json_content.get('example')
                        }

            endpoint = {
                'operation_id': operation.get('operationId', f"{method}_{path}"),
                'path': path,
                'method': method.upper(),
                'tags': operation.get('tags', []),
                'summary': operation.get('summary', ''),
Compartilhar X LinkedIn