Files
APIClient-Agent/README.md
2026-03-28 18:01:49 +05:30

14 KiB

APIClient - Agent

AI-first API testing desktop client - built with Python + PyQt6. Specialised for the EKIKA Odoo API Framework, but works with any REST, GraphQL, or WebSocket API.

alt text


Features

Core API Testing

  • Multi-tab request editor - work on multiple requests simultaneously, drag to reorder
  • All HTTP methods - GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • Smart params & headers table - per-row enable/disable checkboxes, 36 px comfortable rows, auto-expanding blank row
  • Body editor - raw JSON/XML/text with syntax highlighting, Format JSON button, application/vnd.api+json support
  • Auth panel - Bearer Token, Basic Auth, API Key (header or query)
  • Pre-request scripts - Python executed before each request; access pm.environment.get/set
  • Test scripts - assertions auto-run after every response; pm.test(...) / expect(...) DSL
  • Response viewer - syntax-highlighted body, headers table, test results, search, copy, save
  • WebSocket client - connect, send, receive, log messages
  • Mock server - local HTTP mock with configurable routes

Collections & Environments

  • Collections sidebar - import/export Postman Collection v2.1 JSON, cURL
  • Environment variables - {{base_url}}, {{api_key}}, etc. resolved at send time; per-environment values
  • Collection runner - run all requests in a collection, view pass/fail results
  • History - every sent request automatically saved

AI Co-pilot (Claude-powered)

  • Persistent AI chat sidebar - toggle with the ✦ AI button or Ctrl+Shift+A
  • Full context awareness - AI sees your current request (method, URL, headers, body, params, test scripts) and the last response (status, body, errors); secrets are automatically redacted
  • Streaming responses - tokens stream in real time
  • One-click Apply - AI suggestions come with Apply Body, Apply Params, Apply Headers, Apply Test Script buttons that set the values directly in the request editor
  • Multi-turn conversation - full history maintained per session; Clear to reset
  • Quick actions - Analyze, Fix Error, Gen Body, Write Tests, Auth Help, Explain Response
  • EKIKA Odoo collection generator - generate complete collections for JSON-API, REST JSON, GraphQL, and Custom REST JSON without spending AI tokens; supports all auth types

EKIKA Odoo API Framework specialisation

  • Generates full CRUD + Execute / Export / Report / Fields / Access-Rights endpoints per model
  • Auth types: API Key (x-api-key), Basic Auth, User Credentials, OAuth2, JWT, Public
  • Correct JSON-API body format out of the box: {"data": {"type": "sale.order", "attributes": {...}}}
  • Automatic environment creation with base_url, api_key, tokens

Installation

Requirements

  • Python 3.11+
  • Linux, macOS, or Windows
git clone https://git.ekika.co/EKIKA.co/APIClient-Agent.git
cd APIClient-Agent

python -m venv venv
source venv/bin/activate          # Windows: venv\Scripts\activate

pip install -r requirements.txt
python main.py

requirements.txt

PyQt6>=6.6.0
httpx>=0.27.0
websockets>=12.0
anthropic>=0.25.0
pyyaml>=6.0
pyinstaller>=6.0.0

Quick Start

1 - Send your first request

  1. Launch the app: python main.py
  2. Type a URL in the bar, e.g. https://jsonplaceholder.typicode.com/todos/1
  3. Press Send (or Ctrl+Enter)
  4. See the JSON response with syntax highlighting in the bottom panel

2 - Use environment variables

  1. Click ManageNew Environment → name it My API
  2. Add variables:
    base_url  =  https://api.example.com
    api_key   =  your-secret-key
    
  3. Select the environment in the top bar
  4. In the URL bar, type {{base_url}}/v1/users
  5. In Headers, add Authorization: Bearer {{api_key}}
  6. Variables are resolved automatically at send time

3 - Import a collection

From Postman export:

  1. File → Import…
  2. Paste Postman Collection v2.1 JSON or drop the file

From cURL:

File → Import… → paste:
curl -X POST https://api.example.com/v1/orders \
  -H "Content-Type: application/json" \
  -d '{"product_id": 42, "qty": 1}'

From OpenAPI spec:

  1. Tools → AI Assistant → Import from Docs
  2. Paste the OpenAPI JSON/YAML URL - parsed instantly, no AI tokens used

EKIKA Odoo API Framework - Complete Example

Generate a collection in 30 seconds

  1. Open Tools → AI Assistant (or click ✦ AIAI Assistant in the menu)

  2. Select the EKIKA Odoo API tab

  3. Fill in:

    Field Example
    Instance URL https://mycompany.odoo.com
    API Endpoint /user-jsonapi-apikey
    API Kind JSON-API
    Auth Type API Key
    API Key EwKCljvZoHXsaGlxxvCHt1h4SvWLpuWW
    Models sale.order, res.partner, account.move
    Operations ✓ List, Get, Create, Update, Delete
  4. Click Generate Collection - preview appears instantly

  5. Click Import Both - collection + environment are saved

This generates the following requests for each model with zero AI tokens:

GET  {{base_url}}/user-jsonapi-apikey/sale.order
GET  {{base_url}}/user-jsonapi-apikey/sale.order/{{id}}
POST {{base_url}}/user-jsonapi-apikey/sale.order
PATCH {{base_url}}/user-jsonapi-apikey/sale.order/{{id}}
DELETE {{base_url}}/user-jsonapi-apikey/sale.order/{{id}}

Sending a JSON-API request

The generated Create sale.order request body:

{
  "data": {
    "type": "sale.order",
    "attributes": {
      "name": "New Order"
    }
  }
}

Headers sent automatically:

x-api-key: EwKCljvZoHXsaGlxxvCHt1h4SvWLpuWW
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

Filtering and pagination (List endpoint)

The List sale.order request includes query params:

page[number] = 1
page[size]   = 10
fields[sale.order] = id,name,display_name,partner_id
sort = -id

To filter by customer, open the AI chat sidebar and ask:

"Add a filter param to get only sale orders for partner ID 7"

AI responds with an apply block you can apply in one click.

GraphQL example

Select API Kind: GraphQL. The generator creates:

List sale.order (GraphQL)

{
  "query": "query {\n  sale_order(\n    filter: \"\"\n    pageSize: 10\n    pageNumber: 1\n  ) {\n    id\n    name\n    display_name\n  }\n}"
}

Create sale.order (GraphQL)

{
  "query": "mutation {\n  create_sale_order(\n    attributes: {\n      name: \"New Record\"\n    }\n  ) {\n    id\n    name\n  }\n}"
}

AI Chat Co-pilot - Example Session

Click ✦ AI in the top bar to open the sidebar. The AI automatically knows what request you have open and the last response.

Debugging a 401 error

You:  I'm getting 401 Unauthorized on all my Odoo API requests.

AI:   A 401 on the EKIKA JSON-API endpoint means the x-api-key header is
      missing, empty, or incorrect.

      Checklist:
      1. Confirm your environment has api_key set (Tools → Environments)
      2. Confirm the request Headers tab includes x-api-key: {{api_key}}
      3. In Odoo, verify the API key is still active under your user's
         API Framework settings

      Here are the correct headers to apply:

      ┌─ apply:headers ──────────────────────────────────┐
      │ x-api-key: {{api_key}}                           │
      │ Accept: application/vnd.api+json                 │
      └──────────────────────────────────────────────────┘
      [ Apply Headers to Request ]

Click Apply Headers to Request - headers are set immediately and the Headers tab opens.

Generating a body for a complex model

You:  Generate a body to create an invoice (account.move) for partner ID 14,
      with one line for product ID 7, quantity 3, price 150.

AI:   Here is a JSON-API compliant body for creating an account.move:

      ┌─ apply:body ─────────────────────────────────────┐
      │ {                                                │
      │   "data": {                                      │
      │     "type": "account.move",                      │
      │     "attributes": {                              │
      │       "move_type": "out_invoice",                │
      │       "partner_id": 14,                          │
      │       "invoice_line_ids": [[0, 0, {              │
      │         "product_id": 7,                         │
      │         "quantity": 3,                           │
      │         "price_unit": 150.0                      │
      │       }]]                                        │
      │     }                                            │
      │   }                                              │
      │ }                                                │
      └──────────────────────────────────────────────────┘
      [ Apply Body to Request ]

Writing test scripts

You:  Write tests to verify a successful JSON-API list response.

AI:   ┌─ apply:test ─────────────────────────────────────┐
      │ pm.test('Status 200', lambda:                    │
      │     pm.response.to_have_status(200))             │
      │ pm.test('Has data array', lambda:                │
      │     expect(pm.response.json()).to_have_key('data'))│
      │ pm.test('Data is list', lambda:                  │
      │     expect(pm.response.json()['data']).to_be_list())│
      │ pm.test('Response time < 2s', lambda:            │
      │     expect(pm.response.response_time).to_be_below(2000))│
      └──────────────────────────────────────────────────┘
      [ Apply Test Script to Request ]

Keyboard Shortcuts

Shortcut Action
Ctrl+Enter Send request
Ctrl+T New tab
Ctrl+W Close tab
Ctrl+S Save to collection
Ctrl+F Search requests
Ctrl+E Manage environments
Ctrl+Shift+A Toggle AI chat sidebar
Ctrl+Shift+F Format JSON body
Escape Cancel in-flight request
Ctrl+Q Quit

Project Structure

APIClient-Agent/
├── main.py                        # Entry point
├── requirements.txt
├── LICENSE
├── app/
│   ├── models.py                  # HttpRequest, HttpResponse, Environment
│   ├── core/
│   │   ├── storage.py             # SQLite persistence (collections, environments, history)
│   │   ├── http_client.py         # httpx-based request engine, variable resolution
│   │   ├── ai_client.py           # Claude API - collection generation from docs
│   │   ├── ai_chat.py             # Claude API - multi-turn conversational co-pilot
│   │   ├── openapi_parser.py      # OpenAPI 3.x / Swagger 2.0 local parser
│   │   ├── ekika_odoo_generator.py# EKIKA Odoo framework collection generator
│   │   ├── test_runner.py         # pm.test / expect assertion engine
│   │   ├── mock_server.py         # Local HTTP mock server
│   │   ├── code_gen.py            # Code generation (curl, Python, JS, etc.)
│   │   ├── exporter.py            # Postman Collection v2.1 export
│   │   └── importer.py            # Postman Collection / cURL import
│   └── ui/
│       ├── main_window.py         # Main window, splitter layout, env bar
│       ├── theme.py               # Central QSS stylesheet engine (dark/light)
│       ├── request_panel.py       # URL bar, params/headers/body/auth/tests editor
│       ├── response_panel.py      # Response viewer with status badge
│       ├── tabs_manager.py        # Multi-tab request manager
│       ├── sidebar.py             # Collections tree sidebar
│       ├── ai_panel.py            # AI Assistant dialog (collection generator)
│       ├── ai_chat_panel.py       # AI chat sidebar (co-pilot)
│       ├── environment_dialog.py  # Environment manager
│       ├── collection_runner.py   # Collection runner
│       ├── websocket_panel.py     # WebSocket client
│       ├── mock_server_panel.py   # Mock server UI
│       ├── import_dialog.py       # Import dialog
│       ├── code_gen_dialog.py     # Code generation dialog
│       ├── search_dialog.py       # Request search
│       └── highlighter.py         # JSON syntax highlighter

Configuration

Settings are stored in an SQLite database at ~/.apiclient_agent/data.db (created automatically).

Anthropic API Key (for AI features)

  1. Get a key at console.anthropic.com
  2. In the app: Tools → AI Assistant → Settings tab
  3. Paste the key and click Save API Key

The key is stored locally in the SQLite database only - never transmitted except to the Anthropic API.


SSL / TLS Notes

Some servers (especially demo/development instances) use self-signed certificates or wildcard certificates that don't match the exact hostname. If you see:

SSL certificate error - could not connect to https://...
Tip: disable SSL verification in the request Settings tab.

Open the Settings tab in the request editor and uncheck Verify SSL certificate.


Building a Standalone Executable

pyinstaller --onefile --windowed \
  --name "APIClient-Agent" \
  --add-data "app:app" \
  main.py

The executable is produced in dist/APIClient-Agent.


Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit your changes: git commit -m "Add my feature"
  4. Push and open a pull request

Please keep UI styling in theme.py using setObjectName() selectors - never inline setStyleSheet() for static colors.


License

MIT License - Copyright (c) 2026 EKIKA.co