420 lines
14 KiB
Python
420 lines
14 KiB
Python
"""Generator de exemple de cod multi-limbaj pentru integrarea cu AutoPass.
|
||
|
||
Modul PUR: fara I/O, fara DB, fara stare globala.
|
||
Folosit de pagina de documentatie a hub-ului de integrare (Etapa 5).
|
||
|
||
Campurile obligatorii din payload-ul JSON sunt derivate dinamic din
|
||
PrezentareIn.model_fields pentru rezistenta la drift de schema.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
|
||
from app.models import PrezentareIn
|
||
|
||
# Placeholder pentru cheia API — niciodata o cheie reala
|
||
_CHEIE_PLACEHOLDER = "rfak_..."
|
||
|
||
|
||
def _campuri_obligatorii() -> list[str]:
|
||
"""Intoarce lista campurilor obligatorii din PrezentareIn (is_required())."""
|
||
return [camp for camp, field in PrezentareIn.model_fields.items() if field.is_required()]
|
||
|
||
|
||
def _payload_prezentari_dict(account_id: int) -> dict:
|
||
"""Construieste un payload JSON exemplu cu toate campurile obligatorii.
|
||
|
||
Campurile cu default (odometru_initial, obs, b64_image, sistem_reparat) sunt
|
||
omise pentru concizie — nu sunt obligatorii.
|
||
|
||
`rar_credentials` NU e inclus: cererea trimite doar cheia API + datele prezentarii,
|
||
iar worker-ul foloseste credentialele RAR salvate pe cont (Meniu cont › Cont). Trimiterea
|
||
lor in payload e optionala (suprascrie creds-urile contului pe acea cerere).
|
||
"""
|
||
# Construim un dict cu toate campurile obligatorii
|
||
campuri = _campuri_obligatorii()
|
||
prezentare: dict = {}
|
||
|
||
# Valori exemplu pentru campuri obligatorii cunoscute
|
||
valori_exemplu: dict = {
|
||
"vin": "WVWZZZ1JZXW000001",
|
||
"nr_inmatriculare": "B123ABC",
|
||
"data_prestatie": "2026-06-22",
|
||
"odometru_final": "150000",
|
||
"prestatii": [{"cod_prestatie": "OE-1"}],
|
||
}
|
||
|
||
for camp in campuri:
|
||
if camp in valori_exemplu:
|
||
prezentare[camp] = valori_exemplu[camp]
|
||
else:
|
||
# Fallback generic pentru campuri neasteptate adaugate ulterior
|
||
prezentare[camp] = f"<{camp}>"
|
||
|
||
return {"prezentari": [prezentare]}
|
||
|
||
|
||
def _payload_json_str(account_id: int, indent: int = 2) -> str:
|
||
"""Payload JSON formatat ca string pentru includere in snippet-uri."""
|
||
return json.dumps(_payload_prezentari_dict(account_id), indent=indent, ensure_ascii=False)
|
||
|
||
|
||
def _payload_json_compact(account_id: int) -> str:
|
||
"""Payload JSON pe o singura linie (fara newline) pentru string literal C#/VFP.
|
||
|
||
Foloseste separators=(',', ':') pentru a elimina spatiile si newline-urile.
|
||
Rezultatul e un JSON valid pe o singura linie, fara newline in interior.
|
||
"""
|
||
return json.dumps(_payload_prezentari_dict(account_id), separators=(",", ":"), ensure_ascii=False)
|
||
|
||
|
||
def _exemplu_cerere_dict() -> dict:
|
||
"""Cerere exemplu completa: ambele forme de prestatie + campuri optionale uzuale."""
|
||
return {
|
||
"prezentari": [
|
||
{
|
||
"vin": "WVWZZZ1JZXW000001",
|
||
"nr_inmatriculare": "B123ABC",
|
||
"data_prestatie": "2026-06-22",
|
||
"odometru_final": "150000",
|
||
"odometru_initial": "149500",
|
||
"prestatii": [
|
||
{"cod_prestatie": "OE-1"},
|
||
{"cod_op_service": "SF01", "denumire": "Schimb filtru ulei"},
|
||
],
|
||
}
|
||
],
|
||
"rar_env": "test",
|
||
}
|
||
|
||
|
||
def _exemplu_raspuns_dict() -> dict:
|
||
"""Raspuns exemplu in forma implicita `minim`: 6 chei fixe per rezultat."""
|
||
return {
|
||
"results": [
|
||
{
|
||
"index": 0,
|
||
"submission_id": 123,
|
||
"vehicul": "B123ABC",
|
||
"status": "queued",
|
||
"motiv": None,
|
||
"id_prezentare": None,
|
||
}
|
||
]
|
||
}
|
||
|
||
|
||
def exemplu_json() -> dict:
|
||
"""Perechea cerere/raspuns JSON formatata pentru cardul din pagina Integrare."""
|
||
return {
|
||
"cerere": json.dumps(_exemplu_cerere_dict(), indent=2, ensure_ascii=False),
|
||
"raspuns": json.dumps(_exemplu_raspuns_dict(), indent=2, ensure_ascii=False),
|
||
}
|
||
|
||
|
||
def _snippet_curl_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_str(account_id)
|
||
return f"""curl -X POST "{base_url}/v1/prezentari" \\
|
||
-H "Content-Type: application/json" \\
|
||
-H "X-API-Key: {_CHEIE_PLACEHOLDER}" \\
|
||
-d '{payload}'"""
|
||
|
||
|
||
def _snippet_curl_import(base_url: str, account_id: int) -> str:
|
||
fisier = '"file=@prezentari.xlsx"'
|
||
return (
|
||
f'curl -X POST "{base_url}/v1/import" \\\n'
|
||
f' -H "X-API-Key: {_CHEIE_PLACEHOLDER}" \\\n'
|
||
f" -F {fisier}"
|
||
)
|
||
|
||
|
||
def _snippet_python_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_str(account_id)
|
||
return f"""import requests
|
||
|
||
url = "{base_url}/v1/prezentari"
|
||
headers = {{
|
||
"X-API-Key": "{_CHEIE_PLACEHOLDER}",
|
||
"Content-Type": "application/json",
|
||
}}
|
||
payload = {payload}
|
||
|
||
response = requests.post(url, json=payload, headers=headers)
|
||
print(response.json())"""
|
||
|
||
|
||
def _snippet_python_import(base_url: str, account_id: int) -> str:
|
||
return f"""import requests
|
||
|
||
url = "{base_url}/v1/import"
|
||
headers = {{
|
||
"X-API-Key": "{_CHEIE_PLACEHOLDER}",
|
||
}}
|
||
|
||
with open("prezentari.xlsx", "rb") as f:
|
||
files = {{"file": ("prezentari.xlsx", f, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")}}
|
||
response = requests.post(url, headers=headers, files=files)
|
||
|
||
print(response.json())"""
|
||
|
||
|
||
def _snippet_php_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_str(account_id)
|
||
# Escapeaza apostrof-urile pentru PHP heredoc
|
||
payload_php = payload.replace("'", "\\'")
|
||
return f"""<?php
|
||
$url = "{base_url}/v1/prezentari";
|
||
$payload = '{payload_php}';
|
||
|
||
$ch = curl_init($url);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($ch, CURLOPT_POST, true);
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||
"Content-Type: application/json",
|
||
"X-API-Key: {_CHEIE_PLACEHOLDER}",
|
||
]);
|
||
|
||
$response = curl_exec($ch);
|
||
curl_close($ch);
|
||
echo $response;"""
|
||
|
||
|
||
def _snippet_php_import(base_url: str, account_id: int) -> str:
|
||
return f"""<?php
|
||
$url = "{base_url}/v1/import";
|
||
$fisier = new CURLFile("prezentari.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "prezentari.xlsx");
|
||
|
||
$ch = curl_init($url);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($ch, CURLOPT_POST, true);
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, ["file" => $fisier]);
|
||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||
"X-API-Key: {_CHEIE_PLACEHOLDER}",
|
||
]);
|
||
|
||
$response = curl_exec($ch);
|
||
curl_close($ch);
|
||
echo $response;"""
|
||
|
||
|
||
def _snippet_csharp_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_compact(account_id)
|
||
# Escape ghilimele duble pentru string C# (literal pe o singura linie)
|
||
payload_cs = payload.replace('"', '\\"')
|
||
return f"""using System.Net.Http;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
var client = new HttpClient();
|
||
client.DefaultRequestHeaders.Add("X-API-Key", "{_CHEIE_PLACEHOLDER}");
|
||
|
||
var json = "{payload_cs}";
|
||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||
|
||
var response = await client.PostAsync("{base_url}/v1/prezentari", content);
|
||
var body = await response.Content.ReadAsStringAsync();
|
||
Console.WriteLine(body);"""
|
||
|
||
|
||
def _snippet_csharp_import(base_url: str, account_id: int) -> str:
|
||
return f"""using System.Net.Http;
|
||
using System.Threading.Tasks;
|
||
|
||
var client = new HttpClient();
|
||
client.DefaultRequestHeaders.Add("X-API-Key", "{_CHEIE_PLACEHOLDER}");
|
||
|
||
using var form = new MultipartFormDataContent();
|
||
var fileBytes = File.ReadAllBytes("prezentari.xlsx");
|
||
var fileContent = new ByteArrayContent(fileBytes);
|
||
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(
|
||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||
form.Add(fileContent, "file", "prezentari.xlsx");
|
||
|
||
var response = await client.PostAsync("{base_url}/v1/import", form);
|
||
var body = await response.Content.ReadAsStringAsync();
|
||
Console.WriteLine(body);"""
|
||
|
||
|
||
def _snippet_node_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_str(account_id)
|
||
return f"""const payload = {payload};
|
||
|
||
const response = await fetch("{base_url}/v1/prezentari", {{
|
||
method: "POST",
|
||
headers: {{
|
||
"Content-Type": "application/json",
|
||
"X-API-Key": "{_CHEIE_PLACEHOLDER}",
|
||
}},
|
||
body: JSON.stringify(payload),
|
||
}});
|
||
|
||
const data = await response.json();
|
||
console.log(data);"""
|
||
|
||
|
||
def _snippet_node_import(base_url: str, account_id: int) -> str:
|
||
# FormData si Blob sunt globale in Node 18+ — nu necesita import din node:buffer
|
||
return f"""import {{ readFileSync }} from "fs";
|
||
|
||
const form = new FormData();
|
||
const continut = readFileSync("prezentari.xlsx");
|
||
form.append("file", new Blob([continut], {{
|
||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||
}}), "prezentari.xlsx");
|
||
|
||
const response = await fetch("{base_url}/v1/import", {{
|
||
method: "POST",
|
||
headers: {{ "X-API-Key": "{_CHEIE_PLACEHOLDER}" }},
|
||
body: form,
|
||
}});
|
||
|
||
const data = await response.json();
|
||
console.log(data);"""
|
||
|
||
|
||
def _snippet_vfp_msxml_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_compact(account_id)
|
||
# VFP: ghilimele in string se dubleaza; payload compact = o singura linie
|
||
payload_vfp = payload.replace('"', '""')
|
||
return f"""* Visual FoxPro — MSXML2.ServerXMLHTTP.6.0
|
||
LOCAL oHTTP, cURL, cPayload, cRaspuns
|
||
cURL = "{base_url}/v1/prezentari"
|
||
cPayload = "{payload_vfp}"
|
||
|
||
oHTTP = CREATEOBJECT("MSXML2.ServerXMLHTTP.6.0")
|
||
oHTTP.open("POST", cURL, .F.)
|
||
oHTTP.setRequestHeader("Content-Type", "application/json")
|
||
oHTTP.setRequestHeader("X-API-Key", "{_CHEIE_PLACEHOLDER}")
|
||
oHTTP.send(cPayload)
|
||
|
||
cRaspuns = oHTTP.responseText
|
||
? cRaspuns"""
|
||
|
||
|
||
def _snippet_vfp_msxml_import(base_url: str, account_id: int) -> str:
|
||
return f"""* Visual FoxPro — MSXML2.ServerXMLHTTP.6.0 — upload fisier
|
||
* Necesita ADODB.Stream pentru a citi fisierul binar
|
||
LOCAL oHTTP, oStream, oBody
|
||
LOCAL cURL, cGranita, cCRLF, cDisp, cType
|
||
|
||
cURL = "{base_url}/v1/import"
|
||
cGranita = "----AutoPassBoundary"
|
||
cCRLF = CHR(13) + CHR(10)
|
||
|
||
* Citire fisier in ADODB.Stream
|
||
oStream = CREATEOBJECT("ADODB.Stream")
|
||
oStream.Type = 1 && adTypeBinary
|
||
oStream.Open()
|
||
oStream.LoadFromFile("prezentari.xlsx")
|
||
|
||
* Construire body multipart (simplificat — pentru fisiere mici)
|
||
oBody = CREATEOBJECT("ADODB.Stream")
|
||
oBody.Type = 1
|
||
oBody.Open()
|
||
|
||
oHTTP = CREATEOBJECT("MSXML2.ServerXMLHTTP.6.0")
|
||
oHTTP.open("POST", cURL, .F.)
|
||
oHTTP.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + cGranita)
|
||
oHTTP.setRequestHeader("X-API-Key", "{_CHEIE_PLACEHOLDER}")
|
||
* Nota: pentru upload binar complet folositi un helper COM sau ADODB.
|
||
oHTTP.send(oBody)
|
||
? oHTTP.responseText"""
|
||
|
||
|
||
def _snippet_vfp_winhttp_prezentari(base_url: str, account_id: int) -> str:
|
||
payload = _payload_json_compact(account_id)
|
||
# VFP: ghilimele in string se dubleaza; payload compact = o singura linie
|
||
payload_vfp = payload.replace('"', '""')
|
||
return f"""* Visual FoxPro — WinHttp.WinHttpRequest.5.1
|
||
LOCAL oHTTP, cURL, cPayload, cRaspuns
|
||
cURL = "{base_url}/v1/prezentari"
|
||
cPayload = "{payload_vfp}"
|
||
|
||
oHTTP = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
|
||
oHTTP.Open("POST", cURL, .F.)
|
||
oHTTP.SetRequestHeader("Content-Type", "application/json")
|
||
oHTTP.SetRequestHeader("X-API-Key", "{_CHEIE_PLACEHOLDER}")
|
||
oHTTP.Send(cPayload)
|
||
|
||
cRaspuns = oHTTP.ResponseText
|
||
? cRaspuns"""
|
||
|
||
|
||
def _snippet_vfp_winhttp_import(base_url: str, account_id: int) -> str:
|
||
return f"""* Visual FoxPro — WinHttp.WinHttpRequest.5.1 — upload fisier
|
||
* Necesita ADODB.Stream pentru a citi fisierul binar
|
||
LOCAL oHTTP, oStream
|
||
LOCAL cURL, cGranita, cCRLF
|
||
|
||
cURL = "{base_url}/v1/import"
|
||
cGranita = "----AutoPassBoundary"
|
||
cCRLF = CHR(13) + CHR(10)
|
||
|
||
oStream = CREATEOBJECT("ADODB.Stream")
|
||
oStream.Type = 1 && adTypeBinary
|
||
oStream.Open()
|
||
oStream.LoadFromFile("prezentari.xlsx")
|
||
|
||
oHTTP = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
|
||
oHTTP.Open("POST", cURL, .F.)
|
||
oHTTP.SetRequestHeader("Content-Type", "multipart/form-data; boundary=" + cGranita)
|
||
oHTTP.SetRequestHeader("X-API-Key", "{_CHEIE_PLACEHOLDER}")
|
||
* Nota: pentru upload binar complet folositi un helper COM sau ADODB.
|
||
oHTTP.Send()
|
||
? oHTTP.ResponseText"""
|
||
|
||
|
||
def exemple(base_url: str, account_id: int) -> dict:
|
||
"""Genereaza snippet-uri de cod multi-limbaj pentru integrarea cu AutoPass.
|
||
|
||
Parametri:
|
||
base_url: URL-ul de baza al gateway-ului (ex. "https://autopass.example.com")
|
||
account_id: ID-ul contului (inclus in context, nu in snippet-uri)
|
||
|
||
Intoarce un dict structurat astfel:
|
||
{
|
||
"<limbaj>": {
|
||
"prezentari": "<snippet string>",
|
||
"import": "<snippet string>",
|
||
},
|
||
...
|
||
}
|
||
|
||
Limbaje: curl, python, php, csharp, node, vfp_msxml, vfp_winhttp.
|
||
|
||
Functie pura: fara I/O, fara DB, fara stare globala.
|
||
"""
|
||
return {
|
||
"curl": {
|
||
"prezentari": _snippet_curl_prezentari(base_url, account_id),
|
||
"import": _snippet_curl_import(base_url, account_id),
|
||
},
|
||
"python": {
|
||
"prezentari": _snippet_python_prezentari(base_url, account_id),
|
||
"import": _snippet_python_import(base_url, account_id),
|
||
},
|
||
"php": {
|
||
"prezentari": _snippet_php_prezentari(base_url, account_id),
|
||
"import": _snippet_php_import(base_url, account_id),
|
||
},
|
||
"csharp": {
|
||
"prezentari": _snippet_csharp_prezentari(base_url, account_id),
|
||
"import": _snippet_csharp_import(base_url, account_id),
|
||
},
|
||
"node": {
|
||
"prezentari": _snippet_node_prezentari(base_url, account_id),
|
||
"import": _snippet_node_import(base_url, account_id),
|
||
},
|
||
"vfp_msxml": {
|
||
"prezentari": _snippet_vfp_msxml_prezentari(base_url, account_id),
|
||
"import": _snippet_vfp_msxml_import(base_url, account_id),
|
||
},
|
||
"vfp_winhttp": {
|
||
"prezentari": _snippet_vfp_winhttp_prezentari(base_url, account_id),
|
||
"import": _snippet_vfp_winhttp_import(base_url, account_id),
|
||
},
|
||
}
|