Skip to main content سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/aiskillstore/marketplace --skill happyflow-generatorيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... المهن ذات الصلة SOC
استنادا إلى تصنيف SOC المهني
name happyflow-generator description Automatically generate and execute Python test scripts from OpenAPI specifications and GraphQL schemas with enhanced features
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 {}
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
"""
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 :
path = Path(spec_source)
if path.suffix.lower() in [".graphql" , ".gql" ]:
spec_type = "graphql"
:
spec_type =
spec_type == :
parse_openapi_spec(spec_source, **kwargs)
spec_type == :
parse_graphql_spec(spec_source, **kwargs)
:
ValueError( )
( ) -> [ , ]:
(spec_source, ) spec_source.startswith( ):
response = requests.get(spec_source, headers=headers {})
response.raise_for_status()
content = response.text
:
spec = json.loads(content)
json.JSONDecodeError:
spec = yaml.safe_load(content)
:
(spec_source, ) f:
content = f.read()
:
spec = json.loads(content)
json.JSONDecodeError:
spec = yaml.safe_load(content)
openapi_version = spec.get( , spec.get( , ))
base_url =
spec spec[ ]:
base_url = spec[ ][ ][ ]
spec:
scheme = spec.get( , [ ])[ ]
base_path = spec.get( , )
base_url =
endpoints = []
paths = spec.get( , {})
path, path_item paths.items():
method [ , , , , ]:
method path_item:
operation = path_item[method]
parameters = []
param operation.get( , []):
parameters.append({
: param.get( ),
: param.get( ),
: param.get( , ),
: param.get( , {}),
: param.get( )
})
request_body =
operation:
rb = operation[ ]
content = rb.get( , {})
content:
json_content = content[ ]
request_body = {
: rb.get( , ),
: ,
: json_content.get( , {}),
: json_content.get( )
}
content:
form_content = content[ ]
request_body = {
: rb.get( , ),
: ,
: form_content.get( , {}),
: form_content.get( )
}
responses = {}
status_code, response_data operation.get( , {}).items():
status_code.startswith( ):
content = response_data.get( , {})
content:
json_content = content[ ]
responses[status_code] = {
: response_data.get( , ),
: json_content.get( , {}),
: json_content.get( )
}
endpoint = {
: operation.get( , ),
: path,
: method.upper(),
: operation.get( , []),
: operation.get( , ),
: parameters,
: request_body,
: responses
}
endpoints.append(endpoint)
{
: openapi_version,
: base_url,
: endpoints,
: spec.get( , {}).get( , {})
}
( ) -> [ , ]:
base_url = spec_source (spec_source, ) spec_source.startswith( )
endpoints = [
{
: ,
: ,
: ,
: [ ],
: ,
: [],
: {
: ,
: ,
: {},
: { : }
},
: {
: {
: ,
: {},
: {}
}
}
}
]
{
: ,
: base_url,
: endpoints,
: {}
}
Phase 3: Dependency Analysis
Execute this code to analyze dependencies and determine execution order:
import re
from typing import List , Dict , Any
def analyze_dependencies (endpoints: List [Dict ] ) -> Dict [str , Any ]:
"""Analyze endpoint dependencies and create execution order"""
dependencies = {}
outputs = {}
for endpoint in endpoints:
endpoint_id = f"{endpoint['method' ]} {endpoint['path' ]} "
dependencies[endpoint_id] = []
outputs[endpoint_id] = {}
for endpoint in endpoints:
endpoint_id = f"{endpoint['method' ]} {endpoint['path' ]} "
path = endpoint['path' ]
path_params = re.findall(r'\{(\w+)\}' , path)
for param in path_params:
for other_endpoint in endpoints:
other_id = f"{other_endpoint['method' ]} {other_endpoint['path' ]} "
if other_endpoint['method' ] in ['POST' , 'PUT' ]:
for status, response in other_endpoint.get('responses' , {}).items():
schema = response.get( , {})
properties = schema.get( , {})
properties param properties:
other_id != endpoint_id other_id dependencies[endpoint_id]:
dependencies[endpoint_id].append(other_id)
output_field = properties param
outputs[other_id][param] =
method_priority = { : , : , : , : , : }
endpoint endpoints:
endpoint_id =
path_clean = re.sub( , , endpoint[ ])
other_endpoint endpoints:
other_id =
other_path_clean = re.sub( , , other_endpoint[ ])
path_clean == other_path_clean:
method_priority.get(endpoint[ ], ) > method_priority.get(other_endpoint[ ], ):
other_id dependencies[endpoint_id]:
dependencies[endpoint_id].append(other_id)
( ):
in_degree = {node: node deps}
node deps:
dep deps[node]:
in_degree[dep] = in_degree.get(dep, ) +
queue = [node node deps in_degree[node] == ]
result = []
queue:
queue.sort(key= x: (x.split()[ ].count( ), method_priority.get(x.split()[ ], )))
node = queue.pop( )
result.append(node)
other_node deps:
node deps[other_node]:
in_degree[other_node] -=
in_degree[other_node] == :
queue.append(other_node)
result
execution_order_ids = topological_sort(dependencies)
execution_plan = []
step, endpoint_id (execution_order_ids, ):
endpoint = (e e endpoints == endpoint_id)
inputs = {}
dep_id dependencies[endpoint_id]:
dep_id outputs:
param_name, json_path outputs[dep_id].items():
dep_step = execution_order_ids.index(dep_id) +
inputs[param_name] = {
: ,
: json_path
}
execution_plan.append({
: step,
: endpoint,
: dependencies[endpoint_id],
: inputs,
: outputs[endpoint_id]
})
{
: execution_plan,
: dependencies
}
( ) -> [ [ ]]:
parallel_groups = []
processed_steps = ()
independent_steps = [step[ ] step execution_plan step[ ]]
independent_steps:
parallel_groups.append(independent_steps)
processed_steps.update(independent_steps)
remaining_steps = [step step execution_plan step[ ] processed_steps]
dependency_map = {}
step remaining_steps:
dep_tuple = ( (step[ ]))
dep_tuple dependency_map:
dependency_map[dep_tuple] = []
dependency_map[dep_tuple].append(step[ ])
group dependency_map.values():
parallel_groups.append(group)
parallel_groups
Phase 4: Script Generation
Execute this code to generate the Python test script:
import json
import time
from typing import Dict , List , Any
from jsonschema import validate, ValidationError
def generate_value_from_schema (schema: Dict , field_name: str = "" ) -> Any :
"""Generate example value based on schema"""
if 'example' in schema:
return schema['example' ]
if 'default' in schema:
return schema['default' ]
if 'enum' in schema:
return schema['enum' ][0 ]
schema_type = schema.get('type' , 'string' )
if schema_type == 'string' :
if schema.get('format' ) == 'email' :
return 'test@example.com'
elif schema.get('format' ) == 'uuid' :
return '550e8400-e29b-41d4-a716-446655440000'
elif 'email' in field_name.lower():
return
field_name.lower():
field_name.lower():
schema_type == :
minimum = schema.get( , )
maximum = schema.get( , minimum + )
(minimum, )
schema_type == :
schema_type == :
schema_type == :
items_schema = schema.get( , {})
[generate_value_from_schema(items_schema)]
schema_type == :
obj = {}
prop, prop_schema schema.get( , {}).items():
prop schema.get( , []) schema.get( ):
obj[prop] = generate_value_from_schema(prop_schema, prop)
obj
( ) -> :
lines = []
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
parallel_execution:
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
parallel_execution parallel_groups:
lines.append( )
lines.append( )
lines.append( )
lines.append( )
group parallel_groups:
(group) > :
step_num group:
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
parallel_execution parallel_groups:
executed_steps = ()
i, group (parallel_groups):
(group) > :
lines.append( )
lines.append( )
lines.append( )
executed_steps.update(group)
:
step_num = group[ ]
step_num executed_steps:
lines.append( )
executed_steps.add(step_num)
step_info execution_plan:
step_num = step_info[ ]
step_num executed_steps:
lines.append( )
:
step_info execution_plan:
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
step_info execution_plan:
endpoint = step_info[ ]
step_num = step_info[ ]
method = endpoint[ ]
path = endpoint[ ]
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( % method)
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
url_expr =
path:
param re.findall( , path):
url_expr = url_expr.replace( , )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
endpoint.get( ):
schema = endpoint[ ].get( , {})
example = endpoint[ ].get( )
content_type = endpoint[ ].get( , )
example:
payload = example
:
payload = generate_value_from_schema(schema)
lines.append( )
content_type == :
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( % method.lower())
:
lines.append( )
lines.append( )
lines.append( % method.lower())
:
lines.append( )
lines.append( % method.lower())
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
success_response =
status_code, resp_data endpoint.get( , {}).items():
status_code.startswith( ):
success_response = resp_data
success_response success_response.get( ):
schema = success_response[ ]
lines.append( )
lines.append( % json.dumps(schema))
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
step_info[ ]:
output_name, json_path step_info[ ].items():
field = json_path.split( )[- ]
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( % step_num)
lines.append( )
lines.append( % method)
lines.append( % path)
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
lines.append( )
.join(lines)
Phase 5: Execute and Iterate
Execute this code to run the script and fix errors:
import subprocess
import tempfile
import os
import re
def execute_script_with_retries (script_content: str , max_retries: int = 5 , detailed_reporting: bool = False ):
"""Execute script and retry with fixes"""
for attempt in range (1 , max_retries + 1 ):
print (f"\n=== Attempt {attempt} /{max_retries} ===" )
with tempfile.NamedTemporaryFile(mode='w' , suffix='.py' , delete=False ) as f:
f.write(script_content)
script_path = f.name
try :
env = os.environ.copy()
if detailed_reporting:
env["DETAILED_REPORT" ] = "true"
result = subprocess.run(
['python' , script_path],
capture_output=True ,
text=True ,
timeout=300 ,
env=env
)
print (result.stdout)
if result.returncode == 0 :
print ("\n✓ SUCCESS! All requests returned 2xx" )
return {
'success' : True ,
: script_content,
: attempt
}
( )
result.stdout result.stdout:
field_match = re.search( , result.stdout)
field_match:
field = field_match.group( )
script_content = script_content.replace(
,
)
( )
result.stdout:
script_content = script_content.replace( , )
script_content = script_content.replace( , )
( )
subprocess.TimeoutExpired:
( )
Exception e:
( )
:
os.path.exists(script_path):
os.unlink(script_path)
{
: ,
: script_content,
: max_retries
}
Complete End-to-End Example
Here's how to execute the entire workflow:
auth_headers = setup_authentication("bearer" , {"token" : "YOUR_TOKEN" })
parsed_spec = parse_specification("https://api.example.com/openapi.json" )
print (f"Found {len (parsed_spec['endpoints' ])} endpoints" )
dependency_analysis = analyze_dependencies(parsed_spec['endpoints' ])
parallel_groups = identify_parallel_groups(dependency_analysis['execution_order' ])
print (f"Execution order: {len (dependency_analysis['execution_order' ])} steps" )
generated_script = generate_python_script(
dependency_analysis['execution_order' ],
parsed_spec['base_url' ],
auth_headers,
parallel_execution=True ,
parallel_groups=parallel_groups
)
print (f"Generated script: {len (generated_script)} characters" )
final_result = execute_script_with_retries(generated_script, max_retries=5 , detailed_reporting=True )
if final_result['success' ]:
print ("\n" + "=" *60 )
print ("✓ HAPPYFLOW SCRIPT GENERATED SUCCESSFULLY" )
print ("=" *60 )
( )
( )
(final_result[ ])
:
( )
( )
Usage Instructions
When invoked, execute this skill by:
Receive input from user (API spec URL + credentials)
Execute Phase 1 code with user's auth credentials
Execute Phase 2 code with spec URL
Execute Phase 3 code with parsed endpoints
Execute Phase 4 code to generate script with enhanced features
Execute Phase 5 code to test and fix script
Return final working script to user
Output Format
Return to user:
## ✓ HappyFlow Script Generated Successfully
**API** : [API name from spec]
**Total Endpoints** : [count]
**Execution Attempts** : [attempts]
### Generated Script
```python
[COMPLETE WORKING SCRIPT]
Usage
Save as test_api.py
Run: python test_api.py
All requests will return 2xx status codes
Enhanced Features Used
Parallel Execution : Enabled for faster testing
Detailed Reporting : Set DETAILED_REPORT=true for comprehensive metrics
Rate Limiting Handling : Automatic retry with exponential backoff
Response Validation : JSON Schema validation for responses
## Enhanced Features
### Multi-Format Support
- **OpenAPI 3.0+**: Full specification parsing with schema resolution
- **GraphQL**: Schema introspection and operation extraction
### Advanced Execution
- **Parallel Execution**: Concurrent execution of independent endpoints
- **Detailed Reporting**: Comprehensive execution metrics and timing
- **Connection Pooling**: HTTP connection reuse for improved performance
- **Caching**: Specification parsing cache for reduced processing time
### Enhanced Testing Capabilities
- **File Upload Support**: Multipart/form-data request handling
- **Response Schema Validation**: JSON Schema validation against specifications
- **Rate Limiting Handling**: Automatic retry with exponential backoff
- **Error Recovery**: Intelligent error handling and automatic fixes
### Improved Code Quality
- **Modular Architecture**: Well-organized components for maintainability
- **Type Hints**: Comprehensive type annotations throughout
- **Custom Exceptions**: Structured exception hierarchy
- **Proper Logging**: Structured logging instead of print statements
## Version History
- v2.0.0 (2026-01-08): Enhanced implementation with modular architecture
- v1.0.0 (2025-12-29): Self-contained implementation with embedded code
else
"openapi"
if
"openapi"
return
elif
"graphql"
return
else
raise
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"""
if
isinstance
str
and
'http'
or
try
except
else
with
open
'r'
as
try
except
'openapi'
'swagger'
'unknown'
""
if
'servers'
in
and
'servers'
'servers'
0
'url'
elif
'host'
in
'schemes'
'https'
0
'basePath'
''
f"{scheme} ://{spec['host' ]} {base_path} "
'paths'
for
in
for
in
'get'
'post'
'put'
'patch'
'delete'
if
not
in
continue
for
in
'parameters'
'name'
'name'
'in'
'in'
'required'
'required'
False
'schema'
'schema'
'example'
'example'
None
if
'requestBody'
in
'requestBody'
'content'
if
'application/json'
in
'application/json'
'required'
'required'
False
'content_type'
'application/json'
'schema'
'schema'
'example'
'example'
elif
'multipart/form-data'
in
'multipart/form-data'
'required'
'required'
False
'content_type'
'multipart/form-data'
'schema'
'schema'
'example'
'example'
for
in
'responses'
if
'2'
'content'
if
'application/json'
in
'application/json'
'description'
'description'
''
'schema'
'schema'
'example'
'example'
'operation_id'
'operationId'
f"{method} _{path} "
'path'
'method'
'tags'
'tags'
'summary'
'summary'
''
'parameters'
'request_body'
'responses'
return
'openapi_version'
'base_url'
'endpoints'
'schemas'
'components'
'schemas'
def
parse_graphql_spec
spec_source: str , headers: Dict [str , str ] = None
Dict
str
Any
"""Parse GraphQL schema and extract operations"""
if
isinstance
str
and
'http'
else
""
'operation_id'
'graphql_query'
'path'
'/graphql'
'method'
'POST'
'tags'
'GraphQL'
'summary'
'GraphQL Query'
'parameters'
'request_body'
'required'
True
'content_type'
'application/json'
'schema'
'example'
'query'
'query { __schema { types { name } } }'
'responses'
'200'
'description'
'Successful GraphQL response'
'schema'
'example'
return
'spec_type'
'graphql'
'base_url'
'endpoints'
'schemas'
'schema'
'properties'
if
'id'
in
or
in
if
and
not
in
'id'
if
'id'
in
else
f"response.body.{output_field} "
'POST'
1
'GET'
2
'PUT'
3
'PATCH'
3
'DELETE'
4
for
in
f"{endpoint['method' ]} {endpoint['path' ]} "
r'\{[^}]+\}'
''
'path'
for
in
f"{other_endpoint['method' ]} {other_endpoint['path' ]} "
r'\{[^}]+\}'
''
'path'
if
if
'method'
5
'method'
5
if
not
in
def
topological_sort
deps
0
for
in
for
in
for
in
0
1
for
in
if
0
while
lambda
1
'/'
0
5
0
for
in
if
in
1
if
0
return
for
in
enumerate
1
next
for
in
if
f"{e['method' ]} {e['path' ]} "
for
in
if
in
for
in
1
'source'
f"step_{dep_step} "
'json_path'
'step'
'endpoint'
'dependencies'
'inputs'
'outputs'
return
'execution_order'
'dependency_graph'
def
identify_parallel_groups
execution_plan: List [Dict ]
List
List
int
"""Identify groups of steps that can be executed in parallel"""
set
'step'
for
in
if
not
'dependencies'
if
for
in
if
'step'
not
in
for
in
tuple
sorted
'dependencies'
if
not
in
'step'
for
in
return
'test@example.com'
elif
'name'
in
return
'Test User'
elif
'description'
in
return
'Test description'
return
'test_value'
elif
'integer'
'minimum'
1
'maximum'
100
return
max
1
elif
'number'
return
10.5
elif
'boolean'
return
True
elif
'array'
'items'
return
elif
'object'
for
in
'properties'
if
in
'required'
or
not
'required'
return
return
None
def
generate_python_script
execution_plan: List [Dict ],
base_url: str ,
auth_headers: Dict ,
parallel_execution: bool = False ,
parallel_groups: List [List [int ]] = None
str
"""Generate complete Python script"""
'#!/usr/bin/env python3'
'"""HappyFlow Generator - Auto-generated API test script"""'
''
'import requests'
'import json'
'import sys'
'import time'
'from datetime import datetime'
if
'from concurrent.futures import ThreadPoolExecutor, as_completed'
'from jsonschema import validate, ValidationError'
''
'class APIFlowExecutor:'
' def __init__(self, base_url, auth_headers):'
' self.base_url = base_url.rstrip("/")'
' self.session = requests.Session()'
' self.session.headers.update(auth_headers)'
' self.context = {}'
' self.results = []'
''
' def log(self, message, level="INFO"):'
' print(f"[{datetime.utcnow().isoformat()}] [{level}] {message}")'
''
' def _make_request(self, method, url, **kwargs):'
' """Make HTTP request with retry logic for rate limiting"""'
' max_retries = 3'
' for attempt in range(max_retries):'
' try:'
' response = self.session.request(method, url, **kwargs)'
' # Handle rate limiting'
' if response.status_code == 429:'
' if attempt < max_retries - 1:'
' delay = 2 ** attempt # Exponential backoff'
' self.log(f"Rate limited. Waiting {delay}s before retry...", "WARN")'
' time.sleep(delay)'
' continue'
' return response'
' except Exception as e:'
' if attempt < max_retries - 1:'
' delay = 2 ** attempt'
' self.log(f"Request failed: {e}. Retrying in {delay}s...", "WARN")'
' time.sleep(delay)'
' else:'
' raise'
''
if
and
' def execute_parallel_group(self, step_numbers):'
' """Execute a group of steps in parallel"""'
' with ThreadPoolExecutor(max_workers=5) as executor:'
' future_to_step = {'
for
in
if
len
1
for
in
f' executor.submit(self.step_{step_num} ): {step_num} ,'
break
' }'
' '
' for future in as_completed(future_to_step):'
' step_num = future_to_step[future]'
' try:'
' future.result()'
' self.log(f"Step {step_num} completed successfully")'
' except Exception as e:'
' self.log(f"Step {step_num} failed: {e}", "ERROR")'
' raise'
''
' def execute_flow(self):'
' try:'
if
and
set
for
in
enumerate
if
len
1
f' # Parallel Group {i+1 } '
f' self.log("Executing parallel group: {group} ")'
f' self.execute_parallel_group({group} )'
else
0
if
not
in
f' self.step_{step_num} ()'
for
in
'step'
if
not
in
f' self.step_{step_num} ()'
else
for
in
f' self.step_{step_info["step" ]} ()'
' self.log("✓ All requests completed", "SUCCESS")'
' return True'
' except Exception as e:'
' self.log(f"✗ Failed: {e}", "ERROR")'
' return False'
''
for
in
'endpoint'
'step'
'method'
'path'
f' def step_{step_num} (self):'
f' """Step {step_num} : {method} {path} """'
f' self.log("Step {step_num} : {method} {path} ")'
' # Initialize tracking variables'
' start_time = time.time()'
' request_details = {'
' "method": "%s",'
' "url": None,'
' "headers": dict(self.session.headers),'
' "payload": None'
' }'
' response_details = {'
' "status_code": None,'
' "headers": None,'
' "body": None,'
' "elapsed": None'
' }'
' error_details = None'
''
' try:'
f'f"{{self.base_url}}{path} "'
if
'{'
in
for
in
r'\{(\w+)\}'
f'{{{param} }}'
f'{{self.context.get("{param} ", "UNKNOWN_{param} ")}}'
f' # Build URL with path parameters'
f' url = {url_expr} '
' request_details["url"] = url'
''
if
'request_body'
'request_body'
'schema'
'request_body'
'example'
'request_body'
'content_type'
'application/json'
if
else
f' # Handle request body ({content_type} )'
if
'multipart/form-data'
' # Handle file uploads'
' files = {}'
f' payload = {json.dumps(payload) if payload else {} }'
' request_details["payload"] = payload'
' response = self._make_request("%s", url, data=payload, files=files)'
else
f' payload = {json.dumps(payload) if payload else {} }'
' request_details["payload"] = payload'
' response = self._make_request("%s", url, json=payload)'
else
' # No request body'
' response = self._make_request("%s", url)'
' self.log(f"Status: {response.status_code}")'
' if response.status_code not in [200, 201, 202, 204]:'
' raise Exception(f"Unexpected status code: {response.status_code}")'
' if response.text:'
' try:'
' data = response.json()'
None
for
in
'responses'
if
'2'
break
if
and
'schema'
'schema'
' # Validate response against schema'
' schema = %s'
' try:'
' validate(instance=data, schema=schema)'
' self.log("Response validated successfully against schema")'
' except ValidationError as e:'
' self.log(f"Response validation failed: {e.message}", "ERROR")'
' self.log(f"Validation path: {\' -> \'.join(str(x) for x in e.absolute_path)}", "ERROR")'
if
'outputs'
for
in
'outputs'
'.'
1
f' self.context["{output_name} "] = data.get("{field} ")'
' except ValueError:'
' self.log("Warning: Response is not valid JSON", "WARN")'
''
' # Calculate execution time'
' end_time = time.time()'
' elapsed_time = end_time - start_time'
''
' # Capture response details'
' response_details.update({'
' "status_code": response.status_code,'
' "headers": dict(response.headers),'
' "body": response.text[:1000] if response.text else "",'
' "elapsed": elapsed_time'
' })'
''
' except Exception as e:'
' error_details = str(e)'
' self.log(f"Error processing response: {e}", "ERROR")'
' # Still capture timing info even on error'
' end_time = time.time()'
' elapsed_time = end_time - start_time if "start_time" in locals() else 0'
' # Capture partial response details if available'
' if "response" in locals():'
' response_details.update({'
' "status_code": getattr(response, "status_code", None),'
' "headers": dict(getattr(response, "headers", {})),'
' "body": getattr(response, "text", "")[:1000] if getattr(response, "text", "") else "",'
' "elapsed": elapsed_time'
' })'
' raise'
''
' # Store detailed results'
' result_entry = {'
' "step": %d,'
' "status": response.status_code if "response" in locals() else None,'
' "method": "%s",'
' "path": "%s",'
' "elapsed_time": elapsed_time,'
' "request": request_details,'
' "response": response_details,'
' "error": error_details'
' }'
' self.results.append(result_entry)'
''
' def print_summary(self):'
' print("\\n" + "="*60)'
' print("EXECUTION SUMMARY")'
' print("="*60)'
' for r in self.results:'
' print(f"✓ Step {r[\'step\']}: {r[\'method\']} {r[\'path\']} - {r[\'status\']} ({r[\'elapsed_time\']:.3f}s)")'
' print("="*60)'
''
' def print_detailed_report(self):'
' """Print detailed execution report with metrics"""'
' print("\\n" + "="*80)'
' print("DETAILED EXECUTION REPORT")'
' print("="*80)'
' '
' total_time = 0'
' successful_steps = 0'
' failed_steps = 0'
' '
' for r in self.results:'
' print(f"\\n--- Step {r[\'step\']}: {r[\'method\']} {r[\'path\']} ---")'
' print(f" Status: {r[\'status\']}")'
' print(f" Elapsed Time: {r[\'elapsed_time\']:.3f}s")'
' '
' if r[\'error\'] is not None:'
' print(f" Error: {r[\'error\']}")'
' failed_steps += 1'
' else:'
' successful_steps += 1'
' '
' # Request details'
' req = r[\'request\']'
' if req[\'payload\'] is not None:'
' print(f" Request Payload: {req[\'payload\']}")'
' '
' # Response details'
' resp = r[\'response\']'
' if resp[\'headers\'] is not None:'
' content_type = resp[\'headers\'].get(\'Content-Type\', \'Unknown\')'
' print(f" Content-Type: {content_type}")'
' '
' total_time += r[\'elapsed_time\']'
' '
' print("\\n" + "-"*80)'
' print("SUMMARY STATISTICS")'
' print("-"*80)'
' print(f" Total Steps: {len(self.results)}")'
' print(f" Successful: {successful_steps}")'
' print(f" Failed: {failed_steps}")'
' print(f" Total Execution Time: {total_time:.3f}s")'
' if len(self.results) > 0:'
' avg_time = total_time / len(self.results)'
' print(f" Average Time per Step: {avg_time:.3f}s")'
' print("="*80)'
''
'def main():'
f' BASE_URL = "{base_url} "'
f' AUTH_HEADERS = {json.dumps(auth_headers)} '
' executor = APIFlowExecutor(BASE_URL, AUTH_HEADERS)'
' success = executor.execute_flow()'
' executor.print_summary()'
' # Check if DETAILED_REPORT environment variable is set'
' import os'
' if os.environ.get("DETAILED_REPORT", "").lower() == "true":'
' executor.print_detailed_report()'
' sys.exit(0 if success else 1)'
''
'if __name__ == "__main__":'
' main()'
return
'\n'
'script'
'attempts'
print
f"✗ Exit code: {result.returncode} "
if
'400'
in
and
'missing required field'
in
r"field '(\w+)'"
if
1
'payload = {'
f'payload = {{"{field} ": "test_value", '
print
f"Applied fix: Added missing field '{field} '"
continue
if
'422'
in
'"quantity": 0'
'"quantity": 1'
'"age": 0'
'"age": 18'
print
"Applied fix: Adjusted values to meet constraints"
continue
break
except
print
"✗ Script execution timed out"
break
except
as
print
f"✗ Execution error: {e} "
break
finally
if
return
'success'
False
'script'
'attempts'
print
f"Attempts required: {final_result['attempts' ]} "
print
"\nFinal Script:"
print
'script'
else
print
"\n✗ Failed to generate working script"
print
"Manual intervention required"