mirror of
https://git.zavage.net/Zavage-Software/wabot.git
synced 2026-07-22 13:36:08 -06:00
refactor: rename sessions submodule to _sessions to avoid shadowing sessions()
wabot/__init__.py defines def sessions(...) and also had a sessions.py submodule, so wabot.sessions (attribute) resolved to the function, shadowing the module for import wabot.sessions as m style access. This is the same class of collision that browser.py -> _browser.py already fixed. Renaming to _sessions.py removes the ambiguity and lets docs/api.rst drop the :no-index: Sphinx workaround in favor of plain autoclass directives on the public SessionRecord/SessionStore re-exports.
This commit is contained in:
parent
68978a34e7
commit
154344e94a
@ -16,9 +16,11 @@ API reference
|
|||||||
.. automodule:: wabot.pacing
|
.. automodule:: wabot.pacing
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. automodule:: wabot.sessions
|
.. autoclass:: wabot.SessionRecord
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: wabot.SessionStore
|
||||||
:members:
|
:members:
|
||||||
:no-index:
|
|
||||||
|
|
||||||
.. automodule:: wabot.hosts
|
.. automodule:: wabot.hosts
|
||||||
:members: ExternalServer, ManagedService, attach, service_alive
|
:members: ExternalServer, ManagedService, attach, service_alive
|
||||||
|
|||||||
@ -44,7 +44,7 @@ wabot/ (repo root, branch feature/modernization
|
|||||||
├── src/wabot/
|
├── src/wabot/
|
||||||
│ ├── __init__.py # public API: browser(), sessions(), destroy(), re-exports
|
│ ├── __init__.py # public API: browser(), sessions(), destroy(), re-exports
|
||||||
│ ├── pacing.py # NoPacing / HumanPacing
|
│ ├── pacing.py # NoPacing / HumanPacing
|
||||||
│ ├── sessions.py # SessionRecord, SessionStore
|
│ ├── _sessions.py # SessionRecord, SessionStore (underscored to avoid shadowing sessions())
|
||||||
│ ├── hosts.py # build_options, service_alive, ExternalServer,
|
│ ├── hosts.py # build_options, service_alive, ExternalServer,
|
||||||
│ │ # ManagedService, find_driver_binary, stop_service,
|
│ │ # ManagedService, find_driver_binary, stop_service,
|
||||||
│ │ # ReattachingRemote, attach
|
│ │ # ReattachingRemote, attach
|
||||||
@ -291,10 +291,10 @@ git commit -m "feat: pacing policies (HumanPacing default behavior, NoPacing for
|
|||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
### Task 3: `sessions.py` — SessionRecord + SessionStore
|
### Task 3: `_sessions.py` — SessionRecord + SessionStore
|
||||||
|
|
||||||
**Files:**
|
**Files:**
|
||||||
- Create: `src/wabot/sessions.py`
|
- Create: `src/wabot/_sessions.py`
|
||||||
- Test: `tests/unit/test_sessions.py`
|
- Test: `tests/unit/test_sessions.py`
|
||||||
|
|
||||||
- [ ] **Step 1: Write the failing tests**
|
- [ ] **Step 1: Write the failing tests**
|
||||||
@ -304,7 +304,7 @@ git commit -m "feat: pacing policies (HumanPacing default behavior, NoPacing for
|
|||||||
```python
|
```python
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
from wabot.sessions import SessionRecord, SessionStore
|
from wabot._sessions import SessionRecord, SessionStore
|
||||||
|
|
||||||
|
|
||||||
def make_record(name="scraper1", created_at=None):
|
def make_record(name="scraper1", created_at=None):
|
||||||
@ -367,7 +367,7 @@ class TestSessionStore:
|
|||||||
assert store.get("scraper1") is not None
|
assert store.get("scraper1") is not None
|
||||||
|
|
||||||
def test_default_path_is_under_platformdirs(self):
|
def test_default_path_is_under_platformdirs(self):
|
||||||
from wabot.sessions import default_store_path
|
from wabot._sessions import default_store_path
|
||||||
|
|
||||||
assert default_store_path().name == "sessions.json"
|
assert default_store_path().name == "sessions.json"
|
||||||
assert "wabot" in str(default_store_path())
|
assert "wabot" in str(default_store_path())
|
||||||
@ -432,11 +432,11 @@ class TestSessionStore:
|
|||||||
- [ ] **Step 2: Run tests to verify they fail**
|
- [ ] **Step 2: Run tests to verify they fail**
|
||||||
|
|
||||||
Run: `uv run pytest tests/unit/test_sessions.py -v`
|
Run: `uv run pytest tests/unit/test_sessions.py -v`
|
||||||
Expected: FAIL — `ModuleNotFoundError: No module named 'wabot.sessions'`
|
Expected: FAIL — `ModuleNotFoundError: No module named 'wabot._sessions'`
|
||||||
|
|
||||||
- [ ] **Step 3: Write the implementation**
|
- [ ] **Step 3: Write the implementation**
|
||||||
|
|
||||||
`src/wabot/sessions.py`:
|
`src/wabot/_sessions.py`:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
"""Persistence of reattachable browser sessions as plain JSON.
|
"""Persistence of reattachable browser sessions as plain JSON.
|
||||||
@ -573,7 +573,7 @@ Expected: 14 passed
|
|||||||
- [ ] **Step 5: Commit**
|
- [ ] **Step 5: Commit**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add src/wabot/sessions.py tests/unit/test_sessions.py
|
git add src/wabot/_sessions.py tests/unit/test_sessions.py
|
||||||
git commit -m "feat: JSON SessionStore with stale eviction (replaces pickle persistence)"
|
git commit -m "feat: JSON SessionStore with stale eviction (replaces pickle persistence)"
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2773,7 +2773,7 @@ from unittest.mock import MagicMock
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import wabot
|
import wabot
|
||||||
from wabot.sessions import SessionRecord, SessionStore
|
from wabot import SessionRecord, SessionStore
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -3042,7 +3042,7 @@ from .hosts import (
|
|||||||
)
|
)
|
||||||
from .page import Page
|
from .page import Page
|
||||||
from .pacing import HumanPacing, NoPacing
|
from .pacing import HumanPacing, NoPacing
|
||||||
from .sessions import SessionRecord, SessionStore
|
from ._sessions import SessionRecord, SessionStore
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Browser",
|
"Browser",
|
||||||
@ -3282,7 +3282,7 @@ def site_url():
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def store(tmp_path):
|
def store(tmp_path):
|
||||||
from wabot.sessions import SessionStore
|
from wabot import SessionStore
|
||||||
|
|
||||||
return SessionStore(path=tmp_path / "sessions.json")
|
return SessionStore(path=tmp_path / "sessions.json")
|
||||||
```
|
```
|
||||||
@ -3422,7 +3422,7 @@ REATTACH_SCRIPT = textwrap.dedent(
|
|||||||
"""
|
"""
|
||||||
import json, sys
|
import json, sys
|
||||||
import wabot
|
import wabot
|
||||||
from wabot.sessions import SessionStore
|
from wabot import SessionStore
|
||||||
|
|
||||||
store = SessionStore(path=sys.argv[1])
|
store = SessionStore(path=sys.argv[1])
|
||||||
bot = wabot.browser(session=sys.argv[2], pacing=wabot.NoPacing(), store=store)
|
bot = wabot.browser(session=sys.argv[2], pacing=wabot.NoPacing(), store=store)
|
||||||
@ -3807,7 +3807,10 @@ API reference
|
|||||||
.. automodule:: wabot.pacing
|
.. automodule:: wabot.pacing
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. automodule:: wabot.sessions
|
.. autoclass:: wabot.SessionRecord
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: wabot.SessionStore
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. automodule:: wabot.hosts
|
.. automodule:: wabot.hosts
|
||||||
|
|||||||
@ -19,6 +19,7 @@ from selenium import webdriver
|
|||||||
from selenium.common.exceptions import WebDriverException
|
from selenium.common.exceptions import WebDriverException
|
||||||
|
|
||||||
from ._browser import Browser
|
from ._browser import Browser
|
||||||
|
from ._sessions import SessionRecord, SessionStore
|
||||||
from .fields import CheckField, NullField, PageObject, SelectField, TextField
|
from .fields import CheckField, NullField, PageObject, SelectField, TextField
|
||||||
from .hosts import (
|
from .hosts import (
|
||||||
ExternalServer,
|
ExternalServer,
|
||||||
@ -31,7 +32,6 @@ from .hosts import (
|
|||||||
)
|
)
|
||||||
from .pacing import HumanPacing, NoPacing
|
from .pacing import HumanPacing, NoPacing
|
||||||
from .page import Page
|
from .page import Page
|
||||||
from .sessions import SessionRecord, SessionStore
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Browser",
|
"Browser",
|
||||||
|
|||||||
@ -36,6 +36,6 @@ def site_url():
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def store(tmp_path):
|
def store(tmp_path):
|
||||||
from wabot.sessions import SessionStore
|
from wabot import SessionStore
|
||||||
|
|
||||||
return SessionStore(path=tmp_path / "sessions.json")
|
return SessionStore(path=tmp_path / "sessions.json")
|
||||||
|
|||||||
@ -15,7 +15,7 @@ REATTACH_SCRIPT = textwrap.dedent(
|
|||||||
"""
|
"""
|
||||||
import json, sys
|
import json, sys
|
||||||
import wabot
|
import wabot
|
||||||
from wabot.sessions import SessionStore
|
from wabot import SessionStore
|
||||||
|
|
||||||
store = SessionStore(path=sys.argv[1])
|
store = SessionStore(path=sys.argv[1])
|
||||||
bot = wabot.browser(session=sys.argv[2], pacing=wabot.NoPacing(), store=store)
|
bot = wabot.browser(session=sys.argv[2], pacing=wabot.NoPacing(), store=store)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from unittest.mock import MagicMock
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import wabot
|
import wabot
|
||||||
from wabot.sessions import SessionRecord, SessionStore
|
from wabot import SessionRecord, SessionStore
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
from wabot.sessions import SessionRecord, SessionStore
|
from wabot._sessions import SessionRecord, SessionStore
|
||||||
|
|
||||||
|
|
||||||
def make_record(name="scraper1", created_at=None):
|
def make_record(name="scraper1", created_at=None):
|
||||||
@ -63,7 +63,7 @@ class TestSessionStore:
|
|||||||
assert store.get("scraper1") is not None
|
assert store.get("scraper1") is not None
|
||||||
|
|
||||||
def test_default_path_is_under_platformdirs(self):
|
def test_default_path_is_under_platformdirs(self):
|
||||||
from wabot.sessions import default_store_path
|
from wabot._sessions import default_store_path
|
||||||
|
|
||||||
assert default_store_path().name == "sessions.json"
|
assert default_store_path().name == "sessions.json"
|
||||||
assert "wabot" in str(default_store_path())
|
assert "wabot" in str(default_store_path())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user