Skip to main content

api-client-tester-waruna834

Complete API testing tool for REST, GraphQL, and WebSocket with collections support - lightweight Postman alternative

Jump to install

Source facts

Repository
reason-machines/devtools-skills
Last source activity
July 1, 2026 at 22:03
Detected SKILL.md language
English
Stars
4
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
api-client-tester-waruna834
description
Complete API testing tool for REST, GraphQL, and WebSocket with collections support - lightweight Postman alternative
triggers
["test REST API endpoints","send GraphQL queries","test WebSocket connections","manage API request collections","authenticate API requests","export API test collections","inspect HTTP responses","build API testing suite"]
# API Client & Tester > Skill by [ara.so](https://ara.so) — Devtools Skills collection. ## Overview API Client & Tester is a complete API testing tool for REST, GraphQL, and WebSocket protocols. It provides a lightweight alternative to Postman with support for multiple HTTP methods, authentication strategies, request collections, and import/export functionality. ## Installation ### From Source ```bash git clone https://github.com/waruna834/API_Client___Tester.git cd API_Client___Tester pip install -r requirements.txt python main.py ``` ### Requirements - Python 3.7+ - Windows 10/11 (64-bit) - Dependencies managed via `requirements.txt` ## Core Components ### HTTP Client The tool supports standard HTTP methods with authentication: ```python import requests import json class APIClient: def __init__(self, base_url=""): self.base_url = base_url self.headers = {} self.auth = None def set_auth(self, auth_type, credentials): """Set authentication for requests""" if auth_type == "basic": from requests.auth import HTTPBasicAuth self.auth = HTTPBasicAuth(credentials['username'], credentials['password']) elif auth_type == "bearer": self.headers['Authorization'] = f"Bearer {credentials['token']}" elif auth_type == "api_key": self.headers[credentials['key_name']] = credentials['key_value'] def request(self, method, endpoint, **kwargs): """Send HTTP request""" url = f"{self.base_url}{endpoint}" kwargs.setdefault('headers', {}).update(self.headers) if self.auth: kwargs['auth'] = self.auth response = requests.request(method, url, **kwargs) return { 'status_code': response.status_code, 'headers': dict(response.headers), 'body': response.text, 'json': response.json() if response.headers.get('content-type', '').startswith('application/json') else None } # Usage client = APIClient(base_url="https://api.example.com") client.set_auth("bearer", {"token": os.getenv("API_TOKEN")}) response = client.request("GET", "/users", params={"page": 1}) print(f"Status: {response['status_code']}") print(f"Data: {response['json']}") ``` ### GraphQL Support ```python class GraphQLClient: def __init__(self, endpoint, headers=None): self.endpoint = endpoint self.headers = headers or {} def query(self, query, variables=None): """Execute GraphQL query""" payload = { 'query': query, 'variables': variables or {} } response = requests.post( self.endpoint, json=payload, headers=self.headers ) result = response.json() if 'errors' in result: raise Exception(f"GraphQL errors: {result['errors']}") return result['data'] def mutation(self, mutation, variables=None): """Execute GraphQL mutation""" return self.query(mutation, variables) # Usage gql_client = GraphQLClient( endpoint="https://api.example.com/graphql", headers={"Authorization": f"Bearer {os.getenv('GRAPHQL_TOKEN')}"} ) query = """ query GetUser($id: ID!) { user(id: $id) { id name email } } """ result = gql_client.query(query, variables={"id": "123"}) print(result['user']) ``` ### WebSocket Testing ```python import websocket import json import threading class WebSocketClient: def __init__(self, url): self.url = url self.ws = None self.messages = [] def on_message(self, ws, message): """Handle incoming message""" self.messages.append({ 'timestamp': datetime.now().isoformat(), 'data': message }) print(f"Received: {message}") def on_error(self, ws, error): """Handle error""" print(f"Error: {error}") def on_close(self, ws, close_status_code, close_msg): """Handle connection close""" print(f"Connection closed: {close_status_code} - {close_msg}") def on_open(self, ws): """Handle connection open""" print("WebSocket connection opened") def connect(self): """Establish WebSocket connection""" self.ws = websocket.WebSocketApp( self.url, on_open=self.on_open, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close ) ws_thread = threading.Thread(target=self.ws.run_forever) ws_thread.daemon = True ws_thread.start() def send(self, data): """Send message""" if self.ws: self.ws.send(json.dumps(data) if isinstance(data, dict) else data) def close(self): """Close connection""" if self.ws: self.ws.close() # Usage ws_client = WebSocketClient("wss://echo.websocket.org") ws_client.connect() # Send message ws_client.send({"type": "ping", "timestamp": time.time()}) # Wait for responses time.sleep(2) # Close connection ws_client.close() ``` ### Collections Management ```python import json import os class CollectionManager: def __init__(self, collections_dir="./collections"): self.collections_dir = collections_dir os.makedirs(collections_dir, exist_ok=True) def create_collection(self, name, requests=None): """Create a new collection""" collection = { 'name': name, 'created_at': datetime.now().isoformat(), 'requests': requests or [] } return collection def add_request(self, collection, request_data): """Add request to collection""" request = { 'id': str(uuid.uuid4()), 'name': request_data.get('name', 'Untitled'), 'method': request_data['method'], 'url': request_data['url'], 'headers': request_data.get('headers', {}), 'body': request_data.get('body', ''), 'auth': request_data.get('auth', None), 'params': request_data.get('params', {}) } collection['requests'].append(request) return collection def save_collection(self, collection): """Save collection to file""" filename = f"{collection['name'].replace(' ', '_')}.json" filepath = os.path.join(self.collections_dir, filename) with open(filepath, 'w') as f: json.dump(collection, f, indent=2) return filepath def load_collection(self, name): """Load collection from file""" filename = f"{name.replace(' ', '_')}.json" filepath = os.path.join(self.collections_dir, filename) with open(filepath, 'r') as f: return json.load(f) def export_collection(self, collection, output_path): """Export collection to JSON""" with open(output_path, 'w') as f: json.dump(collection, f, indent=2) def import_collection(self, input_path): """Import collection from JSON""" with open(input_path, 'r') as f: collection = json.load(f) self.save_collection(collection) return collection # Usage manager = CollectionManager() # Create collection collection = manager.create_collection("User API Tests") # Add requests collection = manager.add_request(collection, { 'name': 'Get All Users', 'method': 'GET', 'url': 'https://api.example.com/users', 'auth': {'type': 'bearer', 'token': '${API_TOKEN}'} }) collection = manager.add_request(collection, { 'name': 'Create User', 'method': 'POST', 'url': 'https://api.example.com/users', 'headers': {'Content-Type': 'application/json'}, 'body': json.dumps({'name': 'John Doe', 'email': 'john@example.com'}), 'auth': {'type': 'bearer', 'token': '${API_TOKEN}'} }) # Save collection manager.save_collection(collection) # Export for sharing manager.export_collection(collection, "./exports/user_api_tests.json") ``` ## Authentication Patterns ### Basic Authentication ```python client = APIClient(base_url="https://api.example.com") client.set_auth("basic", { 'username': os.getenv('API_USERNAME'), 'password': os.getenv('API_PASSWORD') }) response = client.request("GET", "/protected") ``` ### Bearer Token ```python client = APIClient(base_url="https://api.example.com") client.set_auth("bearer", { 'token': os.getenv('BEARER_TOKEN') }) response = client.request("GET", "/me") ``` ### API Key (Header) ```python client = APIClient(base_url="https://api.example.com") client.set_auth("api_key", { 'key_name': 'X-API-Key', 'key_value': os.getenv('API_KEY') }) response = client.request("GET", "/data") ``` ### OAuth2 Flow ```python import requests from urllib.parse import urlencode class OAuth2Client: def __init__(self, client_id, client_secret, auth_url, token_url): self.client_id = client_id self.client_secret = client_secret self.auth_url = auth_url self.token_url = token_url self.access_token = None def get_authorization_url(self, redirect_uri, scope=None): """Generate authorization URL""" params = { 'client_id': self.client_id, 'redirect_uri': redirect_uri, 'response_type': 'code' } if scope: params['scope'] = scope return f"{self.auth_url}?{urlencode(params)}" def exchange_code_for_token(self, code, redirect_uri): """Exchange authorization code for access token""" data = { 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': self.client_id, 'client_secret': self.client_secret } response = requests.post(self.token_url, data=data) token_data = response.json() self.access_token = token_data['access_token'] return token_data # Usage oauth = OAuth2Client( client_id=os.getenv('OAUTH_CLIENT_ID'),
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub