fix: fetch dataset scope options from WorldQuant platform
This commit is contained in:
@@ -266,6 +266,10 @@ class WqClient:
|
||||
raise WqError("验证会话已失效,请重新连接", "authentication_failed")
|
||||
|
||||
async def get(self, path: str, params=None, headers=None):
|
||||
return await self._read_json("GET", path, params=params, headers=headers)
|
||||
|
||||
async def _read_json(self, method: str, path: str, **kwargs):
|
||||
"""Authenticated read with shared refresh/retry handling; callers use GET or OPTIONS."""
|
||||
if not self.credentials:
|
||||
raise WqError("请先连接 WorldQuant", "disconnected")
|
||||
if not self.authenticated:
|
||||
@@ -273,7 +277,7 @@ class WqClient:
|
||||
refreshed = False
|
||||
for attempt in range(self.settings.retry_attempts):
|
||||
generation = self.auth_generation
|
||||
response = await self._request("GET", path, params=params, headers=headers)
|
||||
response = await self._request(method, path, **kwargs)
|
||||
if response.status_code == 401 and not refreshed:
|
||||
await self.authenticate(*self.credentials, stale_generation=generation)
|
||||
refreshed = True
|
||||
@@ -359,9 +363,58 @@ class WqClient:
|
||||
|
||||
async def catalog_page(self, scope, dataset_id, offset):
|
||||
"""Read a single scoped page. IDs are query parameters, never upstream paths."""
|
||||
params = {"instrumentType": scope["instrument_type"], "region": scope["region"],
|
||||
"universe": scope["universe"], "delay": scope["delay"],
|
||||
"limit": 50, "offset": offset}
|
||||
params = {
|
||||
"instrumentType": scope["instrument_type"],
|
||||
"region": scope["region"],
|
||||
"universe": scope["universe"],
|
||||
"delay": scope["delay"],
|
||||
"limit": 50,
|
||||
"offset": offset,
|
||||
}
|
||||
if dataset_id is not None:
|
||||
params["dataset.id"] = dataset_id
|
||||
return await self.get("/data-fields" if dataset_id else "/data-sets", params)
|
||||
|
||||
async def get_platform_setting_options(self):
|
||||
"""Read platform choices for the connected account; malformed responses raise WqError."""
|
||||
data = await self._read_json("OPTIONS", "/simulations")
|
||||
try:
|
||||
children = data["actions"]["POST"]["settings"]["children"]
|
||||
|
||||
def choices(key, instrument=None, region=None):
|
||||
value = children[key]["choices"]
|
||||
if instrument is not None:
|
||||
value = value["instrumentType"][instrument]
|
||||
if region is not None:
|
||||
value = value["region"][region]
|
||||
values = [item["value"] for item in value]
|
||||
if not values:
|
||||
raise ValueError()
|
||||
return values
|
||||
|
||||
instruments = choices("instrumentType")
|
||||
regions = {}
|
||||
rows = []
|
||||
for instrument in instruments:
|
||||
regions[instrument] = choices("region", instrument)
|
||||
for region in regions[instrument]:
|
||||
universes = choices("universe", instrument, region)
|
||||
for delay in choices("delay", instrument, region):
|
||||
if type(delay) is not int or delay < 0:
|
||||
raise ValueError()
|
||||
if not all(
|
||||
isinstance(v, str) and v and "|" not in v
|
||||
for v in [instrument, region, *universes]
|
||||
):
|
||||
raise ValueError()
|
||||
rows.append(
|
||||
dict(instrument_type=instrument, region=region, delay=delay, universes=universes)
|
||||
)
|
||||
return dict(
|
||||
instrument_options=rows,
|
||||
instrument_types=instruments,
|
||||
regions_by_type=regions,
|
||||
total_combinations=len(rows),
|
||||
)
|
||||
except (KeyError, TypeError, ValueError):
|
||||
raise WqError("平台配置选项格式无法识别,请稍后重试", "invalid_response") from None
|
||||
|
||||
Reference in New Issue
Block a user