summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node')
-rw-r--r--packages/meshbay-node/src/meshbay_node/config.py4
-rw-r--r--packages/meshbay-node/src/meshbay_node/daemon.py42
-rw-r--r--packages/meshbay-node/src/meshbay_node/hub_client.py2
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/__init__.py4
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/enrich.py6
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/enrich_photo.py4
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/group_index.py19
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/indexer.py11
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/title_parse.py5
-rw-r--r--packages/meshbay-node/src/meshbay_node/keystore.py6
-rw-r--r--packages/meshbay-node/src/meshbay_node/ops.py10
-rw-r--r--packages/meshbay-node/src/meshbay_node/replication.py2
-rw-r--r--packages/meshbay-node/src/meshbay_node/revocation.py155
-rw-r--r--packages/meshbay-node/src/meshbay_node/roots.py4
-rw-r--r--packages/meshbay-node/src/meshbay_node/roster.py12
-rw-r--r--packages/meshbay-node/src/meshbay_node/transfers.py2
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/__init__.py4
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/quic_client.py7
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/quic_server.py11
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/tls_cert.py9
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py132
-rw-r--r--packages/meshbay-node/src/meshbay_node/ui/app.py2
-rw-r--r--packages/meshbay-node/src/meshbay_node/uploads.py2
-rw-r--r--packages/meshbay-node/tests/test_admin_ops_mnp.py5
-rw-r--r--packages/meshbay-node/tests/test_app_directories.py1
-rw-r--r--packages/meshbay-node/tests/test_app_directories_signed.py1
-rw-r--r--packages/meshbay-node/tests/test_apps_enabled_policy.py3
-rw-r--r--packages/meshbay-node/tests/test_audio_root_gates_enrichment.py3
-rw-r--r--packages/meshbay-node/tests/test_audio_transcode.py6
-rw-r--r--packages/meshbay-node/tests/test_chat_is_bounded.py1
-rw-r--r--packages/meshbay-node/tests/test_chat_multidevice.py3
-rw-r--r--packages/meshbay-node/tests/test_chat_pagination.py2
-rw-r--r--packages/meshbay-node/tests/test_chat_store.py3
-rw-r--r--packages/meshbay-node/tests/test_cli_dispatch.py3
-rw-r--r--packages/meshbay-node/tests/test_daemon.py13
-rw-r--r--packages/meshbay-node/tests/test_device_linking.py4
-rw-r--r--packages/meshbay-node/tests/test_enrich.py8
-rw-r--r--packages/meshbay-node/tests/test_enrich_photo.py6
-rw-r--r--packages/meshbay-node/tests/test_group_roster.py4
-rw-r--r--packages/meshbay-node/tests/test_hot_reload_survives_client_close.py10
-rw-r--r--packages/meshbay-node/tests/test_hub_client.py13
-rw-r--r--packages/meshbay-node/tests/test_hub_ws_group_claim.py1
-rw-r--r--packages/meshbay-node/tests/test_ice_filter.py2
-rw-r--r--packages/meshbay-node/tests/test_index_cache.py1
-rw-r--r--packages/meshbay-node/tests/test_index_delta_carries_roots.py2
-rw-r--r--packages/meshbay-node/tests/test_index_no_cleartext.py3
-rw-r--r--packages/meshbay-node/tests/test_index_progress.py7
-rw-r--r--packages/meshbay-node/tests/test_indexer.py20
-rw-r--r--packages/meshbay-node/tests/test_keystore.py6
-rw-r--r--packages/meshbay-node/tests/test_leaseless_reads.py5
-rw-r--r--packages/meshbay-node/tests/test_media_cache.py3
-rw-r--r--packages/meshbay-node/tests/test_media_cache_eviction.py1
-rw-r--r--packages/meshbay-node/tests/test_multi_group.py17
-rw-r--r--packages/meshbay-node/tests/test_musicbrainz_enabled_policy.py3
-rw-r--r--packages/meshbay-node/tests/test_node_status.py23
-rw-r--r--packages/meshbay-node/tests/test_packaging_win.py5
-rw-r--r--packages/meshbay-node/tests/test_partial_uploads.py20
-rw-r--r--packages/meshbay-node/tests/test_peer_session_limits.py6
-rw-r--r--packages/meshbay-node/tests/test_platform.py2
-rw-r--r--packages/meshbay-node/tests/test_poster_cache.py1
-rw-r--r--packages/meshbay-node/tests/test_quic_transport.py10
-rw-r--r--packages/meshbay-node/tests/test_rename_reenrichment.py3
-rw-r--r--packages/meshbay-node/tests/test_replug_restores_enrichment.py4
-rw-r--r--packages/meshbay-node/tests/test_root_availability.py2
-rw-r--r--packages/meshbay-node/tests/test_root_eject.py1
-rw-r--r--packages/meshbay-node/tests/test_root_ops_reach_the_live_set.py1
-rw-r--r--packages/meshbay-node/tests/test_root_paths_are_operator_only.py1
-rw-r--r--packages/meshbay-node/tests/test_root_writable_policy.py6
-rw-r--r--packages/meshbay-node/tests/test_roots.py12
-rw-r--r--packages/meshbay-node/tests/test_roster_pairing.py7
-rw-r--r--packages/meshbay-node/tests/test_scan_settings_policy.py1
-rw-r--r--packages/meshbay-node/tests/test_season_and_search_requests.py1
-rw-r--r--packages/meshbay-node/tests/test_security_regressions.py33
-rw-r--r--packages/meshbay-node/tests/test_startup_scan_enrichment.py5
-rw-r--r--packages/meshbay-node/tests/test_stream_audio_track_selection.py1
-rw-r--r--packages/meshbay-node/tests/test_stream_audio_transcode.py3
-rw-r--r--packages/meshbay-node/tests/test_stream_capacity.py9
-rw-r--r--packages/meshbay-node/tests/test_stream_capacity_config.py1
-rw-r--r--packages/meshbay-node/tests/test_stream_seek_audio_alignment.py1
-rw-r--r--packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py1
-rw-r--r--packages/meshbay-node/tests/test_stream_subtitle_tracks.py1
-rw-r--r--packages/meshbay-node/tests/test_stream_video_transcode.py1
-rw-r--r--packages/meshbay-node/tests/test_title_parse.py1
-rw-r--r--packages/meshbay-node/tests/test_tmdb.py1
-rw-r--r--packages/meshbay-node/tests/test_tmdb_config_policy.py3
-rw-r--r--packages/meshbay-node/tests/test_tmdb_enabled_policy.py3
-rw-r--r--packages/meshbay-node/tests/test_tmdb_language_fallback.py1
-rw-r--r--packages/meshbay-node/tests/test_tmdb_override_policy.py3
-rw-r--r--packages/meshbay-node/tests/test_tmdb_rematch_policy.py3
-rw-r--r--packages/meshbay-node/tests/test_tmdb_show_director.py1
-rw-r--r--packages/meshbay-node/tests/test_transfer_settings.py6
-rw-r--r--packages/meshbay-node/tests/test_transfer_slots.py14
-rw-r--r--packages/meshbay-node/tests/test_transfer_slots_wire.py7
-rw-r--r--packages/meshbay-node/tests/test_transport_wire_parity.py3
-rw-r--r--packages/meshbay-node/tests/test_upload_size_cap.py1
-rw-r--r--packages/meshbay-node/tests/test_video_root_gates_enrichment.py3
-rw-r--r--packages/meshbay-node/tests/test_webrtc_transport.py44
-rw-r--r--packages/meshbay-node/tests/test_windows_root_shapes.py1
-rw-r--r--packages/meshbay-node/tests/test_wizard_apps_endpoint.py4
-rwxr-xr-xpackages/meshbay-node/tests/transfer_probe.py12
100 files changed, 356 insertions, 532 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/config.py b/packages/meshbay-node/src/meshbay_node/config.py
index 2ae3c7c..437f629 100644
--- a/packages/meshbay-node/src/meshbay_node/config.py
+++ b/packages/meshbay-node/src/meshbay_node/config.py
@@ -14,9 +14,9 @@ from pathlib import Path
from meshbay_node.platform import config_dir, data_dir
try:
- import tomllib # Python 3.11+
+ import tomllib # Python 3.11+
except ImportError:
- import tomli as tomllib # type: ignore[no-redef]
+ import tomli as tomllib # type: ignore[no-redef]
log = logging.getLogger(__name__)
diff --git a/packages/meshbay-node/src/meshbay_node/daemon.py b/packages/meshbay-node/src/meshbay_node/daemon.py
index 3492d03..bb50bcf 100644
--- a/packages/meshbay-node/src/meshbay_node/daemon.py
+++ b/packages/meshbay-node/src/meshbay_node/daemon.py
@@ -25,43 +25,43 @@ Usage:
"""
import asyncio
-from dataclasses import asdict, replace
import base64
-import json
import logging
import os
import signal
import sys
import time
+from dataclasses import asdict, replace
from pathlib import Path
import uvicorn
-
+from meshbay_common import MNP_VERSION
from meshbay_common.background import spawn
from meshbay_common.paths import fold
-from meshbay_common import MNP_VERSION
from meshbay_common.protocol import MNP
-from meshbay_node.audit import RETENTION_DAYS as AUDIT_RETENTION_DAYS, AuditStore
+
+from meshbay_node import uploads as uploads_mod
+from meshbay_node.audit import RETENTION_DAYS as AUDIT_RETENTION_DAYS
+from meshbay_node.audit import AuditStore
from meshbay_node.bundle_store import BundleStore
from meshbay_node.chat.store import ChatStore
-from meshbay_node.config import Config, DEFAULT_CONFIG_PATH, load_config, write_example_config
-from meshbay_node.roots import RootSet, RootError, entry_abs_path, off_disk
+from meshbay_node.config import DEFAULT_CONFIG_PATH, Config, load_config
from meshbay_node.hub_client import HubClient, HubConfig
-from meshbay_node.indexer import DirectoryIndexer, IndexCache, GroupIndex
+from meshbay_node.indexer import DirectoryIndexer, GroupIndex, IndexCache
from meshbay_node.indexer.enrich import Enricher
from meshbay_node.indexer.enrich_audio import AudioEnricher
from meshbay_node.indexer.enrich_photo import PhotoEnricher
+from meshbay_node.keystore import create_keystore, load_keystore, load_or_create_keystore
from meshbay_node.media_cache import MediaCache
-from meshbay_node.tmdb import TmdbClient
-from meshbay_node import uploads as uploads_mod
from meshbay_node.musicbrainz import MusicBrainzClient
-from meshbay_node.keystore import create_keystore, load_keystore, load_or_create_keystore
from meshbay_node.platform import chmod_private, config_dir, data_dir, state_dir
+from meshbay_node.roots import RootError, RootSet, entry_abs_path, off_disk
from meshbay_node.roster import Roster
+from meshbay_node.tmdb import TmdbClient
from meshbay_node.transport import (
- Denylist,
QUIC_AVAILABLE,
WEBRTC_AVAILABLE,
+ Denylist,
)
from meshbay_node.transport.wire import index_delta_message, index_sync_message
@@ -109,8 +109,8 @@ def _owning_directory(path: str, directories: list[str]) -> str | None:
def calibrate_argon2(target_ms: int = 500) -> None:
"""Benchmark Argon2id and suggest parameters targeting ~target_ms."""
- import time
import os
+ import time
print(f"Calibrating Argon2id (target: {target_ms}ms) ...")
salt = os.urandom(16)
@@ -1938,8 +1938,7 @@ def _systemctl_user(verb: str, unit: str, *, not_running_hint: str,
def main() -> None:
import argparse
- from meshbay_node.platform import (configure_event_loop, force_utf8_stdio,
- load_node_env)
+ from meshbay_node.platform import configure_event_loop, force_utf8_stdio, load_node_env
force_utf8_stdio()
configure_event_loop()
# Before anything reads the environment. On Linux systemd has usually loaded
@@ -2164,10 +2163,10 @@ def main() -> None:
print("Aborted.")
return
- import subprocess as _sp
import json as _json
- import urllib.request
+ import subprocess as _sp
import urllib.error
+ import urllib.request
token_file = data_dir_ / "ui-token"
if token_file.exists():
@@ -2244,7 +2243,8 @@ def main() -> None:
_GUIDANCE = {
"node_key_link": (
"Link node key",
- f"Copy the node key above and paste it in Settings → Link Node on {cfg.hub.url}"),
+ f"Copy the node key above and paste it in "
+ f"Settings → Link Node on {cfg.hub.url}"),
"group_add": (
"Add a group",
"meshbay-node group add <name> --dir /path/to/files"),
@@ -2475,7 +2475,11 @@ def main() -> None:
if args.command == "restart-daemon":
if sys.platform == "win32":
from meshbay_node.platform import (
- autostart_end, autostart_run, service_end, service_run, service_status,
+ autostart_end,
+ autostart_run,
+ service_end,
+ service_run,
+ service_status,
)
if service_status()["installed"]:
service_end()
diff --git a/packages/meshbay-node/src/meshbay_node/hub_client.py b/packages/meshbay-node/src/meshbay_node/hub_client.py
index ef12bb4..58bf657 100644
--- a/packages/meshbay-node/src/meshbay_node/hub_client.py
+++ b/packages/meshbay-node/src/meshbay_node/hub_client.py
@@ -20,7 +20,7 @@ import logging
import time
from dataclasses import dataclass, field
from pathlib import Path
-from typing import Any, Callable
+from typing import Any
import httpx
import jwt
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/__init__.py b/packages/meshbay-node/src/meshbay_node/indexer/__init__.py
index c92c730..a40e9f2 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/__init__.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/__init__.py
@@ -1,6 +1,6 @@
"""Directory indexer and Mesh Group Index."""
-from .indexer import DirectoryIndexer
-from .group_index import GroupIndex
from .cache import IndexCache
+from .group_index import GroupIndex
+from .indexer import DirectoryIndexer
__all__ = ["DirectoryIndexer", "GroupIndex", "IndexCache"]
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/enrich.py b/packages/meshbay-node/src/meshbay_node/indexer/enrich.py
index b44a246..9881298 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/enrich.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/enrich.py
@@ -13,12 +13,12 @@ the rest asynchronously and hands the result back via a callback.
import asyncio
import logging
+from collections.abc import Awaitable, Callable
from pathlib import Path
-from typing import Awaitable, Callable
import blake3
-
from meshbay_common.protocol import IndexEntry
+
from meshbay_node.indexer import title_parse
from meshbay_node.indexer.indexer import MEDIA_EXTENSIONS
from meshbay_node.media_cache import MediaCache
@@ -173,7 +173,7 @@ async def _make_thumbnail(file_path: Path, duration: float | None) -> bytes | No
)
try:
stdout, _ = await asyncio.wait_for(proc.communicate(), THUMB_TIMEOUT_SECS)
- except asyncio.TimeoutError:
+ except TimeoutError:
proc.kill()
await proc.wait()
return None
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/enrich_photo.py b/packages/meshbay-node/src/meshbay_node/indexer/enrich_photo.py
index 6613f85..5cacef9 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/enrich_photo.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/enrich_photo.py
@@ -22,13 +22,13 @@ import asyncio
import datetime
import io
import logging
+from collections.abc import Awaitable, Callable
from pathlib import Path
-from typing import Awaitable, Callable
import blake3
+from meshbay_common.protocol import IndexEntry
from PIL import ExifTags, Image, ImageOps
-from meshbay_common.protocol import IndexEntry
from meshbay_node.media_cache import MediaCache
log = logging.getLogger(__name__)
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/group_index.py b/packages/meshbay-node/src/meshbay_node/indexer/group_index.py
index 2340c78..9e4e780 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/group_index.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/group_index.py
@@ -13,29 +13,27 @@ Delta format:
import base64
import logging
-import os
-import time
-from dataclasses import dataclass, field, asdict
-from pathlib import Path
-from typing import Iterator
+from dataclasses import asdict, dataclass, field
import blake3
import msgpack
import zstandard as zstd
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import (
+ pk_to_b64,
sign_chunk,
verify_chunk_signature,
- pk_to_b64,
- generate_gek,
)
+from meshbay_common.protocol import IndexDelta, IndexEntry
from meshbay_common.webcrypto import (
chunk_key_aes as derive_chunk_key,
- encrypt_chunk_aes as encrypt_chunk,
+)
+from meshbay_common.webcrypto import (
decrypt_chunk_aes as decrypt_chunk,
)
-from meshbay_common.protocol import IndexEntry, IndexDelta
+from meshbay_common.webcrypto import (
+ encrypt_chunk_aes as encrypt_chunk,
+)
log = logging.getLogger(__name__)
@@ -171,7 +169,6 @@ class GroupIndex:
) -> "GroupIndex":
"""Deserialize, verify signature, and decrypt (if private)."""
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
- from meshbay_common.crypto import verify_chunk_signature
envelope = msgpack.unpackb(data, raw=False)
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/indexer.py b/packages/meshbay-node/src/meshbay_node/indexer/indexer.py
index 3fe4f3e..4b619d7 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/indexer.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/indexer.py
@@ -25,19 +25,20 @@ it is the only thing that recovers a missed event.
import asyncio
import logging
import time
+from collections.abc import Awaitable, Callable
from concurrent.futures import ThreadPoolExecutor
-from dataclasses import dataclass, field as dataclass_field
+from dataclasses import dataclass
+from dataclasses import field as dataclass_field
from pathlib import Path
-from typing import Callable, Awaitable
import blake3
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
+from meshbay_common.background import spawn
+from meshbay_common.paths import find_fold_collisions, fold, long_path
+from meshbay_common.protocol import IndexEntry
from watchdog.events import FileSystemEvent, FileSystemEventHandler
from watchdog.observers import Observer
-from meshbay_common.background import spawn
-from meshbay_common.paths import fold, find_fold_collisions, long_path
-from meshbay_common.protocol import IndexEntry
from meshbay_node.indexer.cache import IndexCache
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roots import Root, RootSet, off_disk
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py
index 14728ff..91bf2bd 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py
@@ -19,7 +19,7 @@ directory listing; this module only parses strings it's handed.
from __future__ import annotations
import re
-from dataclasses import dataclass, field
+from dataclasses import dataclass
from guessit import guessit
@@ -218,7 +218,8 @@ class ParsedName:
year: int | None = None
season: int | None = None
episode: int | None = None
- confidence: bool = False # True only when display_title is set and structurally corroborated
+ # True only when display_title is set and structurally corroborated
+ confidence: bool = False
def parse_movie_filename(filename: str) -> ParsedName:
diff --git a/packages/meshbay-node/src/meshbay_node/keystore.py b/packages/meshbay-node/src/meshbay_node/keystore.py
index 00e504e..78fe122 100644
--- a/packages/meshbay-node/src/meshbay_node/keystore.py
+++ b/packages/meshbay-node/src/meshbay_node/keystore.py
@@ -38,8 +38,6 @@ from pathlib import Path
import msgpack
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-
-from meshbay_node.platform import chmod_private, config_dir
from meshbay_common.crypto import (
ARGON2_ITERATIONS,
ARGON2_LANES,
@@ -50,12 +48,12 @@ from meshbay_common.crypto import (
decrypt_keystore,
derive_keystore_key,
encrypt_keystore,
- generate_gek,
pk_to_b64,
sk_to_b64,
- sk_to_raw,
)
+from meshbay_node.platform import chmod_private, config_dir
+
log = logging.getLogger(__name__)
KEYSTORE_VERSION = 1
diff --git a/packages/meshbay-node/src/meshbay_node/ops.py b/packages/meshbay-node/src/meshbay_node/ops.py
index ca1b87d..baea365 100644
--- a/packages/meshbay-node/src/meshbay_node/ops.py
+++ b/packages/meshbay-node/src/meshbay_node/ops.py
@@ -24,8 +24,8 @@ from __future__ import annotations
import asyncio
import logging
-import time as _time
import re
+import time as _time
from dataclasses import asdict
from pathlib import Path
from typing import Any
@@ -37,8 +37,9 @@ from meshbay_common.crypto import (
unwrap_gek_aes,
wrap_gek_aes,
)
-from meshbay_node.config import DEFAULT_CONFIG_PATH
from meshbay_common.join import ROLE_MEMBER, ROLE_OPERATOR
+
+from meshbay_node.config import DEFAULT_CONFIG_PATH
from meshbay_node.roots import RootError, RootSet, off_disk
from meshbay_node.roster import Roster
@@ -951,6 +952,7 @@ async def remove_root(state: dict, group_id: str, root_name: str) -> dict:
raise OpError("Group not configured on this node", status=404)
from meshbay_common.paths import fold
+
from meshbay_node.roots import derive_name
target = fold(root_name)
match_idx = None
@@ -1001,6 +1003,7 @@ async def update_root(state: dict, group_id: str, root_name: str, *,
raise OpError("Group not configured on this node", status=404)
from meshbay_common.paths import fold
+
from meshbay_node.roots import RootSet
target = fold(root_name)
match = None
@@ -1462,8 +1465,7 @@ async def list_transfers(state: dict) -> dict:
ctx = getattr(webrtc, "_ctx", {}) if webrtc else {}
slots = ctx.get("_transfer_slots")
if slots is None:
- from meshbay_node.transfers import (
- DEFAULT_MAX_CONCURRENT, DEFAULT_MAX_PER_MEMBER, KINDS)
+ from meshbay_node.transfers import DEFAULT_MAX_CONCURRENT, DEFAULT_MAX_PER_MEMBER, KINDS
# No pool built means nothing has transferred since the daemon started,
# which is a real answer and not an error.
#
diff --git a/packages/meshbay-node/src/meshbay_node/replication.py b/packages/meshbay-node/src/meshbay_node/replication.py
index c2f5cd3..297ed0b 100644
--- a/packages/meshbay-node/src/meshbay_node/replication.py
+++ b/packages/meshbay-node/src/meshbay_node/replication.py
@@ -16,8 +16,6 @@ Usage:
await replicator.replicate_file(file_id, file_name, file_size)
"""
-import asyncio
-import hashlib
import logging
from pathlib import Path
diff --git a/packages/meshbay-node/src/meshbay_node/revocation.py b/packages/meshbay-node/src/meshbay_node/revocation.py
deleted file mode 100644
index d3ee18f..0000000
--- a/packages/meshbay-node/src/meshbay_node/revocation.py
+++ /dev/null
@@ -1,155 +0,0 @@
-"""
-MeshBay Node — revocation subscriber.
-
-Maintains a persistent WebSocket connection to the hub.
-When a signed revocation token arrives, verifies it (Ed25519)
-and adds the revoked target to the local blocklist.
-
-Usage in daemon:
- subscriber = RevocationSubscriber(hub_url, access_token, hub_pk_pem)
- await subscriber.start() # connects in background
- # check membership:
- if subscriber.is_revoked("user", user_id):
- refuse connection
- await subscriber.stop()
-"""
-
-import asyncio
-import json
-import logging
-import time
-from typing import Literal
-
-import httpx
-import jwt
-
-log = logging.getLogger(__name__)
-
-RevocationTarget = Literal["user", "group"]
-
-
-class RevocationSubscriber:
- """
- Background task that keeps a WebSocket connection to the hub
- and maintains a local revocation set.
- """
-
- def __init__(
- self,
- hub_url: str,
- access_token: str,
- hub_pk_pem: bytes,
- reconnect_delay: float = 5.0,
- ):
- self._hub_url = hub_url.rstrip("/")
- self._access_token = access_token
- self._hub_pk_pem = hub_pk_pem
- self._reconnect_delay = reconnect_delay
- self._revoked_users: set[str] = set()
- self._revoked_groups: set[str] = set()
- self._task: asyncio.Task | None = None
- self._running = False
-
- def is_revoked(self, target: RevocationTarget, target_id: str) -> bool:
- if target == "user":
- return target_id in self._revoked_users
- return target_id in self._revoked_groups
-
- def add_revocation(self, target: RevocationTarget, target_id: str) -> None:
- if target == "user":
- self._revoked_users.add(target_id)
- log.warning("User revoked locally: %s", target_id[:8])
- else:
- self._revoked_groups.add(target_id)
- log.warning("Group revoked locally: %s", target_id[:8])
-
- def verify_and_apply(self, token: str) -> bool:
- """Verify a revocation token and apply it. Returns True if valid."""
- try:
- from meshbay_common.handshake import JWT_LEEWAY_SECONDS
- payload = jwt.decode(token, self._hub_pk_pem, algorithms=["EdDSA"],
- leeway=JWT_LEEWAY_SECONDS,
- options={"verify_exp": False})
- if payload.get("type") != "revocation":
- return False
- target = payload["target"]
- target_id = payload["target_id"]
- self.add_revocation(target, target_id)
- return True
- except Exception as e:
- log.error("Invalid revocation token: %s", e)
- return False
-
- async def start(self) -> None:
- self._running = True
- self._task = asyncio.create_task(self._run_loop())
- log.info("RevocationSubscriber started")
-
- async def stop(self) -> None:
- self._running = False
- if self._task:
- self._task.cancel()
- try:
- await self._task
- except asyncio.CancelledError:
- pass
- log.info("RevocationSubscriber stopped")
-
- async def _run_loop(self) -> None:
- while self._running:
- try:
- await self._connect_and_listen()
- except asyncio.CancelledError:
- raise
- except Exception as e:
- log.warning("WS disconnected (%s), reconnecting in %ss", e, self._reconnect_delay)
- await asyncio.sleep(self._reconnect_delay)
-
- async def _connect_and_listen(self) -> None:
- ws_url = self._hub_url.replace("http://", "ws://").replace("https://", "wss://")
- ws_url += "/v1/nodes/ws"
-
- async with httpx.AsyncClient() as client:
- async with client.stream("GET", ws_url,
- headers={"Upgrade": "websocket"}) as resp:
- # Use websockets library for proper WS protocol
- pass
-
- # Use websockets library directly
- import websockets
- async with websockets.connect(ws_url) as ws:
- # Authenticate
- await ws.send(json.dumps({
- "type": "auth",
- "token": self._access_token,
- }))
- auth_resp = json.loads(await ws.recv())
- if auth_resp.get("type") != "auth_ok":
- raise ConnectionError(f"WS auth failed: {auth_resp}")
- log.info("WS connected to hub — node_id=%s", auth_resp.get("node_id", "?")[:8])
-
- # Listen for revocations + send keepalive pings
- ping_interval = 30.0
- last_ping = asyncio.get_event_loop().time()
-
- while self._running:
- now = asyncio.get_event_loop().time()
- if now - last_ping > ping_interval:
- await ws.send(json.dumps({"type": "ping"}))
- last_ping = now
-
- try:
- msg_raw = await asyncio.wait_for(ws.recv(), timeout=ping_interval + 5)
- msg = json.loads(msg_raw)
-
- if msg.get("type") == "revocation":
- token = msg.get("token", "")
- ok = self.verify_and_apply(token)
- log.info("Revocation received — valid=%s", ok)
- elif msg.get("type") == "pong":
- pass
- else:
- log.debug("WS message: %s", msg.get("type"))
-
- except asyncio.TimeoutError:
- continue
diff --git a/packages/meshbay-node/src/meshbay_node/roots.py b/packages/meshbay-node/src/meshbay_node/roots.py
index 67778ca..89b0441 100644
--- a/packages/meshbay-node/src/meshbay_node/roots.py
+++ b/packages/meshbay-node/src/meshbay_node/roots.py
@@ -71,7 +71,7 @@ def _free_name(directory: Path, filename: str) -> str:
raise FileExistsError(filename)
-def safe_subdir(roots: "RootSet", rel: str) -> Path | None:
+def safe_subdir(roots: RootSet, rel: str) -> Path | None:
"""
Resolve a client-supplied directory inside one of the group's roots, or refuse.
@@ -219,7 +219,7 @@ class RootSet:
# ── Construction ─────────────────────────────────────────────────────────
@classmethod
- def build(cls, specs: list[dict]) -> "RootSet":
+ def build(cls, specs: list[dict]) -> RootSet:
"""
Build from configuration, refusing anything ambiguous.
diff --git a/packages/meshbay-node/src/meshbay_node/roster.py b/packages/meshbay-node/src/meshbay_node/roster.py
index 8c9b3ef..9478a32 100644
--- a/packages/meshbay-node/src/meshbay_node/roster.py
+++ b/packages/meshbay-node/src/meshbay_node/roster.py
@@ -24,13 +24,11 @@ from __future__ import annotations
import hashlib
import json
import logging
-import os
import secrets
-from datetime import datetime, timedelta, timezone
+from datetime import UTC, datetime, timedelta
from pathlib import Path
import aiosqlite
-
from meshbay_common.paths import fold
log = logging.getLogger(__name__)
@@ -194,11 +192,11 @@ def hash_code(code: str) -> str:
def _now() -> str:
- return datetime.now(timezone.utc).isoformat(timespec="seconds")
+ return datetime.now(UTC).isoformat(timespec="seconds")
def _iso_in(seconds: int) -> str:
- return (datetime.now(timezone.utc)
+ return (datetime.now(UTC)
+ timedelta(seconds=seconds)).isoformat(timespec="seconds")
@@ -1073,7 +1071,7 @@ class Roster:
(group_id, user_id),
)
code = generate_code()
- expires = datetime.now(timezone.utc) + timedelta(seconds=ttl)
+ expires = datetime.now(UTC) + timedelta(seconds=ttl)
await self._db.execute(
"INSERT INTO invites (code_hash, group_id, user_id, username, role, "
"created_by, created_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
@@ -1106,7 +1104,7 @@ class Roster:
# redeemed by whoever finds it first.
if invite["user_id"] != user_id:
return None
- if datetime.fromisoformat(invite["expires_at"]) < datetime.now(timezone.utc):
+ if datetime.fromisoformat(invite["expires_at"]) < datetime.now(UTC):
return None
cur = await self._db.execute(
diff --git a/packages/meshbay-node/src/meshbay_node/transfers.py b/packages/meshbay-node/src/meshbay_node/transfers.py
index 86c8d14..3345cb9 100644
--- a/packages/meshbay-node/src/meshbay_node/transfers.py
+++ b/packages/meshbay-node/src/meshbay_node/transfers.py
@@ -393,7 +393,7 @@ class TransferSlots:
# the one place it would be tempting to add one for a prettier
# log line.
for x in sorted(self.leases.values(),
- key=lambda l: (l.kind, l.state, l.created_at))
+ key=lambda ls: (ls.kind, ls.state, ls.created_at))
],
}
diff --git a/packages/meshbay-node/src/meshbay_node/transport/__init__.py b/packages/meshbay-node/src/meshbay_node/transport/__init__.py
index e423e35..86dbf23 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/__init__.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/__init__.py
@@ -15,8 +15,8 @@ Transport decision (2026-08-13, second security review):
# QUIC transport (MNP v2) — requires aioquic>=1.0
try:
- from .quic_server import QuicChunkServer, Denylist
from .quic_client import QuicChunkClient
+ from .quic_server import Denylist, QuicChunkServer
QUIC_AVAILABLE = True
except ImportError:
QuicChunkServer = None # type: ignore[assignment,misc]
@@ -26,7 +26,7 @@ except ImportError:
# WebRTC transport (browsers + native clients) — requires aiortc>=1.9
try:
- from .webrtc_server import WebRTCTransport, WebRTCPeerSession
+ from .webrtc_server import WebRTCPeerSession, WebRTCTransport
WEBRTC_AVAILABLE = True
except ImportError:
WebRTCTransport = None # type: ignore[assignment,misc]
diff --git a/packages/meshbay-node/src/meshbay_node/transport/quic_client.py b/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
index af87b70..273f225 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
@@ -13,18 +13,14 @@ import base64
import logging
import os
import struct
-from pathlib import Path
-import jwt
import msgpack
-from aioquic.asyncio import connect, QuicConnectionProtocol
+from aioquic.asyncio import QuicConnectionProtocol, connect
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import QuicEvent, StreamDataReceived
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
-
from meshbay_common import MNP_VERSION
from meshbay_common.groupbox import PURPOSE_ACK, PURPOSE_INDEX, unseal
-from meshbay_common.protocol import MNP, file_chunk_plaintext
from meshbay_common.handshake import (
MNP_MIN_SUPPORTED,
NONCE_LEN,
@@ -36,6 +32,7 @@ from meshbay_common.handshake import (
quic_binding,
verify_proof,
)
+from meshbay_common.protocol import MNP, file_chunk_plaintext
def _peer_cert_der(proto) -> bytes | None:
diff --git a/packages/meshbay-node/src/meshbay_node/transport/quic_server.py b/packages/meshbay-node/src/meshbay_node/transport/quic_server.py
index 2a2b07a..036574b 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/quic_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/quic_server.py
@@ -24,17 +24,16 @@ import os
import struct
import uuid
from pathlib import Path
-from typing import Any, Callable
+from typing import Any
-import jwt
import msgpack
from aioquic.asyncio import QuicConnectionProtocol, serve
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import QuicEvent, StreamDataReceived, StreamReset
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common import MNP_VERSION
-from meshbay_node.roots import ROOT_NOT_SERVED, RootSet, entry_abs_path
+from meshbay_common.crypto import pk_to_b64
+from meshbay_common.groupbox import PURPOSE_ACK, seal
from meshbay_common.handshake import (
MNP_MIN_SUPPORTED,
NONCE_LEN,
@@ -48,10 +47,10 @@ from meshbay_common.handshake import (
quic_binding,
verify_proof,
)
-from meshbay_common.crypto import pk_to_b64
-from meshbay_common.groupbox import PURPOSE_ACK, seal
from meshbay_common.protocol import MNP, file_chunk_wire
+
from meshbay_node.indexer import GroupIndex
+from meshbay_node.roots import ROOT_NOT_SERVED, RootSet, entry_abs_path
from meshbay_node.transport.wire import index_sync_message
log = logging.getLogger(__name__)
diff --git a/packages/meshbay-node/src/meshbay_node/transport/tls_cert.py b/packages/meshbay-node/src/meshbay_node/transport/tls_cert.py
index 8d680ea..cfc93c7 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/tls_cert.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/tls_cert.py
@@ -10,11 +10,10 @@ the QUIC handshake proof (11.5.6), since QUIC has no DTLS fingerprint to bind to
Certificate is generated once and cached at ~/.config/meshbay/node_tls.crt/.key.
"""
-import logging
-import os
-from pathlib import Path
import datetime
import ipaddress
+import logging
+from pathlib import Path
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
@@ -47,8 +46,8 @@ def generate_self_signed_cert(
.issuer_name(issuer)
.public_key(rsa_key.public_key())
.serial_number(x509.random_serial_number())
- .not_valid_before(datetime.datetime.now(datetime.timezone.utc))
- .not_valid_after(datetime.datetime.now(datetime.timezone.utc)
+ .not_valid_before(datetime.datetime.now(datetime.UTC))
+ .not_valid_after(datetime.datetime.now(datetime.UTC)
+ datetime.timedelta(days=3650))
.add_extension(
x509.SubjectAlternativeName([
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
index 8a5bbff..e92ec13 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py
@@ -25,8 +25,6 @@ Signaling flow (handled externally by the hub):
import asyncio
import base64
import contextvars
-import hashlib
-import hmac
import logging
import os
import re
@@ -38,63 +36,53 @@ from pathlib import Path
from typing import Any
import blake3
-import jwt
import msgpack
-from aiortc import RTCPeerConnection, RTCSessionDescription, RTCDataChannel
+from aiortc import RTCDataChannel, RTCPeerConnection, RTCSessionDescription
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey,
Ed25519PublicKey,
)
-
from meshbay_common import MNP_VERSION
-from meshbay_common.handshake import (
- MNP_MIN_SUPPORTED,
- NONCE_LEN,
- ROLE_CLIENT,
- ROLE_NODE,
- HandshakeError,
- authorize_token,
- check_version,
- handshake_transcript,
- make_proof,
- verify_proof,
- webrtc_binding,
-)
from meshbay_common.adminop import (
ADMIN_CHALLENGE_TTL,
+ OP_APP_DIRECTORIES,
+ OP_APPS_ENABLED,
+ OP_CHAT_DIRECTORY,
+ OP_CHAT_EPOCH,
+ OP_CHAT_LINK_PREVIEW,
OP_DIR_DELETE,
OP_FILE_DELETE,
+ OP_GEK_ROTATE,
+ OP_GROUP_ATTACH,
+ OP_GROUP_DETACH,
OP_INVITE_CREATE,
OP_MEMBER_REVOKE,
- OP_GEK_ROTATE,
OP_MEMBER_UNPIN,
- OP_APPS_ENABLED,
+ OP_MUSICBRAINZ_ENABLED,
+ OP_ROOT_ADD,
+ OP_ROOT_EJECT,
+ OP_ROOT_PLUG,
+ OP_ROOT_REMOVE,
+ OP_ROOT_UPDATE,
+ OP_SEARCH_LISTED,
OP_SET_SCAN_SETTINGS,
- OP_TRANSFER_LIMITS,
OP_TMDB_CONFIG,
OP_TMDB_ENABLED,
OP_TMDB_OVERRIDE,
OP_TMDB_REMATCH,
- OP_MUSICBRAINZ_ENABLED,
- OP_APP_DIRECTORIES,
- OP_CHAT_DIRECTORY,
- OP_CHAT_EPOCH,
- OP_CHAT_LINK_PREVIEW,
- OP_SEARCH_LISTED,
- OP_ROOT_ADD,
- OP_ROOT_REMOVE,
- OP_ROOT_UPDATE,
- OP_ROOT_EJECT,
- OP_ROOT_PLUG,
- OP_GROUP_ATTACH,
- OP_GROUP_DETACH,
+ OP_TRANSFER_LIMITS,
admin_transcript,
)
+from meshbay_common.chatbox import (
+ NONCE_LEN as CHAT_NONCE_LEN,
+)
+from meshbay_common.chatbox import (
+ SIG_LEN as CHAT_SIG_LEN,
+)
from meshbay_common.crypto import pk_to_b64, wrap_gek_aes
from meshbay_common.device import (
DEVICE_TTL,
device_add_transcript,
- device_code_hash,
device_hello_transcript,
device_request_transcript,
)
@@ -104,44 +92,62 @@ from meshbay_common.groupbox import (
PURPOSE_ROSTER,
seal,
)
+from meshbay_common.handshake import (
+ MNP_MIN_SUPPORTED,
+ NONCE_LEN,
+ ROLE_CLIENT,
+ ROLE_NODE,
+ HandshakeError,
+ authorize_token,
+ check_version,
+ handshake_transcript,
+ make_proof,
+ verify_proof,
+ webrtc_binding,
+)
from meshbay_common.join import (
JOIN_TTL,
ROLE_MEMBER,
ROLE_OPERATOR,
join_transcript,
)
-from meshbay_common.chatbox import (
- NONCE_LEN as CHAT_NONCE_LEN,
- SIG_LEN as CHAT_SIG_LEN,
-)
from meshbay_common.protocol import (
MNP,
+ UPLOAD_PROBE_INDEX,
chunk_ciphertext,
file_chunk_wire,
- UPLOAD_PROBE_INDEX,
file_upload_ack_wire,
file_upload_payload,
)
-from meshbay_node.chat import FORMAT_SEALED_V1, ReplayedMessage
-from meshbay_node.transport.wire import index_sync_message
-from meshbay_node.indexer import GroupIndex
-from meshbay_node.indexer.indexer import DirectoryIndexer
+
from meshbay_node import hwaccel, linkpreview, ops, platform
from meshbay_node import transfers as transfers_mod
from meshbay_node import uploads as uploads_mod
-from meshbay_node.transfers import TransferSlots
+from meshbay_node.chat import FORMAT_SEALED_V1, ReplayedMessage
+from meshbay_node.indexer import GroupIndex
+from meshbay_node.indexer.indexer import DirectoryIndexer
+
# Re-imported under its original name: every call site and existing test in
# this module still refers to it as `_probe_video`. The implementation lives
# in media_probe.py so the indexer package (imported just above) can call it
# too, for index-time enrichment, without a circular import.
from meshbay_node.media_probe import (
BROWSER_INCOMPATIBLE_VIDEO_CODECS,
+)
+from meshbay_node.media_probe import (
probe_video as _probe_video,
)
from meshbay_node.roots import (
- ROOT_NOT_SERVED, RootSet, entry_abs_path, off_disk, SAFE_UPLOAD_NAME, safe_subdir,
+ ROOT_NOT_SERVED,
+ SAFE_UPLOAD_NAME,
+ RootSet,
_free_name,
+ entry_abs_path,
+ off_disk,
+ safe_subdir,
)
+from meshbay_node.transfers import TransferSlots
+from meshbay_node.transport.wire import index_sync_message
log = logging.getLogger(__name__)
@@ -3924,7 +3930,8 @@ class WebRTCPeerSession:
if not entry:
thumb = await self._try_serve_thumbnail(file_id, chunk_index, ctx.get("gek"))
if thumb is not None:
- log.debug("file_req file_id=%s chunk=%s: served as thumbnail", file_id[:16], chunk_index)
+ log.debug("file_req file_id=%s chunk=%s: served as thumbnail",
+ file_id[:16], chunk_index)
self._send(thumb)
return
log.warning("File not found: %s", file_id[:16])
@@ -3992,7 +3999,8 @@ class WebRTCPeerSession:
self._leaseless.finish(str(file_id))
@staticmethod
- async def _fetch_and_cache_poster(media_cache, tmdb_client, poster_path: str | None) -> str | None:
+ async def _fetch_and_cache_poster(media_cache, tmdb_client,
+ poster_path: str | None) -> str | None:
"""
Downloads a TMDB poster/backdrop once, caches it under its own
blake3 like a video thumbnail (docs/MESHBAY_DESIGN.md §9.7), and
@@ -4020,7 +4028,8 @@ class WebRTCPeerSession:
return thumb_hash
@staticmethod
- async def _fetch_and_cache_cover(media_cache, musicbrainz_client, mbid: str | None) -> str | None:
+ async def _fetch_and_cache_cover(media_cache, musicbrainz_client,
+ mbid: str | None) -> str | None:
"""
Music app equivalent of `_fetch_and_cache_poster` — a release's
Cover Art Archive image, fetched once per mbid and cached under its
@@ -4504,7 +4513,9 @@ class WebRTCPeerSession:
# itself.
if not fetched.get("overview"):
fallback = await tmdb_client.tv_season(tmdb_id, season, language="en-US") or {}
- fetched = {**fallback, **{k: v for k, v in fetched.items() if v not in (None, "", [])}}
+ fetched = {**fallback,
+ **{k: v for k, v in fetched.items()
+ if v not in (None, "", [])}}
await media_cache.set_season_meta(tmdb_id, season, fetched)
details = fetched
@@ -4833,8 +4844,10 @@ class WebRTCPeerSession:
# back to English per field rather than discarding an otherwise-good
# localized response over one empty one — mirrored here the same
# way, at field granularity, not by abandoning the whole response.
- if not details.get("overview") or not details.get("poster_path") or not details.get("genres"):
- fallback = (await tmdb_client.tv_details(tmdb_id, language="en-US") if media_type == "tv"
+ if (not details.get("overview") or not details.get("poster_path")
+ or not details.get("genres")):
+ fallback = (await tmdb_client.tv_details(tmdb_id, language="en-US")
+ if media_type == "tv"
else await tmdb_client.movie_details(tmdb_id, language="en-US")) or {}
details = {**fallback, **{k: v for k, v in details.items() if v not in (None, "", [])}}
credits = (await tmdb_client.tv_credits(tmdb_id) if media_type == "tv"
@@ -5909,7 +5922,8 @@ class WebRTCPeerSession:
transcript = admin_transcript(
op=pending["op"],
node_pk_b64=self._node_pk_b64(),
- group_id=pending["group_id"] if pending.get("group_id") is not None else (self._group_id or ""),
+ group_id=(pending["group_id"] if pending.get("group_id") is not None
+ else (self._group_id or "")),
subject=pending["subject"],
nonce=pending["nonce"],
ts=pending["ts"],
@@ -6160,7 +6174,7 @@ class WebRTCPeerSession:
# total budget is unchanged.
await asyncio.wait_for(self._stream_credit_evt.wait(),
timeout=STREAM_CREDIT_POLL)
- except asyncio.TimeoutError:
+ except TimeoutError:
silent = time.monotonic() - self._stream_heard_at
if silent >= STREAM_CREDIT_TIMEOUT:
log.info("Stream stalled: nothing from peer=%s for %.0fs",
@@ -6208,7 +6222,7 @@ class WebRTCPeerSession:
await asyncio.wait_for(asyncio.shield(prev), timeout=15)
log.info("stream: previous stream ended in %.1fs",
time.monotonic() - t0)
- except asyncio.TimeoutError:
+ except TimeoutError:
log.warning("stream: previous stream STILL RUNNING after 15s")
except Exception:
pass # it failed on its own; the slot is free either way
@@ -6851,7 +6865,7 @@ async def _transcode_audio_to_aac(file_path: Path) -> bytes:
try:
_, stderr = await asyncio.wait_for(
proc.communicate(), timeout=AUDIO_TRANSCODE_TIMEOUT_SECS)
- except asyncio.TimeoutError:
+ except TimeoutError:
proc.kill()
await proc.wait()
raise RuntimeError(f"ffmpeg timed out after {AUDIO_TRANSCODE_TIMEOUT_SECS}s")
@@ -6912,7 +6926,7 @@ async def _seek_lands_at(file_path: Path, t: float, map_args: list[str]) -> floa
)
stdout, _ = await asyncio.wait_for(
probe.communicate(), timeout=SEEK_PROBE_TIMEOUT_SECS)
- except (asyncio.TimeoutError, OSError) as e:
+ except (TimeoutError, OSError) as e:
log.warning("stream: seek probe failed at %.1fs: %r", t, e)
return None
finally:
@@ -6967,7 +6981,7 @@ async def _extract_subtitle_to_webvtt(file_path: Path, ordinal: int,
try:
_, stderr = await asyncio.wait_for(
proc.communicate(), timeout=timeout)
- except asyncio.TimeoutError:
+ except TimeoutError:
proc.kill()
await proc.wait()
raise RuntimeError(f"ffmpeg timed out after {timeout:.0f}s")
@@ -7152,7 +7166,7 @@ class WebRTCTransport:
Returns (answer_sdp, ice_candidates) to relay back via hub signaling.
ICE candidates are embedded in the SDP (aiortc gathers before returning).
"""
- from aiortc import RTCIceServer, RTCConfiguration
+ from aiortc import RTCConfiguration, RTCIceServer
# aiortc keeps only the first STUN entry it sees here; the actual
# multi-server fan-out is done by transport/stun_multi, which patches
diff --git a/packages/meshbay-node/src/meshbay_node/ui/app.py b/packages/meshbay-node/src/meshbay_node/ui/app.py
index 77491a0..888487c 100644
--- a/packages/meshbay-node/src/meshbay_node/ui/app.py
+++ b/packages/meshbay-node/src/meshbay_node/ui/app.py
@@ -16,8 +16,8 @@ import logging
from fastapi import FastAPI, HTTPException, Query
from fastapi.responses import JSONResponse
-
from meshbay_common.background import spawn
+
from meshbay_node import __version__, ops
from meshbay_node.indexer.indexer import DirectoryIndexer
diff --git a/packages/meshbay-node/src/meshbay_node/uploads.py b/packages/meshbay-node/src/meshbay_node/uploads.py
index f8ae7f9..dd31e1e 100644
--- a/packages/meshbay-node/src/meshbay_node/uploads.py
+++ b/packages/meshbay-node/src/meshbay_node/uploads.py
@@ -25,9 +25,9 @@ build first.
from __future__ import annotations
import time
+from collections.abc import Iterable
from dataclasses import dataclass, field
from pathlib import Path
-from typing import Iterable
# What an unfinished upload is called on disk while it is being written. The
# node has always used this; it is named here because the reaper below has to
diff --git a/packages/meshbay-node/tests/test_admin_ops_mnp.py b/packages/meshbay-node/tests/test_admin_ops_mnp.py
index 92e50b5..7fd1c2b 100644
--- a/packages/meshbay-node/tests/test_admin_ops_mnp.py
+++ b/packages/meshbay-node/tests/test_admin_ops_mnp.py
@@ -15,13 +15,10 @@ thing that finishes a revocation: the ex-member still holds the current key.
"""
import base64
-import time
from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
-from conftest import one_root
from meshbay_common.adminop import (
OP_GEK_ROTATE,
OP_MEMBER_UNPIN,
@@ -34,6 +31,8 @@ from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import open_roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root
+
GROUP = "g" * 32
diff --git a/packages/meshbay-node/tests/test_app_directories.py b/packages/meshbay-node/tests/test_app_directories.py
index 726f5bd..955a769 100644
--- a/packages/meshbay-node/tests/test_app_directories.py
+++ b/packages/meshbay-node/tests/test_app_directories.py
@@ -26,7 +26,6 @@ from types import SimpleNamespace
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.adminop import OP_APP_DIRECTORIES
from meshbay_node import ops
from meshbay_node.indexer.group_index import GroupIndex
diff --git a/packages/meshbay-node/tests/test_app_directories_signed.py b/packages/meshbay-node/tests/test_app_directories_signed.py
index eda09d8..af362a1 100644
--- a/packages/meshbay-node/tests/test_app_directories_signed.py
+++ b/packages/meshbay-node/tests/test_app_directories_signed.py
@@ -24,7 +24,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.adminop import OP_APP_DIRECTORIES, admin_transcript
from meshbay_common.crypto import pk_to_b64
from meshbay_common.join import ROLE_OPERATOR
diff --git a/packages/meshbay-node/tests/test_apps_enabled_policy.py b/packages/meshbay-node/tests/test_apps_enabled_policy.py
index 40c7cc8..1fa3d5c 100644
--- a/packages/meshbay-node/tests/test_apps_enabled_policy.py
+++ b/packages/meshbay-node/tests/test_apps_enabled_policy.py
@@ -13,12 +13,11 @@ way an unsigned upload is refused, so the check has to happen up front.
from pathlib import Path
import pytest
-
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.adminop import OP_APPS_ENABLED
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import Roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from conftest import one_root
diff --git a/packages/meshbay-node/tests/test_audio_root_gates_enrichment.py b/packages/meshbay-node/tests/test_audio_root_gates_enrichment.py
index 251617c..b8c4dd6 100644
--- a/packages/meshbay-node/tests/test_audio_root_gates_enrichment.py
+++ b/packages/meshbay-node/tests/test_audio_root_gates_enrichment.py
@@ -17,10 +17,9 @@ import os
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_node import ops
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.indexer.enrich_audio import AudioEnricher
diff --git a/packages/meshbay-node/tests/test_audio_transcode.py b/packages/meshbay-node/tests/test_audio_transcode.py
index a6557f0..acb39b7 100644
--- a/packages/meshbay-node/tests/test_audio_transcode.py
+++ b/packages/meshbay-node/tests/test_audio_transcode.py
@@ -145,7 +145,8 @@ async def test_missing_file_id_is_an_error(tmp_path, media_cache):
sk_node = Ed25519PrivateKey.generate()
session = WebRTCPeerSession.__new__(WebRTCPeerSession)
session._ctx = {
- "roots": one_root(tmp_path), "index": GroupIndex(group_id="g" * 32, sk_node=sk_node, gek=gek),
+ "roots": one_root(tmp_path),
+ "index": GroupIndex(group_id="g" * 32, sk_node=sk_node, gek=gek),
"gek": gek, "sk_node": sk_node, "media_cache": media_cache,
}
session._group_id = None
@@ -170,7 +171,8 @@ async def test_multi_chunk_cached_blob_reassembles_correctly(tmp_path, media_cac
sk_node = Ed25519PrivateKey.generate()
session = WebRTCPeerSession.__new__(WebRTCPeerSession)
session._ctx = {
- "roots": one_root(tmp_path), "index": GroupIndex(group_id="g" * 32, sk_node=sk_node, gek=gek),
+ "roots": one_root(tmp_path),
+ "index": GroupIndex(group_id="g" * 32, sk_node=sk_node, gek=gek),
"gek": gek, "sk_node": sk_node, "media_cache": media_cache,
}
session._group_id = None
diff --git a/packages/meshbay-node/tests/test_chat_is_bounded.py b/packages/meshbay-node/tests/test_chat_is_bounded.py
index 4e767bc..5dc1128 100644
--- a/packages/meshbay-node/tests/test_chat_is_bounded.py
+++ b/packages/meshbay-node/tests/test_chat_is_bounded.py
@@ -33,7 +33,6 @@ import os
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.chatbox import NONCE_LEN, SIG_LEN
from meshbay_common.crypto import pk_to_b64
from meshbay_node.chat import FORMAT_SEALED_V1, ChatStore
diff --git a/packages/meshbay-node/tests/test_chat_multidevice.py b/packages/meshbay-node/tests/test_chat_multidevice.py
index bb61285..058544a 100644
--- a/packages/meshbay-node/tests/test_chat_multidevice.py
+++ b/packages/meshbay-node/tests/test_chat_multidevice.py
@@ -16,10 +16,9 @@ account where it should be keyed by connection" mistake as `pin_identity`'s
old INSERT OR REPLACE.
"""
-from pathlib import Path
-
import base64
import hashlib
+from pathlib import Path
from aiortc import RTCPeerConnection
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
diff --git a/packages/meshbay-node/tests/test_chat_pagination.py b/packages/meshbay-node/tests/test_chat_pagination.py
index caf1f73..f3949a9 100644
--- a/packages/meshbay-node/tests/test_chat_pagination.py
+++ b/packages/meshbay-node/tests/test_chat_pagination.py
@@ -13,12 +13,10 @@ The cursor is the row id rather than the timestamp. `timestamp` is a float from
timestamp cursor would then skip a message or return it twice.
"""
-import asyncio
from pathlib import Path
import pytest
import pytest_asyncio
-
from meshbay_node.chat.store import ChatStore
diff --git a/packages/meshbay-node/tests/test_chat_store.py b/packages/meshbay-node/tests/test_chat_store.py
index d74310d..2533921 100644
--- a/packages/meshbay-node/tests/test_chat_store.py
+++ b/packages/meshbay-node/tests/test_chat_store.py
@@ -2,10 +2,9 @@
Tests for the SQLite-backed chat message store.
"""
+
import pytest
import pytest_asyncio
-from pathlib import Path
-
from meshbay_node.chat.store import ChatStore
diff --git a/packages/meshbay-node/tests/test_cli_dispatch.py b/packages/meshbay-node/tests/test_cli_dispatch.py
index ad60b91..cf2fd6e 100644
--- a/packages/meshbay-node/tests/test_cli_dispatch.py
+++ b/packages/meshbay-node/tests/test_cli_dispatch.py
@@ -14,10 +14,8 @@ branch nobody ever ran.
"""
import sys
-from pathlib import Path
import pytest
-
from meshbay_node import daemon as daemon_mod
# Each verb, with the arguments that reach its branch. `--yes` where the command
@@ -155,7 +153,6 @@ def test_the_verb_list_here_matches_the_parser():
A verb added to the parser and not to this file would go untested, which is
exactly how `reload` shipped broken.
"""
- import argparse
import inspect
source = inspect.getsource(daemon_mod.main)
diff --git a/packages/meshbay-node/tests/test_daemon.py b/packages/meshbay-node/tests/test_daemon.py
index 8bd169d..8c4da2d 100644
--- a/packages/meshbay-node/tests/test_daemon.py
+++ b/packages/meshbay-node/tests/test_daemon.py
@@ -9,20 +9,21 @@ Hub interaction is mocked.
import asyncio
import base64
import os
+from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-from unittest.mock import AsyncMock, MagicMock, patch
-
from meshbay_common.crypto import generate_gek
from meshbay_common.groupbox import PURPOSE_INDEX, unseal
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
-from conftest import one_root
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
+from conftest import one_root
+
+
def _mock_keystore_keys(sk_ed):
"""Create a mock keystore with real Ed25519 + X25519 key material."""
sk_x = X25519PrivateKey.generate()
@@ -125,7 +126,7 @@ async def test_daemon_creates_chat_store(tmp_path, node_config, gek, hub_pk_pem)
patch("signal.SIGTERM", 15):
try:
await asyncio.wait_for(daemon.run(), timeout=5)
- except (asyncio.TimeoutError, Exception):
+ except (TimeoutError, Exception):
pass
task = asyncio.create_task(run_daemon())
@@ -204,7 +205,7 @@ async def test_daemon_no_groups_stays_up(tmp_path, hub_pk_pem):
patch("signal.SIGTERM", 15):
try:
await asyncio.wait_for(daemon.run(), timeout=5)
- except (asyncio.TimeoutError, Exception):
+ except (TimeoutError, Exception):
pass
task = asyncio.create_task(run_daemon())
diff --git a/packages/meshbay-node/tests/test_device_linking.py b/packages/meshbay-node/tests/test_device_linking.py
index 6d50580..53387ca 100644
--- a/packages/meshbay-node/tests/test_device_linking.py
+++ b/packages/meshbay-node/tests/test_device_linking.py
@@ -25,8 +25,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
-from conftest import one_root
from meshbay_common.crypto import pk_to_b64
from meshbay_common.device import (
device_add_transcript,
@@ -39,6 +37,8 @@ from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import generate_code, normalize_code, open_roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root
+
GROUP = "g" * 32
NONCE = b"\x11" * 32
diff --git a/packages/meshbay-node/tests/test_enrich.py b/packages/meshbay-node/tests/test_enrich.py
index e059bbe..ca03392 100644
--- a/packages/meshbay-node/tests/test_enrich.py
+++ b/packages/meshbay-node/tests/test_enrich.py
@@ -3,15 +3,15 @@
import asyncio
import shutil
import subprocess
-from pathlib import Path
-
import sys
+from pathlib import Path
import pytest
-
from meshbay_common.protocol import IndexEntry
from meshbay_node.indexer.enrich import (
- Enricher, _season_and_show_from_ancestors, _synthetic_episode_number,
+ Enricher,
+ _season_and_show_from_ancestors,
+ _synthetic_episode_number,
_title_from_siblings,
)
from meshbay_node.media_cache import MediaCache
diff --git a/packages/meshbay-node/tests/test_enrich_photo.py b/packages/meshbay-node/tests/test_enrich_photo.py
index 81367eb..d1bbd28 100644
--- a/packages/meshbay-node/tests/test_enrich_photo.py
+++ b/packages/meshbay-node/tests/test_enrich_photo.py
@@ -6,11 +6,10 @@ from pathlib import Path
import piexif
import pytest
-from PIL import Image
-
from meshbay_common.protocol import IndexEntry
from meshbay_node.indexer.enrich_photo import PhotoEnricher
from meshbay_node.media_cache import MediaCache
+from PIL import Image
@pytest.fixture
@@ -167,7 +166,8 @@ async def test_enricher_corrects_orientation(tmp_path, media_cache):
"width/height must reflect the EXIF-corrected orientation, not the raw stored frame")
thumb_bytes = await media_cache.get_thumb(fields["thumb_hash"])
thumb = Image.open(io.BytesIO(thumb_bytes))
- assert thumb.size[0] < thumb.size[1], "the stored thumbnail itself must be portrait, not sideways"
+ assert thumb.size[0] < thumb.size[1], (
+ "the stored thumbnail itself must be portrait, not sideways")
def test_gps_is_never_read_by_this_module():
diff --git a/packages/meshbay-node/tests/test_group_roster.py b/packages/meshbay-node/tests/test_group_roster.py
index a41cce2..74908e7 100644
--- a/packages/meshbay-node/tests/test_group_roster.py
+++ b/packages/meshbay-node/tests/test_group_roster.py
@@ -23,8 +23,6 @@ import time
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
-from conftest import one_root
from meshbay_common.crypto import generate_gek, pk_to_b64
from meshbay_common.device import device_add_transcript
from meshbay_common.groupbox import PURPOSE_ROSTER, unseal
@@ -34,6 +32,8 @@ from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import open_roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root
+
GROUP = "g" * 32
NONCE = b"\x11" * 32
diff --git a/packages/meshbay-node/tests/test_hot_reload_survives_client_close.py b/packages/meshbay-node/tests/test_hot_reload_survives_client_close.py
index fc6af70..fb9eade 100644
--- a/packages/meshbay-node/tests/test_hot_reload_survives_client_close.py
+++ b/packages/meshbay-node/tests/test_hot_reload_survives_client_close.py
@@ -18,17 +18,15 @@ import asyncio
import base64
import os
from pathlib import Path
+from unittest.mock import AsyncMock, MagicMock, patch
+import meshbay_node.indexer.indexer as indexer_mod
import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-from unittest.mock import AsyncMock, MagicMock, patch
-
from meshbay_node import ops
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
from meshbay_node.daemon import NodeDaemon
-import meshbay_node.indexer.indexer as indexer_mod
def _free_port() -> int:
@@ -149,7 +147,7 @@ async def test_hot_loaded_group_finishes_scanning_without_anyone_awaiting_the_re
with patch("signal.SIGINT", 2), patch("signal.SIGTERM", 15):
try:
await asyncio.wait_for(daemon.run(), timeout=15)
- except (asyncio.TimeoutError, Exception):
+ except (TimeoutError, Exception):
pass
run_task = asyncio.create_task(run_daemon())
@@ -270,7 +268,7 @@ async def test_group_scoped_ops_404_until_listed_then_succeed(tmp_path):
with patch("signal.SIGINT", 2), patch("signal.SIGTERM", 15):
try:
await asyncio.wait_for(daemon.run(), timeout=15)
- except (asyncio.TimeoutError, Exception):
+ except (TimeoutError, Exception):
pass
run_task = asyncio.create_task(run_daemon())
diff --git a/packages/meshbay-node/tests/test_hub_client.py b/packages/meshbay-node/tests/test_hub_client.py
index 2975ee8..e733610 100644
--- a/packages/meshbay-node/tests/test_hub_client.py
+++ b/packages/meshbay-node/tests/test_hub_client.py
@@ -2,24 +2,17 @@
Tests for meshbay_node.hub_client — uses httpx.MockTransport to avoid network.
"""
-import json
-import os
import time
-import pytest
-from pathlib import Path
-from unittest.mock import AsyncMock, MagicMock, patch
import httpx
import jwt
+import pytest
+from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-from cryptography.hazmat.primitives import serialization
-
-
-from meshbay_node.hub_client import HubClient, HubConfig, HubSession
+from meshbay_node.hub_client import HubClient, HubConfig
from meshbay_node.keystore import NodeKeys
-
# ── Test fixtures ──────────────────────────────────────────────────────────────
@pytest.fixture
diff --git a/packages/meshbay-node/tests/test_hub_ws_group_claim.py b/packages/meshbay-node/tests/test_hub_ws_group_claim.py
index 49ac776..98b944b 100644
--- a/packages/meshbay-node/tests/test_hub_ws_group_claim.py
+++ b/packages/meshbay-node/tests/test_hub_ws_group_claim.py
@@ -15,7 +15,6 @@ import asyncio
import json
import pytest
-
from meshbay_node.hub_client import HubClient, HubConfig, HubSession
diff --git a/packages/meshbay-node/tests/test_ice_filter.py b/packages/meshbay-node/tests/test_ice_filter.py
index a995c2b..0fec2d2 100644
--- a/packages/meshbay-node/tests/test_ice_filter.py
+++ b/packages/meshbay-node/tests/test_ice_filter.py
@@ -3,8 +3,8 @@ transport/ice_filter — the interface filter must name the same adapter on
every platform, and must never leave the gather with no address at all.
"""
-import ifaddr
import aioice.ice
+import ifaddr
import pytest
from meshbay_node.transport import ice_filter
diff --git a/packages/meshbay-node/tests/test_index_cache.py b/packages/meshbay-node/tests/test_index_cache.py
index 036b4d7..8f0ff25 100644
--- a/packages/meshbay-node/tests/test_index_cache.py
+++ b/packages/meshbay-node/tests/test_index_cache.py
@@ -1,7 +1,6 @@
"""Tests for the (path, size, mtime) -> hash cache (indexer/cache.py)."""
import pytest
-
from meshbay_node.indexer.cache import IndexCache
diff --git a/packages/meshbay-node/tests/test_index_delta_carries_roots.py b/packages/meshbay-node/tests/test_index_delta_carries_roots.py
index 227f2d0..c939b4a 100644
--- a/packages/meshbay-node/tests/test_index_delta_carries_roots.py
+++ b/packages/meshbay-node/tests/test_index_delta_carries_roots.py
@@ -19,14 +19,12 @@ Additive on the wire (MNP 1.1): a 1.0 client sees a field it does not read.
from pathlib import Path
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.groupbox import PURPOSE_INDEX, unseal
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roots import RootSet
from meshbay_node.transport.wire import index_delta_message, index_sync_message
-
GROUP = "g" * 32
diff --git a/packages/meshbay-node/tests/test_index_no_cleartext.py b/packages/meshbay-node/tests/test_index_no_cleartext.py
index e5e4555..30d1226 100644
--- a/packages/meshbay-node/tests/test_index_no_cleartext.py
+++ b/packages/meshbay-node/tests/test_index_no_cleartext.py
@@ -14,7 +14,6 @@ framing or in a field name.
import msgpack
import pytest
-from conftest import one_root
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek
from meshbay_common.groupbox import PURPOSE_ACK, PURPOSE_INDEX, seal, unseal
@@ -22,6 +21,8 @@ from meshbay_common.protocol import MNP
from meshbay_node.indexer import DirectoryIndexer, GroupIndex
from meshbay_node.transport.wire import index_delta_message, index_sync_message
+from conftest import one_root
+
# A filename and a folder name that appear nowhere else in the tree.
SECRET_FILE = "quixotry-ledger-2019.pdf"
SECRET_DIR = "zarfwidget-archive"
diff --git a/packages/meshbay-node/tests/test_index_progress.py b/packages/meshbay-node/tests/test_index_progress.py
index df51e85..ecdc223 100644
--- a/packages/meshbay-node/tests/test_index_progress.py
+++ b/packages/meshbay-node/tests/test_index_progress.py
@@ -6,16 +6,15 @@ itself (see test_daemon.py for that) and never anything sent to the hub.
"""
import asyncio
+from unittest.mock import MagicMock
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-from unittest.mock import MagicMock
from fastapi.testclient import TestClient
-
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
+from meshbay_node.config import Config, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
-from meshbay_node.indexer.indexer import IndexProgress
from meshbay_node.indexer.group_index import GroupIndex
+from meshbay_node.indexer.indexer import IndexProgress
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
from meshbay_node.ui.app import create_ui_app
diff --git a/packages/meshbay-node/tests/test_indexer.py b/packages/meshbay-node/tests/test_indexer.py
index 6aee1b5..e97e2ef 100644
--- a/packages/meshbay-node/tests/test_indexer.py
+++ b/packages/meshbay-node/tests/test_indexer.py
@@ -4,16 +4,15 @@ import asyncio
import os
import threading
import time
-import pytest
from pathlib import Path
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
+import meshbay_node.indexer.indexer as indexer_mod
+import pytest
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek
from meshbay_node.indexer import DirectoryIndexer, GroupIndex, IndexCache
-import meshbay_node.indexer.indexer as indexer_mod
+
from conftest import one_root
-from meshbay_node.keystore import NodeKeys
@pytest.fixture
@@ -397,7 +396,8 @@ async def test_scan_interrupted_partway_leaves_only_completed_files_cached(
indexer_mod._scan_file = real_scan_file
assert resumed.index.count == 5
- assert len(calls) == 2, f"expected only the 2 not-yet-cached files to be hashed, got {len(calls)}"
+ assert len(calls) == 2, (
+ f"expected only the 2 not-yet-cached files to be hashed, got {len(calls)}")
# ── Progress state ───────────────────────────────────────────────────────────
@@ -741,7 +741,7 @@ def test_small_file_gets_hash_version_1(tmp_path):
def test_large_file_gets_hash_version_2(tmp_path):
- from meshbay_node.indexer.indexer import _scan_file, _PARTIAL_THRESHOLD
+ from meshbay_node.indexer.indexer import _PARTIAL_THRESHOLD, _scan_file
d = tmp_path / "root"
d.mkdir()
f = d / "big.mkv"
@@ -755,7 +755,7 @@ def test_large_file_gets_hash_version_2(tmp_path):
def test_file_at_threshold_gets_hash_version_1(tmp_path):
- from meshbay_node.indexer.indexer import _scan_file, _PARTIAL_THRESHOLD
+ from meshbay_node.indexer.indexer import _PARTIAL_THRESHOLD, _scan_file
d = tmp_path / "root"
d.mkdir()
f = d / "exact.mkv"
@@ -770,7 +770,7 @@ def test_partial_hash_differs_from_full_hash(tmp_path):
"""For a file above the threshold, the partial hash must differ from what
a full-file blake3 would produce (they read different bytes)."""
import blake3 as b3
- from meshbay_node.indexer.indexer import _scan_file, _PARTIAL_THRESHOLD
+ from meshbay_node.indexer.indexer import _PARTIAL_THRESHOLD, _scan_file
d = tmp_path / "root"
d.mkdir()
f = d / "big.mkv"
@@ -785,7 +785,7 @@ def test_partial_hash_differs_from_full_hash(tmp_path):
def test_partial_hash_is_deterministic(tmp_path):
- from meshbay_node.indexer.indexer import _scan_file, _PARTIAL_THRESHOLD
+ from meshbay_node.indexer.indexer import _PARTIAL_THRESHOLD, _scan_file
d = tmp_path / "root"
d.mkdir()
f = d / "big.mkv"
diff --git a/packages/meshbay-node/tests/test_keystore.py b/packages/meshbay-node/tests/test_keystore.py
index 7dfefce..b9dd3a4 100644
--- a/packages/meshbay-node/tests/test_keystore.py
+++ b/packages/meshbay-node/tests/test_keystore.py
@@ -3,15 +3,13 @@
import sys
import pytest
-from pathlib import Path
+from meshbay_common.crypto import generate_gek
from meshbay_node.keystore import (
- NodeKeys,
create_keystore,
load_keystore,
- save_keystore,
load_or_create_keystore,
+ save_keystore,
)
-from meshbay_common.crypto import generate_gek
def test_create_and_load(tmp_path):
diff --git a/packages/meshbay-node/tests/test_leaseless_reads.py b/packages/meshbay-node/tests/test_leaseless_reads.py
index 6bd7f1f..2c4c6cd 100644
--- a/packages/meshbay-node/tests/test_leaseless_reads.py
+++ b/packages/meshbay-node/tests/test_leaseless_reads.py
@@ -23,9 +23,10 @@ import re
from pathlib import Path
import pytest
-
from meshbay_node.transfers import (
- LEASELESS_IDLE_SECS, MAX_LEASELESS_IN_FLIGHT, LeaselessReads,
+ LEASELESS_IDLE_SECS,
+ MAX_LEASELESS_IN_FLIGHT,
+ LeaselessReads,
)
SPA = (Path(__file__).resolve().parents[2] / "meshbay-hub" / "src"
diff --git a/packages/meshbay-node/tests/test_media_cache.py b/packages/meshbay-node/tests/test_media_cache.py
index dc78d8d..ec4e56e 100644
--- a/packages/meshbay-node/tests/test_media_cache.py
+++ b/packages/meshbay-node/tests/test_media_cache.py
@@ -3,8 +3,7 @@
import time
import pytest
-
-from meshbay_node.media_cache import MediaCache, TMDB_META_TTL_SECS, MUSICBRAINZ_META_TTL_SECS
+from meshbay_node.media_cache import MUSICBRAINZ_META_TTL_SECS, TMDB_META_TTL_SECS, MediaCache
@pytest.fixture
diff --git a/packages/meshbay-node/tests/test_media_cache_eviction.py b/packages/meshbay-node/tests/test_media_cache_eviction.py
index 587063a..f0292b5 100644
--- a/packages/meshbay-node/tests/test_media_cache_eviction.py
+++ b/packages/meshbay-node/tests/test_media_cache_eviction.py
@@ -18,7 +18,6 @@ about `create_all()`. Every existing node has a `thumbs` table without it.
import sqlite3
import pytest
-
from meshbay_node.media_cache import MediaCache
diff --git a/packages/meshbay-node/tests/test_multi_group.py b/packages/meshbay-node/tests/test_multi_group.py
index 3dc4778..b75bad0 100644
--- a/packages/meshbay-node/tests/test_multi_group.py
+++ b/packages/meshbay-node/tests/test_multi_group.py
@@ -7,19 +7,18 @@ Verifies that:
- A user in both groups can access both
"""
-import os
import time
+
import jwt
import pytest
-from pathlib import Path
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
-
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek, pk_to_b64
from meshbay_node.indexer import DirectoryIndexer
-from conftest import one_root
-from meshbay_node.transport.quic_server import QuicChunkServer
from meshbay_node.transport.quic_client import QuicChunkClient
+from meshbay_node.transport.quic_server import QuicChunkServer
+
+from conftest import one_root
@pytest.fixture
@@ -73,10 +72,12 @@ async def multi_group_server(sk_node, sk_hub, gek_a, gek_b, dir_a, dir_b, tmp_pa
hub_pk_pem = sk_hub.public_key().public_bytes(
serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)
- indexer_a = DirectoryIndexer(roots=one_root(dir_a), group_id="group-a", sk_node=sk_node, gek=gek_a)
+ indexer_a = DirectoryIndexer(roots=one_root(dir_a), group_id="group-a",
+ sk_node=sk_node, gek=gek_a)
await indexer_a.initial_scan()
- indexer_b = DirectoryIndexer(roots=one_root(dir_b), group_id="group-b", sk_node=sk_node, gek=gek_b)
+ indexer_b = DirectoryIndexer(roots=one_root(dir_b), group_id="group-b",
+ sk_node=sk_node, gek=gek_b)
await indexer_b.initial_scan()
# RootSet, not a bare Path — what the daemon actually puts in a group context.
diff --git a/packages/meshbay-node/tests/test_musicbrainz_enabled_policy.py b/packages/meshbay-node/tests/test_musicbrainz_enabled_policy.py
index 76b687e..00c1b69 100644
--- a/packages/meshbay-node/tests/test_musicbrainz_enabled_policy.py
+++ b/packages/meshbay-node/tests/test_musicbrainz_enabled_policy.py
@@ -13,12 +13,11 @@ The contact string stays node-wide — see test_musicbrainz_config_policy.py.
from pathlib import Path
import pytest
-
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.adminop import OP_MUSICBRAINZ_ENABLED
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import Roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from conftest import one_root
diff --git a/packages/meshbay-node/tests/test_node_status.py b/packages/meshbay-node/tests/test_node_status.py
index 897be33..8bb2f39 100644
--- a/packages/meshbay-node/tests/test_node_status.py
+++ b/packages/meshbay-node/tests/test_node_status.py
@@ -12,22 +12,22 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
-from conftest import one_root
from meshbay_common.adminop import (
- OP_ROOT_ADD, OP_ROOT_REMOVE, OP_GROUP_ATTACH, OP_MEMBER_UNPIN,
+ OP_MEMBER_UNPIN,
admin_transcript,
)
-from meshbay_node.transport.quic_server import Denylist
from meshbay_common.crypto import pk_to_b64
from meshbay_common.join import ROLE_OPERATOR
from meshbay_common.protocol import MNP
from meshbay_node import ops
from meshbay_node.indexer.group_index import GroupIndex
-from meshbay_node.roster import open_roster
from meshbay_node.roots import RootSet
+from meshbay_node.roster import open_roster
+from meshbay_node.transport.quic_server import Denylist
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root
+
GROUP = "g" * 32
@@ -207,7 +207,6 @@ async def test_node_status_catches_send_failure(tmp_path, roster):
not silently vanish — it used to, because _send was outside the try block."""
session = await _session(tmp_path, roster, operator=True,
node_user_id="grenet")
- original_send = session._send
sent = []
call_count = [0]
@@ -260,7 +259,7 @@ async def test_add_root_creates_directory_and_returns_info(tmp_path):
shared.mkdir()
new_dir = tmp_path / "new_root"
- from meshbay_node.config import NodeConfig, GroupConfig, RootSpec
+ from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
cfg = GroupConfig(id=GROUP, name="test", roots=[
RootSpec(path=str(shared), name="shared", kind="generic", writable=True),
])
@@ -300,7 +299,7 @@ async def test_remove_root_requires_at_least_one_remaining(tmp_path):
shared = tmp_path / "shared"
shared.mkdir()
- from meshbay_node.config import GroupConfig, RootSpec, NodeConfig
+ from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
cfg = GroupConfig(id=GROUP, name="test", roots=[
RootSpec(path=str(shared), name="shared", kind="generic", writable=True),
])
@@ -333,7 +332,7 @@ async def test_removing_a_writable_root_is_allowed(tmp_path):
d1.mkdir()
d2.mkdir()
- from meshbay_node.config import GroupConfig, RootSpec, NodeConfig
+ from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
cfg = GroupConfig(id=GROUP, name="test", roots=[
RootSpec(path=str(d1), name="incoming", kind="generic", writable=True),
RootSpec(path=str(d2), name="shared", kind="generic", writable=False),
@@ -369,7 +368,7 @@ async def test_update_root_rewrites_the_flags_in_node_toml(tmp_path):
d1 = tmp_path / "media"
d1.mkdir()
- from meshbay_node.config import GroupConfig, RootSpec, NodeConfig
+ from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
cfg = GroupConfig(id=GROUP, name="test", roots=[
RootSpec(path=str(d1), name="media", kind="generic", writable=False),
])
@@ -420,7 +419,7 @@ async def test_update_root_replaces_a_legacy_upload_line(tmp_path):
d1 = tmp_path / "media"
d1.mkdir()
- from meshbay_node.config import GroupConfig, RootSpec, NodeConfig
+ from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
cfg = GroupConfig(id=GROUP, name="test", roots=[
RootSpec(path=str(d1), name="media", kind="generic", writable=True),
])
@@ -452,7 +451,7 @@ async def test_remove_root_succeeds_with_two_roots(tmp_path):
d1.mkdir()
d2.mkdir()
- from meshbay_node.config import GroupConfig, RootSpec, NodeConfig
+ from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
cfg = GroupConfig(id=GROUP, name="test", roots=[
RootSpec(path=str(d1), name="dir1", kind="generic", writable=True),
RootSpec(path=str(d2), name="dir2", kind="generic", writable=False),
diff --git a/packages/meshbay-node/tests/test_packaging_win.py b/packages/meshbay-node/tests/test_packaging_win.py
index 7b44bbe..aa77c29 100644
--- a/packages/meshbay-node/tests/test_packaging_win.py
+++ b/packages/meshbay-node/tests/test_packaging_win.py
@@ -1230,13 +1230,14 @@ def test_service_mode_ps1_starts_the_task_after_installing_it():
already-running task pointlessly on every mode switch away from service.
"""
src = (WIN / "service-mode.ps1").read_text(encoding="utf-8")
- install_branch, remove_branch = src.split('$Action -eq "install"', 1)[1], None
+ install_branch = src.split('$Action -eq "install"', 1)[1]
assert '"run"' in install_branch or "'run'" in install_branch, (
"service-mode.ps1 registers the task but never starts it -- the "
"daemon stays down until the next reboot")
# The run step must be conditioned on install having actually succeeded,
# not fired unconditionally regardless of $Action.
- guard_line = src[src.index('$Action -eq "install"') - 40:src.index('$Action -eq "install"') + 40]
+ at = src.index('$Action -eq "install"')
+ guard_line = src[at - 40:at + 40]
assert "-and" in guard_line or "-not $failed" in install_branch, (
"the follow-up `run` must be gated on Action=install and success, "
"not run unconditionally on every invocation including remove")
diff --git a/packages/meshbay-node/tests/test_partial_uploads.py b/packages/meshbay-node/tests/test_partial_uploads.py
index 0270a69..80ab454 100644
--- a/packages/meshbay-node/tests/test_partial_uploads.py
+++ b/packages/meshbay-node/tests/test_partial_uploads.py
@@ -23,21 +23,23 @@ from pathlib import Path
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek
+from meshbay_common.protocol import (
+ UPLOAD_PROBE_INDEX,
+ file_upload_ack_payload,
+)
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roots import Root, RootSet
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
-
-from meshbay_common.protocol import (
- UPLOAD_PROBE_INDEX, file_upload_ack_payload,
-)
-
-from conftest import one_root, sealed_upload
-
from meshbay_node.uploads import (
- ORPHAN_AFTER_SECS, PART_SUFFIX, PartialUploads, find_parts, orphaned_parts,
+ ORPHAN_AFTER_SECS,
+ PART_SUFFIX,
+ PartialUploads,
+ find_parts,
+ orphaned_parts,
)
+from conftest import one_root, sealed_upload
# ── the state ───────────────────────────────────────────────────────────────
@@ -466,7 +468,7 @@ async def test_an_upload_chunk_says_its_slot_is_in_use(tmp_path):
The download twin of this was fixed a day earlier; the same omission was
still here, invisible until uploads took a real lease.
"""
- from meshbay_node.transfers import TransferSlots, UPLOAD
+ from meshbay_node.transfers import UPLOAD, TransferSlots
ctx = _group_ctx(tmp_path)
peer = _peer(ctx)
diff --git a/packages/meshbay-node/tests/test_peer_session_limits.py b/packages/meshbay-node/tests/test_peer_session_limits.py
index 64961ad..d5c909b 100644
--- a/packages/meshbay-node/tests/test_peer_session_limits.py
+++ b/packages/meshbay-node/tests/test_peer_session_limits.py
@@ -15,10 +15,12 @@ import asyncio
from unittest.mock import MagicMock
import pytest
-
from meshbay_node.transport import webrtc_server as ws_mod
from meshbay_node.transport.webrtc_server import (
- MAX_PEER_SESSIONS, UNAUTHENTICATED_SESSION_TIMEOUT, WebRTCTransport)
+ MAX_PEER_SESSIONS,
+ UNAUTHENTICATED_SESSION_TIMEOUT,
+ WebRTCTransport,
+)
def _transport() -> WebRTCTransport:
diff --git a/packages/meshbay-node/tests/test_platform.py b/packages/meshbay-node/tests/test_platform.py
index 3fb27f3..5c80c5b 100644
--- a/packages/meshbay-node/tests/test_platform.py
+++ b/packages/meshbay-node/tests/test_platform.py
@@ -5,8 +5,8 @@ here by monkeypatching that (and `os.environ`) rather than only on the OS the
suite happens to run on.
"""
-import os
import asyncio
+import os
import sys
from pathlib import Path
from unittest.mock import Mock
diff --git a/packages/meshbay-node/tests/test_poster_cache.py b/packages/meshbay-node/tests/test_poster_cache.py
index bbd824d..908fb69 100644
--- a/packages/meshbay-node/tests/test_poster_cache.py
+++ b/packages/meshbay-node/tests/test_poster_cache.py
@@ -15,7 +15,6 @@ already uses to resolve a thumbnail by id.
"""
import pytest
-
from meshbay_node.media_cache import MediaCache
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
diff --git a/packages/meshbay-node/tests/test_quic_transport.py b/packages/meshbay-node/tests/test_quic_transport.py
index fb28295..8eb0622 100644
--- a/packages/meshbay-node/tests/test_quic_transport.py
+++ b/packages/meshbay-node/tests/test_quic_transport.py
@@ -6,17 +6,17 @@ Same structure as test_transport.py but uses QUIC instead of TCP+TLS.
import asyncio
import os
import time
+
import jwt
import pytest
-from pathlib import Path
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
-
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek, pk_to_b64
from meshbay_node.indexer import DirectoryIndexer
-from conftest import one_root
-from meshbay_node.transport.quic_server import QuicChunkServer, Denylist
from meshbay_node.transport.quic_client import QuicChunkClient
+from meshbay_node.transport.quic_server import Denylist, QuicChunkServer
+
+from conftest import one_root
@pytest.fixture
diff --git a/packages/meshbay-node/tests/test_rename_reenrichment.py b/packages/meshbay-node/tests/test_rename_reenrichment.py
index f6761d9..7ddca6f 100644
--- a/packages/meshbay-node/tests/test_rename_reenrichment.py
+++ b/packages/meshbay-node/tests/test_rename_reenrichment.py
@@ -17,9 +17,8 @@ import asyncio
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.media_cache import MediaCache
diff --git a/packages/meshbay-node/tests/test_replug_restores_enrichment.py b/packages/meshbay-node/tests/test_replug_restores_enrichment.py
index 04a06ae..a2d2db4 100644
--- a/packages/meshbay-node/tests/test_replug_restores_enrichment.py
+++ b/packages/meshbay-node/tests/test_replug_restores_enrichment.py
@@ -46,10 +46,8 @@ import os
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
-from meshbay_node.config import (Config, GroupConfig, HubConfig, KeystoreConfig,
- NodeConfig)
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.indexer.enrich_audio import AudioEnricher
diff --git a/packages/meshbay-node/tests/test_root_availability.py b/packages/meshbay-node/tests/test_root_availability.py
index 2d848c7..82bf6bd 100644
--- a/packages/meshbay-node/tests/test_root_availability.py
+++ b/packages/meshbay-node/tests/test_root_availability.py
@@ -13,13 +13,11 @@ an indexer that treats a vanished root as a set of deletions, which is what the
straightforward implementation does.
"""
-import asyncio
import os
from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_node.indexer.indexer import DirectoryIndexer
from meshbay_node.roots import RootSet
diff --git a/packages/meshbay-node/tests/test_root_eject.py b/packages/meshbay-node/tests/test_root_eject.py
index f57fb92..d73e71c 100644
--- a/packages/meshbay-node/tests/test_root_eject.py
+++ b/packages/meshbay-node/tests/test_root_eject.py
@@ -21,7 +21,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_node.indexer.indexer import DirectoryIndexer
from meshbay_node.roots import RootSet
from meshbay_node.roster import Roster
diff --git a/packages/meshbay-node/tests/test_root_ops_reach_the_live_set.py b/packages/meshbay-node/tests/test_root_ops_reach_the_live_set.py
index 976af82..6a52c06 100644
--- a/packages/meshbay-node/tests/test_root_ops_reach_the_live_set.py
+++ b/packages/meshbay-node/tests/test_root_ops_reach_the_live_set.py
@@ -28,7 +28,6 @@ from types import SimpleNamespace
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_node import ops
from meshbay_node.config import GroupConfig, NodeConfig, RootSpec
from meshbay_node.indexer.group_index import GroupIndex
diff --git a/packages/meshbay-node/tests/test_root_paths_are_operator_only.py b/packages/meshbay-node/tests/test_root_paths_are_operator_only.py
index 080d4be..0e89afa 100644
--- a/packages/meshbay-node/tests/test_root_paths_are_operator_only.py
+++ b/packages/meshbay-node/tests/test_root_paths_are_operator_only.py
@@ -21,7 +21,6 @@ import inspect
import re
from pathlib import Path
-
from meshbay_node import daemon as daemon_mod
from meshbay_node import ops
from meshbay_node.roots import RootSet
diff --git a/packages/meshbay-node/tests/test_root_writable_policy.py b/packages/meshbay-node/tests/test_root_writable_policy.py
index 3c8a837..0cd9af8 100644
--- a/packages/meshbay-node/tests/test_root_writable_policy.py
+++ b/packages/meshbay-node/tests/test_root_writable_policy.py
@@ -26,15 +26,15 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
-from conftest import sealed_upload
-from meshbay_common.adminop import OP_ROOT_UPDATE, OP_ROOT_EJECT, OP_ROOT_PLUG
+from meshbay_common.adminop import OP_ROOT_EJECT, OP_ROOT_PLUG, OP_ROOT_UPDATE
from meshbay_common.crypto import generate_gek
from meshbay_common.protocol import MNP
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roots import RootSet
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import sealed_upload
+
pytestmark = pytest.mark.asyncio
diff --git a/packages/meshbay-node/tests/test_roots.py b/packages/meshbay-node/tests/test_roots.py
index 9233180..004f004 100644
--- a/packages/meshbay-node/tests/test_roots.py
+++ b/packages/meshbay-node/tests/test_roots.py
@@ -7,15 +7,17 @@ file went to the wrong disk" or "the same film is listed twice and deleting one
copy breaks the other".
"""
-from pathlib import Path
import pytest
-
+from meshbay_common.protocol import IndexEntry
from meshbay_node.roots import (
- Root, RootError, RootSet, entry_abs_path,
- SAFE_UPLOAD_NAME, safe_subdir, _free_name,
+ SAFE_UPLOAD_NAME,
+ RootError,
+ RootSet,
+ _free_name,
+ entry_abs_path,
+ safe_subdir,
)
-from meshbay_common.protocol import IndexEntry
def _spec(path, **kw):
diff --git a/packages/meshbay-node/tests/test_roster_pairing.py b/packages/meshbay-node/tests/test_roster_pairing.py
index 2e8c183..82336e2 100644
--- a/packages/meshbay-node/tests/test_roster_pairing.py
+++ b/packages/meshbay-node/tests/test_roster_pairing.py
@@ -18,14 +18,13 @@ import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
-
from meshbay_common.crypto import generate_gek, pk_to_b64, unwrap_gek_aes
from meshbay_common.join import ROLE_MEMBER, ROLE_OPERATOR, join_transcript
from meshbay_node.indexer.group_index import GroupIndex
-from conftest import one_root
from meshbay_node.roster import Roster, hash_code, normalize_code
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root
# ── Fixtures ──────────────────────────────────────────────────────────────────
@@ -570,7 +569,8 @@ def test_challenge_carries_node_pk_in_source():
builds, whatever the surrounding handshake does.
"""
source = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
+ / "src" / "meshbay_node" / "transport"
+ / "webrtc_server.py").read_text(encoding="utf-8")
challenge = source[source.find("MNP.HANDSHAKE_CHALLENGE,"):]
challenge = challenge[:challenge.find("})")]
assert "node_pk" in challenge, (
@@ -694,7 +694,6 @@ async def test_unpinned_operator_loses_authority_immediately(tmp_path, roster):
def _ui_client(tmp_path, roster, **extra):
from fastapi.testclient import TestClient
-
from meshbay_node.config import Config
from meshbay_node.ui.app import create_ui_app
diff --git a/packages/meshbay-node/tests/test_scan_settings_policy.py b/packages/meshbay-node/tests/test_scan_settings_policy.py
index 94f4421..926c94f 100644
--- a/packages/meshbay-node/tests/test_scan_settings_policy.py
+++ b/packages/meshbay-node/tests/test_scan_settings_policy.py
@@ -13,7 +13,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.adminop import OP_SET_SCAN_SETTINGS
from meshbay_common.crypto import generate_gek
from meshbay_node import ops
diff --git a/packages/meshbay-node/tests/test_season_and_search_requests.py b/packages/meshbay-node/tests/test_season_and_search_requests.py
index 4141d13..7e81e63 100644
--- a/packages/meshbay-node/tests/test_season_and_search_requests.py
+++ b/packages/meshbay-node/tests/test_season_and_search_requests.py
@@ -10,7 +10,6 @@ test_tmdb_override_policy.py.
"""
import pytest
-
from meshbay_common.protocol import MNP
from meshbay_node.media_cache import MediaCache
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
diff --git a/packages/meshbay-node/tests/test_security_regressions.py b/packages/meshbay-node/tests/test_security_regressions.py
index d6ecb71..7010523 100644
--- a/packages/meshbay-node/tests/test_security_regressions.py
+++ b/packages/meshbay-node/tests/test_security_regressions.py
@@ -9,20 +9,18 @@ only ever exercised happy paths, never an authorization boundary.
If one of these starts failing, a fix has been reverted. Do not "fix" the test.
"""
-import base64
import struct
from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
-from meshbay_common.protocol import IndexEntry
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roots import RootSet
-from conftest import one_root, opened_ack, sealed_upload
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root, opened_ack, sealed_upload
+
def _safe_name_re():
"""
@@ -64,7 +62,7 @@ def test_daemon_exposes_no_plaintext_listener():
C1: the daemon must not bind anything that serves content without a handshake.
NodeConfig no longer carries an HTTP port at all.
"""
- from meshbay_node.config import NodeConfig, GroupConfig
+ from meshbay_node.config import GroupConfig, NodeConfig
assert "http_port" not in NodeConfig.__dataclass_fields__
assert "http_port" not in GroupConfig.__dataclass_fields__
@@ -464,7 +462,8 @@ def test_no_member_can_hand_the_node_key_material(tmp_path):
)
source = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
+ / "src" / "meshbay_node" / "transport"
+ / "webrtc_server.py").read_text(encoding="utf-8")
assert "_do_gek_bundle_store" not in source
assert "_admin_exec_bundle_store" not in source
@@ -568,6 +567,7 @@ def test_admin_signature_does_not_transfer_between_operations(tmp_path):
def test_admin_challenge_expires(tmp_path):
"""H5: a stale challenge must not be usable."""
import time as _time
+
from meshbay_common.adminop import ADMIN_CHALLENGE_TTL, OP_FILE_DELETE
session = _session(tmp_path, "operator")
@@ -633,6 +633,7 @@ def test_keystore_records_argon2_params_for_migration(tmp_path):
envelope records the parameters it was written with.
"""
import json
+
from meshbay_node.keystore import create_keystore, load_keystore
path = tmp_path / "keystore.enc"
@@ -648,11 +649,17 @@ def test_legacy_keystore_still_opens(tmp_path):
"""M2: a keystore written under the 64 MB profile must still unlock."""
import base64 as _b64
import json
+
import msgpack
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
from meshbay_common.crypto import (
- LEGACY_ARGON2_ITERATIONS, LEGACY_ARGON2_LANES, LEGACY_ARGON2_MEMORY_COST,
- derive_keystore_key, encrypt_keystore, pk_to_b64, sk_to_b64,
+ LEGACY_ARGON2_ITERATIONS,
+ LEGACY_ARGON2_LANES,
+ LEGACY_ARGON2_MEMORY_COST,
+ derive_keystore_key,
+ encrypt_keystore,
+ pk_to_b64,
+ sk_to_b64,
)
from meshbay_node.keystore import load_keystore
@@ -717,7 +724,9 @@ def test_pre_handshake_message_budget_is_small():
unauthenticated peer could announce a huge frame and dribble bytes into it.
"""
from meshbay_node.transport.webrtc_server import (
- MAX_MSG, PRE_HANDSHAKE_MAX_MSG, _DataChannelBuffer,
+ MAX_MSG,
+ PRE_HANDSHAKE_MAX_MSG,
+ _DataChannelBuffer,
)
assert PRE_HANDSHAKE_MAX_MSG <= 1024 * 1024
assert PRE_HANDSHAKE_MAX_MSG < MAX_MSG
@@ -918,8 +927,8 @@ async def test_an_identified_device_that_is_not_an_operator_is_refused(tmp_path)
and `operator_pks()` is rebuilt from the roster on every call so a revoked
one stops working at once.
"""
- from meshbay_node.roster import Roster
from meshbay_common.crypto import pk_to_b64
+ from meshbay_node.roster import Roster
roster = Roster(db_path=tmp_path / "roster.db")
await roster.open()
@@ -940,9 +949,9 @@ async def test_an_identified_device_that_is_not_an_operator_is_refused(tmp_path)
async def test_a_paired_operator_device_is_what_opens_it(tmp_path):
"""The positive case, so the test above is about authority and not about
everything being refused."""
- from meshbay_node.roster import Roster
- from meshbay_common.join import ROLE_OPERATOR
from meshbay_common.crypto import pk_to_b64
+ from meshbay_common.join import ROLE_OPERATOR
+ from meshbay_node.roster import Roster
roster = Roster(db_path=tmp_path / "roster.db")
await roster.open()
diff --git a/packages/meshbay-node/tests/test_startup_scan_enrichment.py b/packages/meshbay-node/tests/test_startup_scan_enrichment.py
index f43c6e9..f3ad2ca 100644
--- a/packages/meshbay-node/tests/test_startup_scan_enrichment.py
+++ b/packages/meshbay-node/tests/test_startup_scan_enrichment.py
@@ -21,12 +21,9 @@ is exercised the same way a real operator's group would be.
import asyncio
import pytest
-from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-from unittest.mock import MagicMock
-
from meshbay_common.crypto import generate_gek
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.indexer.enrich import Enricher
diff --git a/packages/meshbay-node/tests/test_stream_audio_track_selection.py b/packages/meshbay-node/tests/test_stream_audio_track_selection.py
index 53781f9..b9e2105 100644
--- a/packages/meshbay-node/tests/test_stream_audio_track_selection.py
+++ b/packages/meshbay-node/tests/test_stream_audio_track_selection.py
@@ -23,7 +23,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.indexer.group_index import GroupIndex
diff --git a/packages/meshbay-node/tests/test_stream_audio_transcode.py b/packages/meshbay-node/tests/test_stream_audio_transcode.py
index 92518ba..6c9bde7 100644
--- a/packages/meshbay-node/tests/test_stream_audio_transcode.py
+++ b/packages/meshbay-node/tests/test_stream_audio_transcode.py
@@ -22,7 +22,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.indexer.group_index import GroupIndex
@@ -44,7 +43,7 @@ def _make_clip(path: Path, *, acodec: str, channels: int = 2) -> None:
subprocess.run(
["ffmpeg", "-hide_banner", "-loglevel", "error", "-y",
"-f", "lavfi", "-i", "testsrc=size=320x240:rate=25:duration=1",
- "-f", "lavfi", "-i", f"sine=frequency=440:duration=1:sample_rate=48000",
+ "-f", "lavfi", "-i", "sine=frequency=440:duration=1:sample_rate=48000",
"-ac", str(channels),
"-c:v", "libx264", "-preset", "ultrafast", "-c:a", acodec,
str(path)],
diff --git a/packages/meshbay-node/tests/test_stream_capacity.py b/packages/meshbay-node/tests/test_stream_capacity.py
index a35ece8..7ce6bf6 100644
--- a/packages/meshbay-node/tests/test_stream_capacity.py
+++ b/packages/meshbay-node/tests/test_stream_capacity.py
@@ -17,9 +17,10 @@ find.
import asyncio
import pytest
-
from meshbay_node.transport.webrtc_server import (
- MAX_CONCURRENT_TRANSCODES, WebRTCPeerSession, WebRTCTransport,
+ MAX_CONCURRENT_TRANSCODES,
+ WebRTCPeerSession,
+ WebRTCTransport,
)
@@ -35,11 +36,11 @@ def transport(tmp_path):
"""A real WebRTCTransport. Its keys and index are genuine but incidental —
nothing below the capacity code reads them."""
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
- from conftest import one_root
from meshbay_common.crypto import generate_gek
from meshbay_node.indexer.group_index import GroupIndex
+ from conftest import one_root
+
sk_node = Ed25519PrivateKey.generate()
gek = generate_gek()
shared = tmp_path / "shared"
diff --git a/packages/meshbay-node/tests/test_stream_capacity_config.py b/packages/meshbay-node/tests/test_stream_capacity_config.py
index 442d3ef..c788ba6 100644
--- a/packages/meshbay-node/tests/test_stream_capacity_config.py
+++ b/packages/meshbay-node/tests/test_stream_capacity_config.py
@@ -23,7 +23,6 @@ import textwrap
from pathlib import Path
import pytest
-
from meshbay_node.config import load_config
from meshbay_node.roots import RootSet
from meshbay_node.transport.webrtc_server import (
diff --git a/packages/meshbay-node/tests/test_stream_seek_audio_alignment.py b/packages/meshbay-node/tests/test_stream_seek_audio_alignment.py
index c1d0c66..5d78c00 100644
--- a/packages/meshbay-node/tests/test_stream_seek_audio_alignment.py
+++ b/packages/meshbay-node/tests/test_stream_seek_audio_alignment.py
@@ -29,7 +29,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.indexer.group_index import GroupIndex
diff --git a/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py b/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py
index 9aea2b4..c575572 100644
--- a/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py
+++ b/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py
@@ -35,7 +35,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.indexer.group_index import GroupIndex
diff --git a/packages/meshbay-node/tests/test_stream_subtitle_tracks.py b/packages/meshbay-node/tests/test_stream_subtitle_tracks.py
index d3bcc8b..7a27a37 100644
--- a/packages/meshbay-node/tests/test_stream_subtitle_tracks.py
+++ b/packages/meshbay-node/tests/test_stream_subtitle_tracks.py
@@ -33,7 +33,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.indexer.group_index import GroupIndex
diff --git a/packages/meshbay-node/tests/test_stream_video_transcode.py b/packages/meshbay-node/tests/test_stream_video_transcode.py
index 316fdce..b60d546 100644
--- a/packages/meshbay-node/tests/test_stream_video_transcode.py
+++ b/packages/meshbay-node/tests/test_stream_video_transcode.py
@@ -32,7 +32,6 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node import hwaccel
diff --git a/packages/meshbay-node/tests/test_title_parse.py b/packages/meshbay-node/tests/test_title_parse.py
index 2c4573a..95c798b 100644
--- a/packages/meshbay-node/tests/test_title_parse.py
+++ b/packages/meshbay-node/tests/test_title_parse.py
@@ -17,7 +17,6 @@ from meshbay_node.indexer.title_parse import (
year_in,
)
-
# ── §3.3 row: plain, well-formed movie filename ──────────────────────────────
def test_plain_movie_filename_parses_confidently():
diff --git a/packages/meshbay-node/tests/test_tmdb.py b/packages/meshbay-node/tests/test_tmdb.py
index 299ff2a..981357a 100644
--- a/packages/meshbay-node/tests/test_tmdb.py
+++ b/packages/meshbay-node/tests/test_tmdb.py
@@ -2,7 +2,6 @@
import httpx
import pytest
-
from meshbay_node.tmdb import TmdbClient
diff --git a/packages/meshbay-node/tests/test_tmdb_config_policy.py b/packages/meshbay-node/tests/test_tmdb_config_policy.py
index cef4fda..6a51eb0 100644
--- a/packages/meshbay-node/tests/test_tmdb_config_policy.py
+++ b/packages/meshbay-node/tests/test_tmdb_config_policy.py
@@ -21,12 +21,11 @@ wire (see _issue_admin_challenge's docstring).
from pathlib import Path
import pytest
-
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.adminop import OP_TMDB_CONFIG
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import Roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from conftest import one_root
diff --git a/packages/meshbay-node/tests/test_tmdb_enabled_policy.py b/packages/meshbay-node/tests/test_tmdb_enabled_policy.py
index 0a748cd..10d1e2b 100644
--- a/packages/meshbay-node/tests/test_tmdb_enabled_policy.py
+++ b/packages/meshbay-node/tests/test_tmdb_enabled_policy.py
@@ -14,12 +14,11 @@ test_tmdb_config_policy.py for those.
from pathlib import Path
import pytest
-
+from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.adminop import OP_TMDB_ENABLED
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import Roster
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
-from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from conftest import one_root
diff --git a/packages/meshbay-node/tests/test_tmdb_language_fallback.py b/packages/meshbay-node/tests/test_tmdb_language_fallback.py
index 52fe4c4..62171c3 100644
--- a/packages/meshbay-node/tests/test_tmdb_language_fallback.py
+++ b/packages/meshbay-node/tests/test_tmdb_language_fallback.py
@@ -9,7 +9,6 @@ field, or silently showing a blank overview/poster.
"""
import pytest
-
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
pytestmark = pytest.mark.asyncio
diff --git a/packages/meshbay-node/tests/test_tmdb_override_policy.py b/packages/meshbay-node/tests/test_tmdb_override_policy.py
index d434e1a..aed3ea2 100644
--- a/packages/meshbay-node/tests/test_tmdb_override_policy.py
+++ b/packages/meshbay-node/tests/test_tmdb_override_policy.py
@@ -14,9 +14,8 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.adminop import OP_TMDB_OVERRIDE
-from meshbay_common.protocol import IndexEntry, MNP
+from meshbay_common.protocol import MNP, IndexEntry
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.media_cache import MediaCache
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
diff --git a/packages/meshbay-node/tests/test_tmdb_rematch_policy.py b/packages/meshbay-node/tests/test_tmdb_rematch_policy.py
index 198d75b..4d43552 100644
--- a/packages/meshbay-node/tests/test_tmdb_rematch_policy.py
+++ b/packages/meshbay-node/tests/test_tmdb_rematch_policy.py
@@ -9,7 +9,6 @@ asking for a fresh resolution.
import hashlib
import pytest
-from conftest import one_root
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.adminop import OP_TMDB_REMATCH
from meshbay_common.protocol import MNP, IndexEntry
@@ -17,6 +16,8 @@ from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.media_cache import MediaCache
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
+from conftest import one_root
+
pytestmark = pytest.mark.asyncio
diff --git a/packages/meshbay-node/tests/test_tmdb_show_director.py b/packages/meshbay-node/tests/test_tmdb_show_director.py
index cb31c2c..fd324b1 100644
--- a/packages/meshbay-node/tests/test_tmdb_show_director.py
+++ b/packages/meshbay-node/tests/test_tmdb_show_director.py
@@ -12,7 +12,6 @@ the show details. Several creators is ordinary, so they join into one line.
"""
import pytest
-
from meshbay_node.transport.webrtc_server import WebRTCPeerSession
pytestmark = pytest.mark.asyncio
diff --git a/packages/meshbay-node/tests/test_transfer_settings.py b/packages/meshbay-node/tests/test_transfer_settings.py
index bcfa6a8..a2c7fd9 100644
--- a/packages/meshbay-node/tests/test_transfer_settings.py
+++ b/packages/meshbay-node/tests/test_transfer_settings.py
@@ -19,10 +19,12 @@ shape of the bug this whole branch started from (`webrtc._stream_sem`).
"""
import pytest
-
from meshbay_node.roster import Roster
from meshbay_node.transfers import (
- DEFAULT_MAX_PER_MEMBER, DOWNLOAD, UPLOAD, TransferSlots,
+ DEFAULT_MAX_PER_MEMBER,
+ DOWNLOAD,
+ UPLOAD,
+ TransferSlots,
)
diff --git a/packages/meshbay-node/tests/test_transfer_slots.py b/packages/meshbay-node/tests/test_transfer_slots.py
index 7056e93..08e7e70 100644
--- a/packages/meshbay-node/tests/test_transfer_slots.py
+++ b/packages/meshbay-node/tests/test_transfer_slots.py
@@ -21,12 +21,18 @@ by reasoning about it.
import random
import pytest
-
from meshbay_node.transfers import (
- DOWNLOAD, GRANT_DEADLINE_SECS, IDLE_TIMEOUT_SECS, KINDS,
- MAX_MISSED_GRANTS, MAX_QUEUED_PER_MEMBER, REASON_ABANDONED, REASON_IDLE,
- REASON_NOT_TAKEN_UP, TransferSlots,
+ DOWNLOAD,
+ GRANT_DEADLINE_SECS,
+ IDLE_TIMEOUT_SECS,
+ KINDS,
+ MAX_MISSED_GRANTS,
+ MAX_QUEUED_PER_MEMBER,
+ REASON_ABANDONED,
+ REASON_IDLE,
+ REASON_NOT_TAKEN_UP,
UPLOAD,
+ TransferSlots,
)
diff --git a/packages/meshbay-node/tests/test_transfer_slots_wire.py b/packages/meshbay-node/tests/test_transfer_slots_wire.py
index c9fc85a..d96456c 100644
--- a/packages/meshbay-node/tests/test_transfer_slots_wire.py
+++ b/packages/meshbay-node/tests/test_transfer_slots_wire.py
@@ -19,6 +19,9 @@ Three things can only be checked here:
"""
import pytest
+from meshbay_common.protocol import MNP
+from meshbay_node.transfers import DOWNLOAD, UPLOAD
+from meshbay_node.transport.webrtc_server import WebRTCPeerSession
# Every test drives a message handler, and in the node a message handler always
# runs inside the event loop: `_do_transfer_open` starts the sweeper task there.
@@ -26,10 +29,6 @@ import pytest
# on "no current event loop" the moment the sweeper stopped being faked.
pytestmark = pytest.mark.asyncio
-from meshbay_common.protocol import MNP
-from meshbay_node.transfers import DOWNLOAD, UPLOAD
-from meshbay_node.transport.webrtc_server import WebRTCPeerSession
-
class _Session(WebRTCPeerSession):
"""A session with the DataChannel replaced by a list, and nothing else."""
diff --git a/packages/meshbay-node/tests/test_transport_wire_parity.py b/packages/meshbay-node/tests/test_transport_wire_parity.py
index bc6b134..6e74b28 100644
--- a/packages/meshbay-node/tests/test_transport_wire_parity.py
+++ b/packages/meshbay-node/tests/test_transport_wire_parity.py
@@ -16,7 +16,6 @@ again.
import inspect
import pytest
-from conftest import one_root
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek
from meshbay_common.groupbox import PURPOSE_INDEX, unseal
@@ -25,6 +24,8 @@ from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.transport import quic_server, webrtc_server
from meshbay_node.transport.wire import index_sync_message
+from conftest import one_root
+
@pytest.fixture
def gek():
diff --git a/packages/meshbay-node/tests/test_upload_size_cap.py b/packages/meshbay-node/tests/test_upload_size_cap.py
index dca6e15..cc04eba 100644
--- a/packages/meshbay-node/tests/test_upload_size_cap.py
+++ b/packages/meshbay-node/tests/test_upload_size_cap.py
@@ -17,7 +17,6 @@ import textwrap
from pathlib import Path
import pytest
-
from meshbay_node.config import load_config
from meshbay_node.roots import RootSet
from meshbay_node.transport.webrtc_server import (
diff --git a/packages/meshbay-node/tests/test_video_root_gates_enrichment.py b/packages/meshbay-node/tests/test_video_root_gates_enrichment.py
index d06b3f4..c39876a 100644
--- a/packages/meshbay-node/tests/test_video_root_gates_enrichment.py
+++ b/packages/meshbay-node/tests/test_video_root_gates_enrichment.py
@@ -17,10 +17,9 @@ import asyncio
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
-
from meshbay_common.crypto import generate_gek
from meshbay_node import ops
-from meshbay_node.config import Config, HubConfig, NodeConfig, GroupConfig, KeystoreConfig
+from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.indexer.enrich import Enricher
diff --git a/packages/meshbay-node/tests/test_webrtc_transport.py b/packages/meshbay-node/tests/test_webrtc_transport.py
index 0839d42..91a6e1c 100644
--- a/packages/meshbay-node/tests/test_webrtc_transport.py
+++ b/packages/meshbay-node/tests/test_webrtc_transport.py
@@ -9,52 +9,58 @@ Uses local loopback (no STUN/ICE needed for localhost).
import asyncio
import base64
-from contextlib import asynccontextmanager
import hashlib
import hmac
import os
import struct
import time
+from contextlib import asynccontextmanager
import jwt
import msgpack
import pytest
+from aiortc import RTCPeerConnection, RTCSessionDescription
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
- Ed25519PrivateKey, Ed25519PublicKey,
+ Ed25519PrivateKey,
+ Ed25519PublicKey,
)
-from aiortc import RTCPeerConnection, RTCSessionDescription
-
from meshbay_common import MNP_VERSION
+from meshbay_common.adminop import (
+ OP_FILE_DELETE,
+ OP_INVITE_CREATE,
+ admin_transcript,
+)
from meshbay_common.crypto import (
generate_gek,
pk_to_b64,
- wrap_gek,
- wrap_gek_aes,
unwrap_gek,
unwrap_gek_aes,
+ wrap_gek,
+ wrap_gek_aes,
)
from meshbay_common.groupbox import PURPOSE_ACK, PURPOSE_INDEX, unseal
-from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
-from meshbay_common.protocol import MNP
-TEST_GROUP = "g"
-
from meshbay_common.handshake import (
- NONCE_LEN, ROLE_CLIENT, ROLE_NODE, handshake_transcript,
- make_proof, verify_proof, webrtc_binding,
-)
-from meshbay_common.adminop import (
- OP_FILE_DELETE,
- OP_INVITE_CREATE,
- admin_transcript,
+ NONCE_LEN,
+ ROLE_CLIENT,
+ ROLE_NODE,
+ handshake_transcript,
+ make_proof,
+ verify_proof,
+ webrtc_binding,
)
from meshbay_common.join import ROLE_MEMBER, ROLE_OPERATOR, join_transcript
+from meshbay_common.protocol import MNP
+from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.bundle_store import BundleStore
-from conftest import one_root
-from meshbay_node.roster import Roster
from meshbay_node.indexer import DirectoryIndexer
+from meshbay_node.roster import Roster
from meshbay_node.transport.webrtc_server import WebRTCTransport
+from conftest import one_root
+
+TEST_GROUP = "g"
+
@pytest.fixture
def sk_node():
diff --git a/packages/meshbay-node/tests/test_windows_root_shapes.py b/packages/meshbay-node/tests/test_windows_root_shapes.py
index 5c5da25..56279b1 100644
--- a/packages/meshbay-node/tests/test_windows_root_shapes.py
+++ b/packages/meshbay-node/tests/test_windows_root_shapes.py
@@ -27,7 +27,6 @@ import tomllib
from pathlib import Path, PureWindowsPath
import pytest
-
from meshbay_node.roots import RootError, RootSet, derive_name
BS = chr(92)
diff --git a/packages/meshbay-node/tests/test_wizard_apps_endpoint.py b/packages/meshbay-node/tests/test_wizard_apps_endpoint.py
index 10ab489..77fa9a6 100644
--- a/packages/meshbay-node/tests/test_wizard_apps_endpoint.py
+++ b/packages/meshbay-node/tests/test_wizard_apps_endpoint.py
@@ -13,12 +13,12 @@ from pathlib import Path
import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from fastapi.testclient import TestClient
-
-from conftest import one_root
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.roster import Roster
from meshbay_node.ui.app import create_ui_app
+from conftest import one_root
+
pytestmark = pytest.mark.asyncio
diff --git a/packages/meshbay-node/tests/transfer_probe.py b/packages/meshbay-node/tests/transfer_probe.py
index 38e6cb6..7aa4902 100755
--- a/packages/meshbay-node/tests/transfer_probe.py
+++ b/packages/meshbay-node/tests/transfer_probe.py
@@ -69,9 +69,8 @@ if not (_QE / "e2e.py").exists():
f"run this from a machine that has one.")
sys.path.insert(0, str(_QE))
-import httpx # noqa: E402
-
-from e2e import Client, env # noqa: E402
+import httpx # noqa: E402
+from e2e import Client, env # noqa: E402
def _line(ok: bool, text: str) -> None:
@@ -272,7 +271,6 @@ async def operator_checks(client, ack, group, node_id) -> int:
and the operator's view because it reported the module defaults.
"""
import asyncio as _a
- import json as _json
import re as _re
failures = 0
@@ -322,7 +320,7 @@ async def operator_checks(client, ack, group, node_id) -> int:
try:
started = await _a.wait_for(
_wait_for_grant(client, tr_waiting), timeout=20)
- except _a.TimeoutError:
+ except TimeoutError:
started = False
_line(started, "raising the cap started the waiting transfer, with no "
"restart and no reconnection")
@@ -371,7 +369,7 @@ async def operator_checks(client, ack, group, node_id) -> int:
_cli("transfers", "per-member", "4", "4", "--group", group["id"])
try:
moved = await _a.wait_for(_wait_for_grant(client, tr_c), timeout=20)
- except _a.TimeoutError:
+ except TimeoutError:
moved = False
_line(moved, "raising the per-member cap started what was waiting on it")
failures += not moved
@@ -526,7 +524,7 @@ async def probe(args) -> int:
try:
seen.append(await alice.recv_type("transfer_state",
timeout=15))
- except asyncio.TimeoutError:
+ except TimeoutError:
break
promoted = [m for m in seen if m.get("state") == "granted"]
ok = bool(promoted)