"""APIClient - Agent — Code snippet generators.""" import json from urllib.parse import urlencode from app.models import HttpRequest def _qs(req: HttpRequest) -> str: if not req.params: return req.url sep = "&" if "?" in req.url else "?" return req.url + sep + urlencode(req.params) def to_curl(req: HttpRequest) -> str: parts = [f"curl -X {req.method}"] parts.append(f' "{_qs(req)}"') for k, v in req.headers.items(): parts.append(f" -H '{k}: {v}'") if req.body: escaped = req.body.replace("'", r"'\''") parts.append(f" -d '{escaped}'") if not req.ssl_verify: parts.append(" --insecure") return " \\\n".join(parts) def to_python_requests(req: HttpRequest) -> str: headers = dict(req.headers) if req.body and "Content-Type" not in headers: headers["Content-Type"] = "application/json" lines = ["import requests", ""] lines.append(f'url = "{req.url}"') if headers: lines.append(f"headers = {json.dumps(headers, indent=4)}") if req.params: lines.append(f"params = {json.dumps(req.params, indent=4)}") lines.append("") call_args = ["url"] if headers: call_args.append("headers=headers") if req.params: call_args.append("params=params") if req.body: lines.append(f"payload = {json.dumps(req.body)}") call_args.append("data=payload") if not req.ssl_verify: call_args.append("verify=False") lines.append(f"response = requests.{req.method.lower()}({', '.join(call_args)})") lines.append("") lines.append("print(response.status_code)") lines.append("print(response.json())") return "\n".join(lines) def to_python_httpx(req: HttpRequest) -> str: headers = dict(req.headers) lines = ["import httpx", ""] lines.append(f'url = "{req.url}"') if headers: lines.append(f"headers = {json.dumps(headers, indent=4)}") if req.params: lines.append(f"params = {json.dumps(req.params, indent=4)}") lines.append("") call_args = ["url"] if headers: call_args.append("headers=headers") if req.params: call_args.append("params=params") if req.body: lines.append(f"payload = {json.dumps(req.body)}") call_args.append("content=payload.encode()") if not req.ssl_verify: call_args.append("verify=False") lines.append("with httpx.Client() as client:") lines.append(f" response = client.{req.method.lower()}({', '.join(call_args)})") lines.append(" print(response.status_code)") lines.append(" print(response.json())") return "\n".join(lines) def to_javascript_fetch(req: HttpRequest) -> str: options: dict = {"method": req.method} if req.headers: options["headers"] = req.headers if req.body: options["body"] = req.body lines = [ f'const response = await fetch("{_qs(req)}", {json.dumps(options, indent=2)});', "", "const data = await response.json();", "console.log(response.status, data);", ] return "\n".join(lines) def to_javascript_axios(req: HttpRequest) -> str: config: dict = {} if req.headers: config["headers"] = req.headers if req.params: config["params"] = req.params if req.body: config["data"] = req.body lines = ["const axios = require('axios');", ""] if config: lines.append(f"const config = {json.dumps(config, indent=2)};") lines.append("") lines.append(f'const response = await axios.{req.method.lower()}("{req.url}", config);') else: lines.append(f'const response = await axios.{req.method.lower()}("{req.url}");') lines.append("console.log(response.status, response.data);") return "\n".join(lines) def to_ruby(req: HttpRequest) -> str: lines = [ "require 'net/http'", "require 'uri'", "require 'json'", "", f'uri = URI.parse("{_qs(req)}")', f"http = Net::HTTP.new(uri.host, uri.port)", "http.use_ssl = uri.scheme == 'https'", ] if not req.ssl_verify: lines.append("http.verify_mode = OpenSSL::SSL::VERIFY_NONE") lines.append("") klass_map = { "GET": "Net::HTTP::Get", "POST": "Net::HTTP::Post", "PUT": "Net::HTTP::Put", "PATCH": "Net::HTTP::Patch", "DELETE": "Net::HTTP::Delete", "HEAD": "Net::HTTP::Head", } klass = klass_map.get(req.method, "Net::HTTP::Get") lines.append(f"request = {klass}.new(uri.request_uri)") for k, v in req.headers.items(): lines.append(f'request["{k}"] = "{v}"') if req.body: lines.append(f"request.body = {json.dumps(req.body)}") lines += [ "", "response = http.request(request)", "puts response.code", "puts response.body", ] return "\n".join(lines) GENERATORS = { "curl": to_curl, "Python (requests)": to_python_requests, "Python (httpx)": to_python_httpx, "JavaScript (fetch)": to_javascript_fetch, "JavaScript (axios)": to_javascript_axios, "Ruby (Net::HTTP)": to_ruby, }