Skip to main content
Glama

MockLoop MCP Server

Official
by MockLoop
proxy-validation-example.pyโ€ข13.4 kB
#!/usr/bin/env python3 """ Proxy Validation Example This example demonstrates how to validate mock responses against a live API using the proxy mode functionality. It shows how to switch from mock to proxy mode and compare responses for consistency. """ import asyncio import json import os from pathlib import Path # MockLoop MCP imports from mockloop_mcp.mcp_tools import create_mcp_plugin, execute_test_plan from mockloop_mcp.proxy.config import ProxyConfig, AuthConfig, AuthType async def main(): """Demonstrate proxy validation against a live API.""" print("๐Ÿ”„ Proxy Validation Example - Mock vs Live API Testing") print("=" * 60) # Define API specification for a public API (JSONPlaceholder) api_spec = { "openapi": "3.0.0", "info": { "title": "JSONPlaceholder API", "version": "1.0.0", "description": "A fake online REST API for testing and prototyping", }, "servers": [ {"url": "https://jsonplaceholder.typicode.com", "description": "Live API"} ], "paths": { "/posts": { "get": { "summary": "Get all posts", "description": "Retrieve all posts from the API", "responses": { "200": { "description": "List of posts", "content": { "application/json": { "example": [ { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", } ] } }, } }, } }, "/posts/{id}": { "get": { "summary": "Get post by ID", "description": "Retrieve a specific post by its ID", "parameters": [ { "name": "id", "in": "path", "required": True, "schema": {"type": "integer"}, "description": "Post ID", } ], "responses": { "200": { "description": "Post details", "content": { "application/json": { "example": { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", } } }, } }, } }, "/users": { "get": { "summary": "Get all users", "description": "Retrieve all users from the API", "responses": { "200": { "description": "List of users", "content": { "application/json": { "example": [ { "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "Sincere@april.biz", "address": { "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", }, } ] } }, } }, } }, }, } # Step 1: Create plugin in mock mode first print("๐Ÿ“ Step 1: Creating MCP plugin in mock mode...") try: mock_plugin = await create_mcp_plugin( spec_url_or_path=json.dumps(api_spec), mode="mock", plugin_name="jsonplaceholder_mock", target_url=None, auth_config=None, proxy_config=None, ) print("โœ… Mock plugin created successfully!") print(f" Plugin ID: {mock_plugin.get('plugin_id', 'N/A')}") print(f" Mode: {mock_plugin.get('mode', 'N/A')}") except Exception as e: print(f"โŒ Failed to create mock plugin: {e}") return # Step 2: Test with mock responses print("\n๐Ÿงช Step 2: Testing with mock responses...") try: mock_results = await execute_test_plan( openapi_spec=api_spec, server_url="http://localhost:8000", test_focus="basic", mode="mock", validation_mode="strict", auto_generate_scenarios=True, execute_immediately=True, ) print("โœ… Mock tests completed!") print(f" Tests run: {mock_results.get('total_tests', 0)}") print(f" Passed: {mock_results.get('passed', 0)}") print(f" Duration: {mock_results.get('duration', 0):.2f}s") except Exception as e: print(f"โŒ Mock testing failed: {e}") return # Step 3: Create plugin in proxy mode print("\n๐Ÿ”„ Step 3: Creating MCP plugin in proxy mode...") try: # No authentication needed for JSONPlaceholder API proxy_plugin = await create_mcp_plugin( spec_url_or_path=json.dumps(api_spec), mode="proxy", plugin_name="jsonplaceholder_proxy", target_url="https://jsonplaceholder.typicode.com", auth_config=None, # No auth required for this public API proxy_config={ "timeout": 30, "retry_count": 3, "rate_limit": {"requests_per_minute": 60}, }, ) print("โœ… Proxy plugin created successfully!") print(f" Plugin ID: {proxy_plugin.get('plugin_id', 'N/A')}") print(" Target URL: https://jsonplaceholder.typicode.com") except Exception as e: print(f"โŒ Failed to create proxy plugin: {e}") return # Step 4: Test with live API (proxy mode) print("\n๐ŸŒ Step 4: Testing with live API (proxy mode)...") try: proxy_results = await execute_test_plan( openapi_spec=api_spec, server_url="https://jsonplaceholder.typicode.com", test_focus="basic", mode="proxy", validation_mode="soft", # Use soft validation for live API auto_generate_scenarios=True, execute_immediately=True, ) print("โœ… Proxy tests completed!") print(f" Tests run: {proxy_results.get('total_tests', 0)}") print(f" Passed: {proxy_results.get('passed', 0)}") print(f" Duration: {proxy_results.get('duration', 0):.2f}s") except Exception as e: print(f"โŒ Proxy testing failed: {e}") return # Step 5: Compare mock vs proxy responses print("\n๐Ÿ“Š Step 5: Comparing mock vs proxy responses...") try: comparison_results = await execute_test_plan( openapi_spec=api_spec, server_url="http://localhost:8000", # Mock server test_focus="validation", mode="auto", # Auto-detect mode validation_mode="soft", comparison_config={ "ignore_fields": [ "id", # IDs might differ between mock and live "userId", # User IDs might differ "timestamp", # Timestamps will differ "created_at", "updated_at", ], "tolerance": 0.1, # 10% tolerance for numeric values "strict_arrays": False, # Allow array order differences "compare_structure": True, # Focus on structure comparison "compare_types": True, # Ensure data types match }, report_differences=True, auto_generate_scenarios=True, execute_immediately=True, ) print("โœ… Comparison completed!") # Display comparison results differences = comparison_results.get("differences", []) if differences: print(f" Found {len(differences)} differences:") for diff in differences[:3]: # Show first 3 differences endpoint = diff.get("endpoint", "Unknown") diff_type = diff.get("type", "Unknown") print(f" โ€ข {endpoint}: {diff_type}") else: print(" ๐ŸŽ‰ No significant differences found!") # Show validation summary validation_summary = comparison_results.get("validation_summary", {}) if validation_summary: print("\n๐Ÿ“ˆ Validation Summary:") print( f" Structure match: {validation_summary.get('structure_match', 'N/A')}%" ) print( f" Type consistency: {validation_summary.get('type_consistency', 'N/A')}%" ) print( f" Response similarity: {validation_summary.get('similarity_score', 'N/A')}%" ) except Exception as e: print(f"โŒ Comparison failed: {e}") return # Step 6: Demonstrate authentication example (conceptual) print("\n๐Ÿ” Step 6: Authentication example (for APIs requiring auth)...") # Example of how to configure authentication for APIs that require it auth_examples = { "API Key (Header)": { "auth_type": "api_key", "credentials": {"api_key": "your-api-key-here"}, "location": "header", "name": "X-API-Key", }, "API Key (Query)": { "auth_type": "api_key", "credentials": {"api_key": "your-api-key-here"}, "location": "query", "name": "key", }, "Bearer Token": { "auth_type": "bearer_token", "credentials": {"token": "your-bearer-token-here"}, }, "Basic Auth": { "auth_type": "basic_auth", "credentials": {"username": "your-username", "password": "your-password"}, }, } print("๐Ÿ“ Authentication configuration examples:") for auth_name, config in auth_examples.items(): print(f" โ€ข {auth_name}: {config['auth_type']}") print("\n๐Ÿ’ก To use authentication, set the API_KEY environment variable:") print(" export API_KEY=your-actual-api-key") print(" python proxy-validation-example.py") # Step 7: Performance comparison print("\nโšก Step 7: Performance comparison...") mock_duration = mock_results.get("duration", 0) proxy_duration = proxy_results.get("duration", 0) if mock_duration > 0 and proxy_duration > 0: speed_ratio = proxy_duration / mock_duration print(f" Mock tests: {mock_duration:.2f}s") print(f" Proxy tests: {proxy_duration:.2f}s") print(f" Proxy is {speed_ratio:.1f}x slower than mock (expected)") if speed_ratio > 10: print( " ๐Ÿ’ก Consider using mock mode for development and proxy for validation" ) elif speed_ratio < 3: print(" ๐Ÿš€ Live API is quite fast - suitable for regular testing") print("\n๐ŸŽฏ Key Benefits of Proxy Validation:") print(" โ€ข Verify mock responses match real API behavior") print(" โ€ข Catch API changes early in development") print(" โ€ข Validate authentication and authorization flows") print(" โ€ข Test with real data and edge cases") print(" โ€ข Ensure mock accuracy for reliable development") print("\nโœจ Next Steps:") print(" 1. Run hybrid-workflow-example.py for mixed testing") print(" 2. Try authentication-examples.py for auth scenarios") print(" 3. Set up CI/CD pipeline for automated validation") if __name__ == "__main__": asyncio.run(main())

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MockLoop/mockloop-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server