degenbot.aave.analysis.orchestrator =================================== .. py:module:: degenbot.aave.analysis.orchestrator .. autoapi-nested-parse:: I/O orchestration for Aave V3 position analysis. A thin Python driver shell over the Rust ``degenbot-aave::analysis`` core (ADR-005 three-layer architecture). The pure math (health-factor / LTV / eMode / isolation / scaled-balance calc) lives in Rust; this module owns only the I/O orchestration: resolve the DB path, fetch users / positions / prices via Rust-backed readers, drive the per-user Rust analysis seam, and bucket the results. The former ``core.py`` (pure math + dataclasses) + ``protocols.py`` (typing seams) were retired once the Rust core reached byte-identical parity (verified by the §4.2 parity gate before deletion). The ``PositionAnalysisResult`` bucket-sorter stays here (it's trivial Python, not math). Module Contents --------------- .. py:class:: DatabasePositionQuery(database_path: pathlib.Path) PositionQuery backed by the Rust ``_EnginePositionQuery`` reader. Routes every read through the PyO3 seam (ADR-005) over one explicit, file-backed database path. .. py:method:: get_users_with_debt(market_id: int, limit: int | None = None) -> list[dict[str, Any]] Get all users with debt positions in a market, as flat dicts. :returns: The Rust-backed row dicts (address checksummed to match the price-map keys the analysis seam consumes). .. py:method:: get_collateral_positions(user_id: int) -> list[dict[str, Any]] Get collateral positions for a user, as flat dicts. :returns: The Rust-backed row dicts (address checksummed). .. py:method:: get_debt_positions(user_id: int) -> list[dict[str, Any]] Get debt positions for a user, as flat dicts. :returns: The Rust-backed row dicts (address checksummed). .. py:method:: get_collateral_config_map(user_id: int) -> dict[int, bool] Get map of asset_id to enabled status for a user. :returns: The computed value. .. py:method:: get_oracle_address(market_id: int) -> degenbot._ffi.ChecksummedAddress | None Get the price oracle address for a market. :returns: The computed value. .. py:method:: get_asset_addresses(market_id: int) -> set[degenbot._ffi.ChecksummedAddress] Get all unique underlying asset addresses for a market. :returns: The computed value. .. py:class:: OraclePriceFetcher(provider: degenbot.provider.AlloyProvider, oracle_address: degenbot._ffi.ChecksummedAddress) PriceFetcher using the Aave oracle contract. Delegating shell over the Rust ``AavePriceOracle`` reader (the ``degenbot-price`` core crate, ADR-005). ``getAssetPrice(address)`` ``eth_call`` + ``uint256`` decode run in Rust, with the same tolerant per-asset skip-on-error behavior. .. py:method:: fetch(asset_addresses: set[degenbot._ffi.ChecksummedAddress]) -> dict[degenbot._ffi.ChecksummedAddress, int] Fetch prices for all assets from the Aave oracle. :returns: The computed value. .. py:class:: PositionAnalysisResult Result of analyzing positions for liquidation risk. Bucket-sorter only (no math) — the per-user ``UserPositionSummary`` objects (Rust-built via the analysis seam) are categorized by health factor into safe / at-risk / liquidatable lists. .. py:attribute:: safe_users :type: list[degenbot.db.UserPositionSummary] :value: [] .. py:attribute:: at_risk_users :type: list[degenbot.db.UserPositionSummary] :value: [] .. py:attribute:: liquidatable_users :type: list[degenbot.db.UserPositionSummary] :value: [] .. py:property:: total_users :type: int Total users. .. py:property:: at_risk_count :type: int At risk count. .. py:property:: liquidatable_count :type: int Liquidatable count. .. py:method:: categorize(summary: degenbot.db.UserPositionSummary, health_factor_threshold: float = 1.1) -> None Categorize a user summary by health factor. :param summary: A ``UserPositionSummary`` (Rust-built). :param health_factor_threshold: The at-risk threshold (default 1.1). .. py:method:: sort_by_risk() -> None Sort at-risk + liquidatable users by health factor (lowest first). Mirrors the Rust ``PositionAnalysisResult::sort_by_risk`` key: a ``None`` OR falsy (``0.0``) health factor sorts as ``+inf`` (the Python ``or`` treats ``0.0`` as falsy). .. py:function:: analyze_positions_for_market(database_path: pathlib.Path, market_id: int, health_factor_threshold: float = 1.1, limit: int | None = None, provider: degenbot.provider.AlloyProvider | None = None) -> PositionAnalysisResult Analyze all users-with-debt in a market for liquidation risk. Thin driver shell: fetches users + prices via Rust-backed readers, drives the per-user ``analyze_aave_user_position`` Rust seam, and buckets the results. The pure math (HF / LTV / scaled-balance) lives in Rust (``degenbot-aave::analysis``). :param database_path: File-backed SQLite database opened by the Rust reader. :param market_id: The Aave V3 market id. :param health_factor_threshold: The at-risk threshold (default 1.1). :param limit: Optional cap on the number of users analyzed. :param provider: Optional RPC provider for price fetching (when ``None``, prices are treated as 1 — faster, but HFs are relative). :returns: The bucketed analysis result.