Update documentation.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — Conversational AI co-pilot core."""
|
||||
"""APIClient - Agent - Conversational AI co-pilot core."""
|
||||
import json
|
||||
import re
|
||||
import httpx
|
||||
@@ -11,9 +11,9 @@ You are APIClient - Agent, an expert AI API testing co-pilot embedded in the API
|
||||
|
||||
Your responsibilities:
|
||||
• Help craft and debug HTTP requests (REST, JSON-API, GraphQL, Odoo APIs)
|
||||
• Analyze HTTP responses — status codes, headers, body structure, errors
|
||||
• Analyze HTTP responses - status codes, headers, body structure, errors
|
||||
• Specialize in the EKIKA Odoo API Framework:
|
||||
- JSON-API (Content-Type: application/vnd.api+json) — body format: {"data": {"type": model, "attributes": {...}}}
|
||||
- JSON-API (Content-Type: application/vnd.api+json) - body format: {"data": {"type": model, "attributes": {...}}}
|
||||
- REST JSON (Content-Type: application/json)
|
||||
- GraphQL (POST with {"query": "..."} body)
|
||||
- Auth: x-api-key header, Basic Auth, OAuth2 Bearer, JWT Bearer
|
||||
@@ -45,7 +45,7 @@ pm.test('Has data', lambda: expect(pm.response.json()).to_have_key('data'))
|
||||
```
|
||||
|
||||
Rules:
|
||||
- Be concise and actionable — explain WHY, not just WHAT
|
||||
- Be concise and actionable - explain WHY, not just WHAT
|
||||
- If you add apply blocks, briefly explain what each block does
|
||||
- For JSON-API responses: data is in response.data, errors in response.errors
|
||||
- For SSL cert errors: tell user to uncheck SSL verification in the Settings tab
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — Claude AI integration."""
|
||||
"""APIClient - Agent - Claude AI integration."""
|
||||
import json
|
||||
import re
|
||||
import httpx
|
||||
@@ -28,7 +28,7 @@ You are an expert API documentation analyzer for APIClient - Agent.
|
||||
Given API documentation (which may be a spec, a web page, framework docs, or raw text),
|
||||
extract or infer all useful API endpoints and return structured JSON.
|
||||
|
||||
Return ONLY valid JSON — no markdown, no commentary, just the JSON object.
|
||||
Return ONLY valid JSON - no markdown, no commentary, just the JSON object.
|
||||
|
||||
Schema:
|
||||
{
|
||||
@@ -74,7 +74,7 @@ Rules:
|
||||
- If it is a GRAPHQL API, generate a POST /graphql endpoint with example query body
|
||||
- If auth options are shown (API key, OAuth, Basic), include ALL variants as separate
|
||||
environment variables so the user can choose
|
||||
- Keep paths clean — strip trailing slashes, normalise to lowercase
|
||||
- Keep paths clean - strip trailing slashes, normalise to lowercase
|
||||
"""
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ def fetch_url_content(url: str) -> str:
|
||||
ct = resp.headers.get("content-type", "")
|
||||
text = resp.text
|
||||
|
||||
# If HTML page — strip tags for cleaner AI input
|
||||
# If HTML page - strip tags for cleaner AI input
|
||||
if "html" in ct and not _looks_like_spec(text):
|
||||
text = _strip_html(text)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — Code snippet generators."""
|
||||
"""APIClient - Agent - Code snippet generators."""
|
||||
import json
|
||||
from urllib.parse import urlencode
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""EKIKA Odoo API Framework — Direct collection generator.
|
||||
"""EKIKA Odoo API Framework - Direct collection generator.
|
||||
|
||||
Generates complete Postman-style collections from the EKIKA api_framework module
|
||||
without requiring any AI API calls. All URL patterns, body formats, auth headers,
|
||||
@@ -87,7 +87,7 @@ def _env_vars(instance_url: str, auth_type: str, extra: dict = None) -> dict:
|
||||
|
||||
|
||||
def _clean_endpoint(endpoint: str) -> str:
|
||||
"""Normalise endpoint slug — ensure leading slash, strip trailing slash."""
|
||||
"""Normalise endpoint slug - ensure leading slash, strip trailing slash."""
|
||||
ep = endpoint.strip().strip("/")
|
||||
return f"/{ep}" if ep else "/api"
|
||||
|
||||
@@ -281,7 +281,7 @@ def _build_jsonapi_endpoints(base_ep: str, model: str, headers: dict,
|
||||
|
||||
if "Get Fields" in operations:
|
||||
eps.append({
|
||||
"name": f"Get Fields — {model}",
|
||||
"name": f"Get Fields - {model}",
|
||||
"method": "GET",
|
||||
"path": f"{ep_path}/fields_get",
|
||||
"headers": {**headers, "Accept": ct},
|
||||
@@ -295,7 +295,7 @@ def _build_jsonapi_endpoints(base_ep: str, model: str, headers: dict,
|
||||
|
||||
if "Check Access Rights" in operations:
|
||||
eps.append({
|
||||
"name": f"Check Access — {model}",
|
||||
"name": f"Check Access - {model}",
|
||||
"method": "GET",
|
||||
"path": f"{ep_path}/check_access_rights",
|
||||
"headers": {**headers, "Accept": ct},
|
||||
@@ -405,7 +405,7 @@ def _build_restjson_endpoints(base_ep: str, model: str, headers: dict,
|
||||
|
||||
if "Get Fields" in operations:
|
||||
eps.append({
|
||||
"name": f"Get Fields — {model}",
|
||||
"name": f"Get Fields - {model}",
|
||||
"method": "GET",
|
||||
"path": f"{ep_path}/fields_get",
|
||||
"headers": {**headers},
|
||||
@@ -442,7 +442,7 @@ def _build_graphql_endpoints(base_ep: str, model: str, headers: dict,
|
||||
f"}}"
|
||||
)
|
||||
eps.append({
|
||||
"name": f"GraphQL — List {model}",
|
||||
"name": f"GraphQL - List {model}",
|
||||
"method": "POST",
|
||||
"path": path,
|
||||
"headers": {**headers, "Content-Type": ct},
|
||||
@@ -465,7 +465,7 @@ def _build_graphql_endpoints(base_ep: str, model: str, headers: dict,
|
||||
f"}}"
|
||||
)
|
||||
eps.append({
|
||||
"name": f"GraphQL — Get {model} by ID",
|
||||
"name": f"GraphQL - Get {model} by ID",
|
||||
"method": "POST",
|
||||
"path": path,
|
||||
"headers": {**headers, "Content-Type": ct},
|
||||
@@ -491,7 +491,7 @@ def _build_graphql_endpoints(base_ep: str, model: str, headers: dict,
|
||||
f"}}"
|
||||
)
|
||||
eps.append({
|
||||
"name": f"GraphQL — Create {model}",
|
||||
"name": f"GraphQL - Create {model}",
|
||||
"method": "POST",
|
||||
"path": path,
|
||||
"headers": {**headers, "Content-Type": ct},
|
||||
@@ -518,7 +518,7 @@ def _build_graphql_endpoints(base_ep: str, model: str, headers: dict,
|
||||
f"}}"
|
||||
)
|
||||
eps.append({
|
||||
"name": f"GraphQL — Update {model}",
|
||||
"name": f"GraphQL - Update {model}",
|
||||
"method": "POST",
|
||||
"path": path,
|
||||
"headers": {**headers, "Content-Type": ct},
|
||||
@@ -539,7 +539,7 @@ def _build_graphql_endpoints(base_ep: str, model: str, headers: dict,
|
||||
f"}}"
|
||||
)
|
||||
eps.append({
|
||||
"name": f"GraphQL — Delete {model}",
|
||||
"name": f"GraphQL - Delete {model}",
|
||||
"method": "POST",
|
||||
"path": path,
|
||||
"headers": {**headers, "Content-Type": ct},
|
||||
@@ -587,7 +587,7 @@ def generate_collection(
|
||||
all_endpoints += _build_restjson_endpoints(base_ep, model, headers, operations)
|
||||
elif api_kind == "GraphQL":
|
||||
all_endpoints += _build_graphql_endpoints(base_ep, model, headers, operations)
|
||||
else: # Custom REST JSON — same as REST JSON
|
||||
else: # Custom REST JSON - same as REST JSON
|
||||
all_endpoints += _build_restjson_endpoints(base_ep, model, headers, operations)
|
||||
|
||||
# Build URLs using {{base_url}} variable
|
||||
@@ -595,7 +595,7 @@ def generate_collection(
|
||||
if not ep["path"].startswith("http"):
|
||||
ep["url"] = f"{{{{base_url}}}}{ep['path']}"
|
||||
|
||||
name = collection_name or f"EKIKA Odoo — {api_kind} — {', '.join(models[:3])}"
|
||||
name = collection_name or f"EKIKA Odoo - {api_kind} - {', '.join(models[:3])}"
|
||||
|
||||
return {
|
||||
"collection_name": name,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — HTTP client engine."""
|
||||
"""APIClient - Agent - HTTP client engine."""
|
||||
import re
|
||||
import base64
|
||||
from copy import deepcopy
|
||||
@@ -144,18 +144,18 @@ def send_request(req: HttpRequest, variables: dict = None) -> HttpResponse:
|
||||
detail = str(e)
|
||||
if "CERTIFICATE_VERIFY_FAILED" in detail or "certificate" in detail.lower() or "SSL" in detail:
|
||||
return HttpResponse(error=(
|
||||
f"SSL certificate error — could not connect to {r.url}\n\n"
|
||||
f"SSL certificate error - could not connect to {r.url}\n\n"
|
||||
f"The server's certificate is not trusted or doesn't match the hostname.\n"
|
||||
f"Tip: disable SSL verification in the request Settings tab."
|
||||
))
|
||||
return HttpResponse(error=f"Connection refused — could not reach {r.url}")
|
||||
return HttpResponse(error=f"Connection refused - could not reach {r.url}")
|
||||
except httpx.ConnectTimeout:
|
||||
return HttpResponse(error=f"Connection timed out after {req.timeout}s")
|
||||
except httpx.ReadTimeout:
|
||||
return HttpResponse(error=f"Read timed out — server took too long to respond")
|
||||
return HttpResponse(error=f"Read timed out - server took too long to respond")
|
||||
except httpx.SSLError as e:
|
||||
return HttpResponse(error=f"SSL error: {e}. Disable SSL verification if using a self-signed cert.")
|
||||
except httpx.TooManyRedirects:
|
||||
return HttpResponse(error="Too many redirects — possible redirect loop")
|
||||
return HttpResponse(error="Too many redirects - possible redirect loop")
|
||||
except Exception as e:
|
||||
return HttpResponse(error=str(e))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — Lightweight HTTP mock server."""
|
||||
"""APIClient - Agent - Lightweight HTTP mock server."""
|
||||
import threading
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — OpenAPI / Swagger spec parser.
|
||||
"""APIClient - Agent - OpenAPI / Swagger spec parser.
|
||||
|
||||
Parses OpenAPI 3.x and Swagger 2.0 specs (JSON or YAML) directly,
|
||||
without needing AI tokens.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""APIClient - Agent — Storage layer (SQLite)."""
|
||||
"""APIClient - Agent - Storage layer (SQLite)."""
|
||||
import json
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
Reference in New Issue
Block a user