ciyidogan commited on
Commit
bf5274e
·
verified ·
1 Parent(s): c08424b

Update api_executor.py

Browse files
Files changed (1) hide show
  1. api_executor.py +62 -70
api_executor.py CHANGED
@@ -1,93 +1,85 @@
1
  """
2
- Flare – API Executor
3
- ~~~~~~~~~~~~~~~~~~~~
4
- • Placeholder yerleştirme ({{variables.x}}, {{auth_tokens.api.token}}, {{config.xxx}})
5
- • Proxy string veya ProxyConfig objesi
6
- • Auth: enabled==True → token alma & cache
7
  """
8
 
9
  from __future__ import annotations
10
-
11
- import json
12
- import re
13
- import time
14
  from typing import Any, Dict
15
-
16
- import requests
17
  from utils import log
18
  from config_provider import ConfigProvider, APIConfig, ProxyConfig
19
-
20
  cfg = ConfigProvider.get()
21
- _token_cache: Dict[str, Dict[str, Any]] = {} # api_name → {token, expiry}
22
-
23
 
24
- # ----------- Placeholder helpers ----------
25
- _placeholder_re = re.compile(r"\{\{\s*([^\}]+?)\s*\}\}")
26
 
 
27
 
28
- def _render(obj: Any, variables: Dict[str, Any], api_name: str) -> Any:
29
- def repl(match):
30
- key = match.group(1)
31
  if key.startswith("variables."):
32
- return str(variables.get(key.split(".", 1)[1], ""))
33
  if key.startswith("auth_tokens."):
34
- _, api, _ = key.split(".")
35
- return _token_cache.get(api, {}).get("token", "")
36
  if key.startswith("config."):
37
- _, prop = key.split(".", 1)
38
- return str(getattr(cfg.global_config, prop, ""))
39
- return match.group(0)
40
-
41
- if isinstance(obj, str):
42
- return _placeholder_re.sub(repl, obj)
43
- if isinstance(obj, dict):
44
- return {k: _render(v, variables, api_name) for k, v in obj.items()}
45
- if isinstance(obj, list):
46
- return [_render(v, variables, api_name) for v in obj]
47
  return obj
48
 
49
-
50
- # ----------- Auth helpers -----------------
51
- def _ensure_token(api: APIConfig):
52
- if not api.auth or not api.auth.enabled:
53
- return
54
- cached = _token_cache.get(api.name)
55
- if cached and cached["expiry"] > time.time():
56
- return
57
-
58
- body = api.auth.token_request_body
59
- body = _render(body, {}, api.name)
60
- log(f"🔒 Fetching token for {api.name} …")
61
- r = requests.post(api.auth.token_endpoint, json=body, timeout=api.timeout_seconds)
62
  r.raise_for_status()
63
- js = r.json()
64
- token = js
65
- for part in api.auth.response_token_path.split("."):
66
- token = token[part]
67
- _token_cache[api.name] = {"token": token, "expiry": time.time() + 3500}
68
-
 
 
 
69
 
70
- # ----------- Main call --------------------
71
- def call_api(api: APIConfig, variables: Dict[str, Any]):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  _ensure_token(api)
73
-
74
- headers = _render(api.headers, variables, api.name)
75
- body = _render(api.body_template, variables, api.name)
76
- url = api.url
77
- method = api.method.upper()
78
-
79
- proxy = None
80
  if api.proxy:
81
- proxy = api.proxy if isinstance(api.proxy, str) else (api.proxy.url if api.proxy.enabled else None)
82
-
83
- log(f"🌐 {api.name} → {method} {url}")
84
- r = requests.request(
85
- method,
86
- url,
87
- json=body if method in ("POST", "PUT", "PATCH") else None,
88
- params=body if method == "GET" else None,
89
- headers=headers,
90
- proxies={"http": proxy, "https": proxy} if proxy else None,
91
  timeout=api.timeout_seconds,
92
  )
93
  r.raise_for_status()
 
1
  """
2
+ Flare – API Executor (token refresh eklenmiş)
 
 
 
 
3
  """
4
 
5
  from __future__ import annotations
6
+ import json, re, time, requests
 
 
 
7
  from typing import Any, Dict
 
 
8
  from utils import log
9
  from config_provider import ConfigProvider, APIConfig, ProxyConfig
 
10
  cfg = ConfigProvider.get()
 
 
11
 
12
+ _token: Dict[str, Dict[str, Any]] = {} # {api: {token, expiry, refresh_ep, refresh_body}}
 
13
 
14
+ _placeholder = re.compile(r"\{\{\s*([^\}]+?)\s*\}\}")
15
 
16
+ def _render(obj, vars, api):
17
+ def r(m):
18
+ key=m.group(1)
19
  if key.startswith("variables."):
20
+ return str(vars.get(key.split(".",1)[1],""))
21
  if key.startswith("auth_tokens."):
22
+ _, apiname, _ = key.split(".")
23
+ return _token.get(apiname,{}).get("token","")
24
  if key.startswith("config."):
25
+ return str(getattr(cfg.global_config, key.split(".",1)[1], ""))
26
+ return m.group(0)
27
+ if isinstance(obj,str): return _placeholder.sub(r,obj)
28
+ if isinstance(obj,dict): return {k:_render(v,vars,api) for k,v in obj.items()}
29
+ if isinstance(obj,list): return [_render(v,vars,api) for v in obj]
 
 
 
 
 
30
  return obj
31
 
32
+ def _fetch_token(api: APIConfig):
33
+ body=_render(api.auth.token_request_body,{},api.name)
34
+ r=requests.post(api.auth.token_endpoint,json=body,timeout=api.timeout_seconds)
 
 
 
 
 
 
 
 
 
 
35
  r.raise_for_status()
36
+ js=r.json()
37
+ tok=js
38
+ for p in api.auth.response_token_path.split("."): tok=tok[p]
39
+ _token[api.name]={
40
+ "token":tok,
41
+ "expiry":time.time()+3500,
42
+ "refresh_ep":api.auth.token_refresh_endpoint,
43
+ "refresh_body":api.auth.token_refresh_body,
44
+ }
45
 
46
+ def _ensure_token(api: APIConfig):
47
+ if not api.auth or not api.auth.enabled: return
48
+ info=_token.get(api.name)
49
+ if not info: _fetch_token(api); return
50
+ if info["expiry"]>time.time(): return
51
+
52
+ # refresh varsa dene
53
+ if info["refresh_ep"]:
54
+ body=_render(info["refresh_body"],{},api.name)
55
+ try:
56
+ r=requests.post(info["refresh_ep"],json=body,timeout=api.timeout_seconds)
57
+ r.raise_for_status()
58
+ js=r.json()
59
+ tok=js
60
+ for p in api.auth.response_token_path.split("."): tok=tok[p]
61
+ info["token"]=tok; info["expiry"]=time.time()+3500
62
+ return
63
+ except Exception as e:
64
+ log(f"⚠️ token refresh fail {e}")
65
+
66
+ _fetch_token(api)
67
+
68
+ def call_api(api: APIConfig, vars: Dict[str,Any]):
69
  _ensure_token(api)
70
+ hdr=_render(api.headers,vars,api.name)
71
+ body=_render(api.body_template,vars,api.name)
72
+ proxy=None
 
 
 
 
73
  if api.proxy:
74
+ proxy=api.proxy if isinstance(api.proxy,str) else (api.proxy.url if api.proxy.enabled else None)
75
+ log(f"🌐 {api.name} {api.method} {api.url}")
76
+ r=requests.request(
77
+ api.method,
78
+ api.url,
79
+ json=body if api.method in ("POST","PUT","PATCH") else None,
80
+ params=body if api.method=="GET" else None,
81
+ headers=hdr,
82
+ proxies={"http":proxy,"https":proxy} if proxy else None,
 
83
  timeout=api.timeout_seconds,
84
  )
85
  r.raise_for_status()