Red-YT-Cipher-Solver 0.2.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Red-YT-Cipher-Solver
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: A thin wrapper over yt-dlp/ejs for deciphering YT signatures. Comes with Deno out of the box.
5
5
  Author: Jakub Kuczys, Cog Creators
6
6
  Author-email: Jakub Kuczys <me@jacken.men>
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Requires-Dist: aiohttp>=3.9.5,<4
14
14
  Requires-Dist: deno>=2.7.1,<3
15
- Requires-Dist: typing-extensions~=4.15.0
15
+ Requires-Dist: typing-extensions>=4.13.2,<5
16
16
  Requires-Dist: yarl~=1.15.2
17
17
  Requires-Dist: yt-dlp-ejs~=0.5.0
18
18
  Requires-Python: >=3.10
@@ -24,6 +24,9 @@ Description-Content-Type: text/markdown
24
24
 
25
25
  # Red-YT-Cipher-Solver
26
26
 
27
+ [![Red-YT-Cipher-Solver on PyPI](https://img.shields.io/pypi/v/Red-YT-Cipher-Solver)](https://pypi.org/project/Red-YT-Cipher-Solver)
28
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
29
+
27
30
  A thin wrapper over [yt-dlp/ejs](https://github.com/yt-dlp/ejs) for deciphering YT signatures.
28
31
  Aside from yt-dlp/ejs, this uses the [official Deno PyPI package](https://github.com/denoland/deno_pypi),
29
32
  meaning no additional setup is required beyond installing the package and then using it either as a library
@@ -1,5 +1,8 @@
1
1
  # Red-YT-Cipher-Solver
2
2
 
3
+ [![Red-YT-Cipher-Solver on PyPI](https://img.shields.io/pypi/v/Red-YT-Cipher-Solver)](https://pypi.org/project/Red-YT-Cipher-Solver)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
3
6
  A thin wrapper over [yt-dlp/ejs](https://github.com/yt-dlp/ejs) for deciphering YT signatures.
4
7
  Aside from yt-dlp/ejs, this uses the [official Deno PyPI package](https://github.com/denoland/deno_pypi),
5
8
  meaning no additional setup is required beyond installing the package and then using it either as a library
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "Red-YT-Cipher-Solver"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "A thin wrapper over yt-dlp/ejs for deciphering YT signatures. Comes with Deno out of the box."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -13,7 +13,7 @@ requires-python = ">=3.10"
13
13
  dependencies = [
14
14
  "aiohttp>=3.9.5,<4",
15
15
  "deno>=2.7.1,<3",
16
- "typing-extensions~=4.15.0",
16
+ "typing-extensions>=4.13.2,<5",
17
17
  "yarl~=1.15.2",
18
18
  "yt-dlp-ejs~=0.5.0",
19
19
  ]
@@ -68,6 +68,7 @@ class SolverServerProcess:
68
68
  self.start_timeout = start_timeout
69
69
  self._client_timeout = client_timeout
70
70
  self._proc: asyncio.subprocess.Process | None = None
71
+ self._startup_finished = asyncio.Event()
71
72
  self._stopped = asyncio.Event()
72
73
  self._running = False
73
74
  self._restarting = False
@@ -100,6 +101,33 @@ class SolverServerProcess:
100
101
  await self.stop()
101
102
  await self._session.close()
102
103
 
104
+ async def wait_for_startup(self) -> bool:
105
+ """
106
+ Wait for the startup to finish (successfully or not).
107
+
108
+ Returns
109
+ -------
110
+ bool
111
+ ``True`` if the startup was successful, ``False`` otherwise.
112
+ """
113
+ await self._startup_finished.wait()
114
+ return not self._stopped.is_set()
115
+
116
+ async def wait_until_stopped(self) -> None:
117
+ """Wait until the server stops."""
118
+ await self._stopped.wait()
119
+
120
+ async def check_restart_failure(self) -> None:
121
+ """
122
+ Check whether a scheduled restart failed.
123
+
124
+ This function will raise the exception from scheduled restart
125
+ or return immediately, if the scheduled restart was successful
126
+ or when there was no restart.
127
+ """
128
+ if self._restart_task is not None:
129
+ await self._restart_task
130
+
103
131
  def is_running(self) -> bool:
104
132
  """Whether the server is currently running."""
105
133
  return self._running
@@ -156,6 +184,8 @@ class SolverServerProcess:
156
184
  while wait:
157
185
  wait = (time.perf_counter() - process_start) < start_timeout
158
186
  if self._proc.returncode is not None:
187
+ await self.stop(timeout=1.0)
188
+ self._startup_finished.set()
159
189
  raise ProcessStartError("The process failed to start.")
160
190
 
161
191
  request_start = time.perf_counter()
@@ -174,12 +204,14 @@ class SolverServerProcess:
174
204
  await asyncio.sleep(1.0 - request_duration)
175
205
  else:
176
206
  await self.stop(timeout=1.0)
207
+ self._startup_finished.set()
177
208
  raise TimeoutError("The server did not start in time.")
178
209
 
179
210
  self._running = True
180
211
  self._health_checker = asyncio.create_task(self._health_check_loop())
181
212
  self._proc_watcher = asyncio.create_task(self._watch_process(self._proc))
182
213
  log.info("A solver server process has been started successfully.")
214
+ self._startup_finished.set()
183
215
 
184
216
  async def stop(self, *, timeout: float = 5.0) -> None:
185
217
  """
@@ -309,6 +341,5 @@ class SolverServerProcess:
309
341
  """
310
342
  async with self:
311
343
  await self.start()
312
- await self._stopped.wait()
313
- if self._restart_task is not None:
314
- await self._restart_task
344
+ await self.wait_until_stopped()
345
+ await self.check_restart_failure()