flare / api_executor.py
ciyidogan's picture
Update api_executor.py
38415cf verified
raw
history blame
2.99 kB
"""
Flare – API Executor
~~~~~~~~~~~~~~~~~~~~
• Placeholder yerleştirme ({{variables.x}}, {{auth_tokens.api.token}}, {{config.xxx}})
• Proxy string veya ProxyConfig objesi
• Auth: enabled==True → token alma & cache
"""
from __future__ import annotations
import json
import re
import time
from typing import Any, Dict
import requests
from utils import log
from config_provider import ConfigProvider, APIConfig, ProxyConfig
cfg = ConfigProvider.get()
_token_cache: Dict[str, Dict[str, Any]] = {} # api_name → {token, expiry}
# ----------- Placeholder helpers ----------
_placeholder_re = re.compile(r"\{\{\s*([^\}]+?)\s*\}\}")
def _render(obj: Any, variables: Dict[str, Any], api_name: str) -> Any:
def repl(match):
key = match.group(1)
if key.startswith("variables."):
return str(variables.get(key.split(".", 1)[1], ""))
if key.startswith("auth_tokens."):
_, api, _ = key.split(".")
return _token_cache.get(api, {}).get("token", "")
if key.startswith("config."):
_, prop = key.split(".", 1)
return str(getattr(cfg.global_config, prop, ""))
return match.group(0)
if isinstance(obj, str):
return _placeholder_re.sub(repl, obj)
if isinstance(obj, dict):
return {k: _render(v, variables, api_name) for k, v in obj.items()}
if isinstance(obj, list):
return [_render(v, variables, api_name) for v in obj]
return obj
# ----------- Auth helpers -----------------
def _ensure_token(api: APIConfig):
if not api.auth or not api.auth.enabled:
return
cached = _token_cache.get(api.name)
if cached and cached["expiry"] > time.time():
return
body = api.auth.token_request_body
body = _render(body, {}, api.name)
log(f"🔒 Fetching token for {api.name} …")
r = requests.post(api.auth.token_endpoint, json=body, timeout=api.timeout_seconds)
r.raise_for_status()
js = r.json()
token = js
for part in api.auth.response_token_path.split("."):
token = token[part]
_token_cache[api.name] = {"token": token, "expiry": time.time() + 3500}
# ----------- Main call --------------------
def call_api(api: APIConfig, variables: Dict[str, Any]):
_ensure_token(api)
headers = _render(api.headers, variables, api.name)
body = _render(api.body_template, variables, api.name)
url = api.url
method = api.method.upper()
proxy = None
if api.proxy:
proxy = api.proxy if isinstance(api.proxy, str) else (api.proxy.url if api.proxy.enabled else None)
log(f"🌐 {api.name}{method} {url}")
r = requests.request(
method,
url,
json=body if method in ("POST", "PUT", "PATCH") else None,
params=body if method == "GET" else None,
headers=headers,
proxies={"http": proxy, "https": proxy} if proxy else None,
timeout=api.timeout_seconds,
)
r.raise_for_status()
return r