Automatic flex query syncing
This commit is contained in:
@@ -29,12 +29,18 @@ class FlexConfig:
|
||||
data_dir: Path
|
||||
poll_interval_seconds: float = 2.0
|
||||
max_polls: int = 30
|
||||
send_request_retry_seconds: float = 10.0
|
||||
max_send_request_attempts: int = 6
|
||||
|
||||
|
||||
class FlexQueryError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
class FlexQueryRetryableError(FlexQueryError):
|
||||
pass
|
||||
|
||||
|
||||
def load_flex_config() -> FlexConfig | None:
|
||||
token = os.environ.get("IB_FLEX_TOKEN", "").strip()
|
||||
query_id = os.environ.get("IB_FLEX_QUERY_ID", "").strip()
|
||||
@@ -86,7 +92,11 @@ def _parse_send_request(xml_bytes: bytes) -> tuple[str, str]:
|
||||
root = ET.fromstring(xml_bytes)
|
||||
status = (root.findtext("Status") or "").strip()
|
||||
if status.lower() != "success":
|
||||
raise FlexQueryError(root.findtext("ErrorMessage") or "Flex send-request failed")
|
||||
error_code = (root.findtext("ErrorCode") or "").strip()
|
||||
error_message = (root.findtext("ErrorMessage") or "Flex send-request failed").strip()
|
||||
if error_code == "1004":
|
||||
raise FlexQueryRetryableError(error_message)
|
||||
raise FlexQueryError(error_message)
|
||||
reference_code = (root.findtext("ReferenceCode") or "").strip()
|
||||
if not reference_code:
|
||||
raise FlexQueryError("Flex send-request returned no ReferenceCode")
|
||||
@@ -110,10 +120,23 @@ def fetch_flex_statement() -> dict:
|
||||
|
||||
config.data_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
_, reference_code = _parse_send_request(_http_get(
|
||||
FLEX_SEND_REQUEST_URL,
|
||||
{"t": config.token, "q": config.query_id, "v": "3"},
|
||||
))
|
||||
reference_code = None
|
||||
last_retryable_error = None
|
||||
for attempt in range(1, config.max_send_request_attempts + 1):
|
||||
try:
|
||||
_, reference_code = _parse_send_request(_http_get(
|
||||
FLEX_SEND_REQUEST_URL,
|
||||
{"t": config.token, "q": config.query_id, "v": "3"},
|
||||
))
|
||||
break
|
||||
except FlexQueryRetryableError as exc:
|
||||
last_retryable_error = str(exc)
|
||||
if attempt >= config.max_send_request_attempts:
|
||||
raise FlexQueryError(last_retryable_error) from exc
|
||||
time.sleep(config.send_request_retry_seconds)
|
||||
|
||||
if not reference_code:
|
||||
raise FlexQueryError(last_retryable_error or "Flex send-request returned no ReferenceCode")
|
||||
|
||||
statement_xml = None
|
||||
for _ in range(config.max_polls):
|
||||
|
||||
Reference in New Issue
Block a user