vsremote 0.2.2__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. vsremote-0.3.0/.github/renovate.json +31 -0
  2. {vsremote-0.2.2 → vsremote-0.3.0}/.github/workflows/cd-build.yml +1 -1
  3. {vsremote-0.2.2 → vsremote-0.3.0}/.github/workflows/ci-lint.yml +2 -1
  4. {vsremote-0.2.2 → vsremote-0.3.0}/.github/workflows/ci-test.yml +1 -1
  5. {vsremote-0.2.2 → vsremote-0.3.0}/PKG-INFO +2 -2
  6. {vsremote-0.2.2 → vsremote-0.3.0}/pyproject.toml +1 -1
  7. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/__init__.py +6 -1
  8. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/api/output.py +5 -0
  9. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/cli.py +8 -21
  10. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/client/client.py +2 -2
  11. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/client/transport.py +216 -94
  12. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/protocol/keys.py +11 -5
  13. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/protocol/messages.py +3 -1
  14. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/server/daemon.py +84 -83
  15. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/server/policy.py +3 -5
  16. vsremote-0.3.0/src/vsremote/server/redirect.py +200 -0
  17. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/server/runner.py +4 -3
  18. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/utils.py +0 -11
  19. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_cli_commands.py +55 -17
  20. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_client_server.py +40 -0
  21. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_exceptions.py +1 -0
  22. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_protocol.py +2 -8
  23. vsremote-0.3.0/tests/test_redirect.py +104 -0
  24. {vsremote-0.2.2 → vsremote-0.3.0}/uv.lock +145 -145
  25. vsremote-0.2.2/src/vsremote/server/redirect.py +0 -171
  26. {vsremote-0.2.2 → vsremote-0.3.0}/.github/workflows/cd.yml +0 -0
  27. {vsremote-0.2.2 → vsremote-0.3.0}/.gitignore +0 -0
  28. {vsremote-0.2.2 → vsremote-0.3.0}/LICENSE +0 -0
  29. {vsremote-0.2.2 → vsremote-0.3.0}/README.md +0 -0
  30. {vsremote-0.2.2 → vsremote-0.3.0}/hatch_build.py +0 -0
  31. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/__main__.py +0 -0
  32. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/_strides.py +0 -0
  33. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/api/__init__.py +0 -0
  34. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/api/info.py +0 -0
  35. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/client/__init__.py +0 -0
  36. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/exceptions.py +0 -0
  37. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/protocol/__init__.py +0 -0
  38. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/protocol/codec.py +0 -0
  39. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/protocol/constants.py +0 -0
  40. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/py.typed +0 -0
  41. {vsremote-0.2.2 → vsremote-0.3.0}/src/vsremote/server/__init__.py +0 -0
  42. {vsremote-0.2.2 → vsremote-0.3.0}/stubs/vapoursynth/__init__.pyi +0 -0
  43. {vsremote-0.2.2 → vsremote-0.3.0}/tests/conftest.py +0 -0
  44. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_api.py +0 -0
  45. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_codec.py +0 -0
  46. {vsremote-0.2.2 → vsremote-0.3.0}/tests/test_serve.py +0 -0
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:best-practices",
5
+ "helpers:pinGitHubActionDigests",
6
+ ":automergeMinor",
7
+ ":automergePr",
8
+ ":automergeRequireAllStatusChecks",
9
+ ":disableDependencyDashboard",
10
+ ":disableRateLimiting",
11
+ ":semanticCommits",
12
+ ":semanticCommitScopeDisabled",
13
+ ":semanticCommitTypeAll(deps)"
14
+ ],
15
+ "vulnerabilityAlerts": {
16
+ "enabled": true,
17
+ "groupName": "Security fixes",
18
+ "addLabels": ["security"]
19
+ },
20
+ "packageRules": [
21
+ {
22
+ "extends": [":semanticCommitTypeAll(ci)"],
23
+ "matchManagers": ["github-actions"],
24
+ "pinDigests": true
25
+ },
26
+ {
27
+ "automerge": true,
28
+ "matchUpdateTypes": ["pin", "digest", "pinDigest"]
29
+ }
30
+ ]
31
+ }
@@ -36,7 +36,7 @@ jobs:
36
36
  fetch-tags: true
37
37
 
38
38
  - name: Set up uv
39
- uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
39
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
40
40
  with:
41
41
  enable-cache: false
42
42
  python-version: ${{ matrix.python-version }}
@@ -13,6 +13,7 @@ on:
13
13
  - "**.py"
14
14
  - "**/pyproject.toml"
15
15
  - "uv.lock"
16
+ - ".github/workflows/ci-lint.yml"
16
17
  workflow_dispatch:
17
18
 
18
19
  permissions:
@@ -34,7 +35,7 @@ jobs:
34
35
  fetch-tags: true
35
36
 
36
37
  - name: Set up uv
37
- uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
38
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
38
39
  with:
39
40
  python-version: "3.12"
40
41
 
@@ -41,7 +41,7 @@ jobs:
41
41
  fetch-tags: true
42
42
 
43
43
  - name: Set up uv
44
- uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
44
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
45
45
  with:
46
46
  python-version: ${{ matrix.python-version }}
47
47
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vsremote
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Remote execution and frame proxy for VapourSynth
5
5
  Author-email: Vardë <ichunjo.le.terrible@gmail.com>
6
6
  License-File: LICENSE
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.14
15
15
  Classifier: Topic :: Multimedia :: Graphics
16
16
  Classifier: Typing :: Typed
17
17
  Requires-Python: >=3.12
18
- Requires-Dist: cyclopts>=5.0.0b1
18
+ Requires-Dist: cyclopts>=4.23.3
19
19
  Requires-Dist: msgspec>=0.21.1
20
20
  Requires-Dist: pyzmq>=27.1.0
21
21
  Requires-Dist: rich>=15.0.0
@@ -32,7 +32,7 @@ dependencies = [
32
32
  "pyzmq>=27.1.0",
33
33
  "zstandard>=0.25.0",
34
34
  "msgspec>=0.21.1",
35
- "cyclopts>=5.0.0b1",
35
+ "cyclopts>=4.23.3",
36
36
  "rich>=15.0.0",
37
37
  ]
38
38
  dynamic = ["version"]
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from . import client, exceptions, protocol, server
4
4
  from .api import is_preview, set_output
5
5
  from .cli import info, keygen, ping, pipe, serve
6
- from .client import RemoteClient, source
6
+ from .client import ClientTransport, RemoteClient, source
7
7
  from .exceptions import (
8
8
  EnvironmentNotSetError,
9
9
  MalformedMessageError,
@@ -30,6 +30,7 @@ from .exceptions import (
30
30
  )
31
31
 
32
32
  __all__ = [
33
+ "ClientTransport",
33
34
  "EnvironmentNotSetError",
34
35
  "MalformedMessageError",
35
36
  "OutputNotFoundError",
@@ -55,7 +56,11 @@ __all__ = [
55
56
  "VSRemoteError",
56
57
  "client",
57
58
  "exceptions",
59
+ "info",
58
60
  "is_preview",
61
+ "keygen",
62
+ "ping",
63
+ "pipe",
59
64
  "protocol",
60
65
  "serve",
61
66
  "server",
@@ -79,6 +79,11 @@ def set_output(node: vs.RawNode, index_or_name: int | str | bool | None = None,
79
79
  _output_metadata[index] = effective_name
80
80
 
81
81
 
82
+ def clear_output_metadata() -> None:
83
+ """Clear all registered output metadata."""
84
+ _output_metadata.clear()
85
+
86
+
82
87
  def _resolve_var_name(obj: Any, *, frame_depth: int = 1) -> str | None:
83
88
  try:
84
89
  frame = sys._getframe(frame_depth)
@@ -8,11 +8,9 @@ import sys
8
8
  import threading
9
9
  import time
10
10
  from collections.abc import Sequence
11
- from contextlib import nullcontext
12
11
  from dataclasses import dataclass
13
12
  from typing import Annotated, override
14
13
 
15
- import vapoursynth as vs
16
14
  import zmq
17
15
  from cyclopts import App, Parameter
18
16
  from cyclopts.help import DefaultFormatter, HelpPanel
@@ -33,7 +31,7 @@ class CleanHelpFormatter(DefaultFormatter):
33
31
  @override
34
32
  def __call__(self, console: Console, options: ConsoleOptions, panel: HelpPanel) -> None:
35
33
  panel.entries = [
36
- entry.copy(positive_names=entry.positive_names[1:]) # type: ignore[no-untyped-call]
34
+ entry.copy(positive_names=entry.positive_names[1:])
37
35
  if len(entry.positive_names) > 1 and not entry.positive_names[0].startswith("-")
38
36
  else entry
39
37
  for entry in panel.entries
@@ -45,7 +43,7 @@ app = App("vsremote", console=console, default_parameter=Parameter(negative=()),
45
43
 
46
44
 
47
45
  @Parameter(name="*")
48
- @dataclass(frozen=True)
46
+ @dataclass(frozen=True, slots=True)
49
47
  class ClientConfig:
50
48
  """Connection and authentication parameters for remote server operations."""
51
49
 
@@ -221,7 +219,6 @@ def pipe(
221
219
  prefetch: int = 8,
222
220
  backlog: int | None = None,
223
221
  compression: Compression = "zstd",
224
- environment: Annotated[Policy | ManagedEnvironment | None, Parameter(show=False)] = None,
225
222
  ) -> None:
226
223
  """
227
224
  Stream video frames directly from the remote server to stdout in Y4M format or raw planes.
@@ -240,7 +237,7 @@ def pipe(
240
237
  stdout_buf = sys.stdout.buffer
241
238
 
242
239
  if y4m:
243
- stdout_buf.write(_get_y4m_header(clip_info, environment))
240
+ stdout_buf.write(_get_y4m_header(clip_info))
244
241
  stdout_buf.flush()
245
242
 
246
243
  prefetch_count = max(0, prefetch)
@@ -320,8 +317,7 @@ def main_meta(*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen
320
317
  """
321
318
  setup_logging(level=logging.DEBUG if verbose else logging.INFO)
322
319
 
323
- if tokens:
324
- app(tokens)
320
+ app(tokens)
325
321
 
326
322
 
327
323
  def main() -> None:
@@ -329,7 +325,8 @@ def main() -> None:
329
325
 
330
326
 
331
327
  async def _watch_stop(daemon: ServerDaemon, stop_event: threading.Event) -> None:
332
- await asyncio.get_running_loop().run_in_executor(None, stop_event.wait)
328
+ while not stop_event.is_set(): # noqa: ASYNC110
329
+ await asyncio.sleep(0.5)
333
330
  await daemon.stop()
334
331
 
335
332
 
@@ -339,7 +336,7 @@ async def _wakeup() -> None:
339
336
  await asyncio.sleep(0.5)
340
337
 
341
338
 
342
- def _get_y4m_header(info: ClipInfo, environment: Policy | ManagedEnvironment | None) -> bytes:
339
+ def _get_y4m_header(info: ClipInfo) -> bytes:
343
340
  if info.num_planes == 1:
344
341
  y4mformat = "mono"
345
342
  elif info.num_planes == 3:
@@ -363,17 +360,7 @@ def _get_y4m_header(info: ClipInfo, environment: Policy | ManagedEnvironment | N
363
360
  else:
364
361
  raise UnsupportedFormatError(f"Unsupported number of planes for Y4M: {info.num_planes}")
365
362
 
366
- if isinstance(policy := environment, Policy):
367
- ctx = policy.new_environment().use()
368
- elif isinstance(environment, ManagedEnvironment):
369
- ctx = environment.use()
370
- else:
371
- ctx = nullcontext()
372
-
373
- with ctx:
374
- bits = vs.core.get_video_format(info.format_id).bits_per_sample
375
-
376
- if bits > 8:
363
+ if (bits := info.bits_per_sample) > 8:
377
364
  y4mformat += f"p{bits}"
378
365
 
379
366
  header = (
@@ -308,12 +308,12 @@ class RemoteClient:
308
308
  "stack_info": event.stack_info,
309
309
  }
310
310
  rec = logging.makeLogRecord(record_dict)
311
- setattr(rec, "_is_remote", True)
311
+ rec._is_remote = True
312
312
  if self.forward_logs:
313
313
  logging.getLogger(rec.name).handle(rec)
314
314
 
315
315
  case StreamOutputEvent():
316
- if not (target := self._streams[event.stream]):
316
+ if not (target := self._streams.get(event.stream)):
317
317
  return
318
318
  try:
319
319
  target.write(event.text)