chore: smoke test fixes and code quality improvements (#88)
* fix: replace deprecated datetime.utcnow() and websockets.legacy APIs - Replace datetime.utcnow() with datetime.now(UTC) in Orderbook model - Use websockets.asyncio.client.connect instead of legacy websockets.connect - Import ConnectionClosed from websockets.exceptions directly - Update test mocks to patch the new import paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: resolve ruff lint errors in alembic migration - Replace typing.Union with X | Y syntax (UP007) - Import Sequence from collections.abc instead of typing (UP035) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove deprecated version key from docker-compose.yml The top-level 'version' key is obsolete in modern Docker Compose and produces a warning. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: fix README to match actual project structure and tooling - Replace pip commands with uv equivalents - Fix run command from 'python -m src.main' to 'python -m polymarket_insider_tracker' - Update project structure tree to reflect actual src/polymarket_insider_tracker/ layout Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -126,13 +126,13 @@ docker compose up -d
|
||||
docker compose ps
|
||||
|
||||
# Install Python dependencies
|
||||
pip install -e .
|
||||
uv sync --all-extras
|
||||
|
||||
# Run database migrations
|
||||
alembic upgrade head
|
||||
uv run alembic upgrade head
|
||||
|
||||
# Run the tracker
|
||||
python -m src.main
|
||||
uv run python -m polymarket_insider_tracker
|
||||
```
|
||||
|
||||
### Docker Services
|
||||
@@ -188,24 +188,16 @@ LIQUIDITY_IMPACT_THRESHOLD=0.02
|
||||
```
|
||||
polymarket-insider-tracker/
|
||||
├── src/
|
||||
│ ├── ingestor/ # Real-time market data ingestion
|
||||
│ │ ├── clob_client.py # Polymarket CLOB API wrapper
|
||||
│ │ └── websocket.py # WebSocket event handler
|
||||
│ ├── profiler/ # Wallet analysis
|
||||
│ │ ├── analyzer.py # Core wallet profiling logic
|
||||
│ │ ├── chain.py # Polygon blockchain client
|
||||
│ │ └── funding.py # Funding chain tracer
|
||||
│ ├── detector/ # Anomaly detection engines
|
||||
│ │ ├── fresh_wallet.py
|
||||
│ │ ├── size_anomaly.py
|
||||
│ │ ├── sniper.py # DBSCAN clustering
|
||||
│ │ └── scorer.py # Composite risk scoring
|
||||
│ ├── alerter/ # Notification dispatch
|
||||
│ │ ├── formatter.py # Alert message formatting
|
||||
│ │ └── dispatcher.py # Multi-channel delivery
|
||||
│ └── storage/ # Persistence layer
|
||||
│ ├── models.py # SQLAlchemy models
|
||||
│ └── repos.py # Repository pattern
|
||||
│ └── polymarket_insider_tracker/
|
||||
│ ├── __main__.py # CLI entry point
|
||||
│ ├── pipeline.py # Core detection pipeline
|
||||
│ ├── ingestor/ # Real-time market data ingestion
|
||||
│ │ ├── clob_client.py # Polymarket CLOB API wrapper
|
||||
│ │ └── websocket.py # WebSocket event handler
|
||||
│ ├── profiler/ # Wallet analysis
|
||||
│ ├── detector/ # Anomaly detection engines
|
||||
│ ├── alerter/ # Notification dispatch
|
||||
│ └── storage/ # Persistence layer
|
||||
├── tests/ # Test suite
|
||||
├── scripts/
|
||||
│ └── backtest.py # Historical analysis
|
||||
@@ -289,16 +281,16 @@ Contributions are welcome! Please read our Contributing Guide before submitting
|
||||
|
||||
```bash
|
||||
# Install dev dependencies
|
||||
pip install -e ".[dev]"
|
||||
uv sync --all-extras
|
||||
|
||||
# Run tests
|
||||
pytest
|
||||
uv run pytest
|
||||
|
||||
# Run linting
|
||||
ruff check src/
|
||||
uv run ruff check src/
|
||||
|
||||
# Run type checking
|
||||
mypy src/
|
||||
uv run mypy src/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -5,16 +5,16 @@ Revises:
|
||||
Create Date: 2026-01-04 00:00:00.000000+00:00
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "001_initial"
|
||||
down_revision: Union[str, None] = None
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
down_revision: str | None = None
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
|
||||
@@ -86,7 +86,7 @@ class Orderbook:
|
||||
bids: tuple[OrderbookLevel, ...]
|
||||
asks: tuple[OrderbookLevel, ...]
|
||||
tick_size: Decimal
|
||||
timestamp: datetime = field(default_factory=datetime.utcnow)
|
||||
timestamp: datetime = field(default_factory=lambda: datetime.now(UTC))
|
||||
|
||||
@classmethod
|
||||
def from_clob_orderbook(cls, orderbook: Any) -> "Orderbook":
|
||||
|
||||
@@ -9,8 +9,9 @@ from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
import websockets
|
||||
from websockets.asyncio.client import ClientConnection
|
||||
from websockets.asyncio.client import connect as ws_connect
|
||||
from websockets.exceptions import ConnectionClosed
|
||||
|
||||
from polymarket_insider_tracker.ingestor.models import TradeEvent
|
||||
|
||||
@@ -156,7 +157,7 @@ class TradeStreamHandler:
|
||||
await self._set_state(ConnectionState.CONNECTING)
|
||||
|
||||
try:
|
||||
ws = await websockets.connect(
|
||||
ws = await ws_connect(
|
||||
self._host,
|
||||
ping_interval=self._ping_interval,
|
||||
ping_timeout=self._ping_interval * 2,
|
||||
@@ -227,7 +228,7 @@ class TradeStreamHandler:
|
||||
else:
|
||||
logger.debug("Received binary message (%d bytes)", len(message))
|
||||
|
||||
except websockets.ConnectionClosed as e:
|
||||
except ConnectionClosed as e:
|
||||
logger.warning("Connection closed: %s", e)
|
||||
raise
|
||||
except Exception as e:
|
||||
@@ -284,7 +285,7 @@ class TradeStreamHandler:
|
||||
while self._running:
|
||||
try:
|
||||
await self._listen(self._ws)
|
||||
except (websockets.ConnectionClosed, Exception) as e:
|
||||
except (ConnectionClosed, Exception) as e:
|
||||
if not self._running:
|
||||
break
|
||||
|
||||
|
||||
@@ -231,7 +231,10 @@ class TestTradeStreamHandler:
|
||||
mock_ws = AsyncMock()
|
||||
mock_ws.send = AsyncMock()
|
||||
|
||||
with patch("websockets.connect", AsyncMock(return_value=mock_ws)):
|
||||
with patch(
|
||||
"polymarket_insider_tracker.ingestor.websocket.ws_connect",
|
||||
AsyncMock(return_value=mock_ws),
|
||||
):
|
||||
ws = await handler._connect()
|
||||
|
||||
assert ws is mock_ws
|
||||
@@ -333,7 +336,10 @@ class TestTradeStreamHandlerIntegration:
|
||||
|
||||
mock_ws = MockWebSocket(handler, trade_message)
|
||||
|
||||
with patch("websockets.connect", AsyncMock(return_value=mock_ws)):
|
||||
with patch(
|
||||
"polymarket_insider_tracker.ingestor.websocket.ws_connect",
|
||||
AsyncMock(return_value=mock_ws),
|
||||
):
|
||||
# Run with timeout to prevent hanging
|
||||
try:
|
||||
await asyncio.wait_for(handler.start(), timeout=1.0)
|
||||
|
||||
Reference in New Issue
Block a user