mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-08 18:32:21 +00:00
* refactor openbb-sec for v5 * linting * ty * normalize compare_company_facts * add workflows * python 3.10 fix * add more thorough url validation and tests * ty check * ty for python 3.10 * reconfigure with apps * temp pyproject overrride * pyproject * pyproject * pyproject * codespell * pyproject * fix uk schema file links in schema_files * test coverage * test_cli * port #7547 into this pr * no hard coded prefix * improve filing rendering capabilities * fix xml text detection * make codeql happy * missed a file in the commit * test coverage * codespell * fix flakey test * some updates * management_ownership --> management_profiles * proxy statement markdown * ruff * fix test coverage * more tests * test coverage * fix lint errors * Add SEC adviser search, profile, and universe routes (#7559) * Add SEC institutional data fetchers * Add SEC filing index and Form D routes * Add SEC investment adviser people data * Expose SEC adviser and institutional routes * fix(sec): address adviser review feedback * refactor(sec): narrow adviser support to IAPD search * feat(sec): add adviser firm and individual searches * feat(sec): add adviser profile drill-down * fix: repair pre-commit configuration * feat(sec): add adviser universe route * feat(sec): expose complete Form ADV data --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * fix test coverage --------- Co-authored-by: deeleeramone <> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
68 lines
1.9 KiB
Python
68 lines
1.9 KiB
Python
"""Process-wide rate limiter for SEC EDGAR requests."""
|
|
|
|
import asyncio
|
|
import os
|
|
import threading
|
|
import time
|
|
from typing import Any
|
|
|
|
_DEFAULT_REQUESTS_PER_SECOND = 9.0
|
|
REQUESTS_PER_SECOND_ENV_VAR = "OPENBB_SEC_REQUESTS_PER_SECOND"
|
|
|
|
_lock = threading.Lock()
|
|
_next_available = 0.0
|
|
|
|
|
|
def _requests_per_second() -> float:
|
|
"""Return the configured request rate, falling back to the default."""
|
|
raw = os.environ.get(REQUESTS_PER_SECOND_ENV_VAR)
|
|
if raw:
|
|
try:
|
|
value = float(raw)
|
|
except ValueError:
|
|
return _DEFAULT_REQUESTS_PER_SECOND
|
|
if value > 0:
|
|
return value
|
|
return _DEFAULT_REQUESTS_PER_SECOND
|
|
|
|
|
|
def _reserve_slot() -> float:
|
|
"""Reserve the next request slot; return the seconds to wait before sending."""
|
|
global _next_available # noqa: PLW0603
|
|
interval = 1.0 / _requests_per_second()
|
|
with _lock:
|
|
now = time.monotonic()
|
|
scheduled = max(now, _next_available)
|
|
_next_available = scheduled + interval
|
|
return scheduled - now
|
|
|
|
|
|
async def sec_rate_limit() -> None:
|
|
"""Await this process's next SEC request slot (async paths)."""
|
|
wait = _reserve_slot()
|
|
if wait > 0:
|
|
await asyncio.sleep(wait)
|
|
|
|
|
|
def sec_rate_limit_sync() -> None:
|
|
"""Block until this process's next SEC request slot is free (sync paths)."""
|
|
wait = _reserve_slot()
|
|
if wait > 0:
|
|
time.sleep(wait)
|
|
|
|
|
|
async def sec_amake_request(*args: Any, **kwargs: Any) -> Any:
|
|
"""Rate-limited ``amake_request`` for SEC EDGAR."""
|
|
from openbb_core.provider.utils.helpers import amake_request # noqa: PLC0415
|
|
|
|
await sec_rate_limit()
|
|
return await amake_request(*args, **kwargs)
|
|
|
|
|
|
def sec_make_request(*args: Any, **kwargs: Any) -> Any:
|
|
"""Rate-limited ``make_request`` for SEC EDGAR."""
|
|
from openbb_core.provider.utils.helpers import make_request # noqa: PLC0415
|
|
|
|
sec_rate_limit_sync()
|
|
return make_request(*args, **kwargs)
|