├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── config_example.json
├── perplex.py
├── poetry.lock
├── pyproject.toml
└── start.ps1
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: ["https://cash.app/$EthanChrisp", "https://venmo.com/u/Mxtive"]
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | # Visual Studio Code
132 | .vscode/
133 |
134 | # Credentials
135 | config.json
136 | auth.txt
137 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Ethan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Perplex
2 |
3 | Perplex is a Discord Rich Presence implementation for Plex.
4 |
5 |
6 |
7 |
8 |
9 | ## Features
10 |
11 | - Modern and beautiful Rich Presence for movies, TV shows, and music.
12 | - [The Movie Database (TMDB)](https://www.themoviedb.org/) integration for enhanced media information.
13 | - Optional minimal mode for Rich Presence to hide granular information
14 | - Lightweight console application that runs in the background.
15 | - Support for two-factor authentication (2FA) at login.
16 | - Prioritize multiple Plex media servers and users with one configuration.
17 |
18 | ## Setup
19 |
20 | Perplex is built for [Python 3.11](https://www.python.org/) or greater. [TMDB API](https://www.themoviedb.org/settings/api) credentials are required to enable media art and external information.
21 |
22 | Note: A Discord desktop client must be connected on the same device that Perplex is running on.
23 |
24 | 1. Install required dependencies using [Poetry](https://python-poetry.org/): `poetry install`
25 | 2. Rename `config_example.json` to `config.json`, then provide the configurable values.
26 | 3. Start Perplex: `python perplex.py`
27 |
28 | **Configurable Values:**
29 |
30 | - `logging`:`severity`: Minimum [Loguru](https://loguru.readthedocs.io/en/stable/api/logger.html) severity level to display in the console (do not modify unless necessary).
31 | - `plex`:`username`: Plex username for login.
32 | - `plex`:`password`: Plex password for login.
33 | - `plex`:`twoFactor`: `true` or `false` toggle for two-factor authentication prompt at login.
34 | - `plex`:`servers`: List of Plex media servers, in order of priority.
35 | - `plex`:`users`: List of Plex users, in order of priority.
36 | - `tmdb`:`enable`: `true` or `false` toggle for enhanced media information in Rich Presence.
37 | - `tmdb`:`apiKey`: [TMDB API](https://www.themoviedb.org/settings/api) key (only used if `tmdb` `enable` is `true`).
38 | - `discord`:`appId`: Discord application ID (do not modify unless necessary).
39 | - `discord`:`minimal`: `true` or `false` toggle for minimal media information in Rich Presence.
40 |
--------------------------------------------------------------------------------
/config_example.json:
--------------------------------------------------------------------------------
1 | {
2 | "logging": {
3 | "severity": "INFO"
4 | },
5 | "plex": {
6 | "username": "example@email.com",
7 | "password": "password123!",
8 | "twoFactor": false,
9 | "servers": ["My Media Server"],
10 | "users": ["Ethan"]
11 | },
12 | "tmdb": {
13 | "enable": true,
14 | "apiKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
15 | },
16 | "discord": {
17 | "appId": 923857760897101855,
18 | "minimal": false
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/perplex.py:
--------------------------------------------------------------------------------
1 | import json
2 | import urllib.parse
3 | from datetime import datetime
4 | from pathlib import Path
5 | from sys import exit, stderr
6 | from time import sleep
7 | from typing import Any, Dict, List, Optional, Self, Union
8 |
9 | import httpx
10 | from httpx import Response
11 | from loguru import logger
12 | from plexapi.audio import TrackSession
13 | from plexapi.media import Media
14 | from plexapi.myplex import MyPlexAccount, MyPlexResource, PlexServer
15 | from plexapi.video import EpisodeSession, MovieSession
16 | from pypresence import Presence
17 |
18 |
19 | class Perplex:
20 | """
21 | Discord Rich Presence implementation for Plex.
22 |
23 | https://github.com/EthanC/Perplex
24 | """
25 |
26 | def Initialize(self: Self) -> None:
27 | """Initialize Perplex and begin primary functionality."""
28 |
29 | logger.info("Perplex")
30 | logger.info("https://github.com/EthanC/Perplex")
31 |
32 | self.config: Dict[str, Any] = Perplex.LoadConfig(self)
33 |
34 | Perplex.SetupLogging(self)
35 |
36 | plex: MyPlexAccount = Perplex.LoginPlex(self)
37 | discord: Presence = Perplex.LoginDiscord(self)
38 |
39 | while True:
40 | session: Optional[
41 | Union[MovieSession, EpisodeSession, TrackSession]
42 | ] = Perplex.FetchSession(self, plex)
43 |
44 | if session:
45 | logger.success(f"Fetched active media session")
46 |
47 | if type(session) is MovieSession:
48 | status: Dict[str, Any] = Perplex.BuildMoviePresence(self, session)
49 | elif type(session) is EpisodeSession:
50 | status: Dict[str, Any] = Perplex.BuildEpisodePresence(self, session)
51 | elif type(session) is TrackSession:
52 | status: Dict[str, Any] = Perplex.BuildTrackPresence(self, session)
53 |
54 | success: bool = Perplex.SetPresence(self, discord, status)
55 |
56 | # Reestablish a failed Discord Rich Presence connection
57 | if not success:
58 | discord = Perplex.LoginDiscord(self)
59 | else:
60 | try:
61 | discord.clear()
62 | except Exception:
63 | pass
64 |
65 | # Presence updates have a rate limit of 1 update per 15 seconds
66 | # https://discord.com/developers/docs/rich-presence/how-to#updating-presence
67 | logger.info("Sleeping for 15s...")
68 |
69 | sleep(15.0)
70 |
71 | def LoadConfig(self: Self) -> Dict[str, Any]:
72 | """Load the configuration values specified in config.json"""
73 |
74 | try:
75 | with open("config.json", "r") as file:
76 | config: Dict[str, Any] = json.loads(file.read())
77 | except Exception as e:
78 | logger.critical(f"Failed to load configuration, {e}")
79 |
80 | exit(1)
81 |
82 | logger.success("Loaded configuration")
83 |
84 | return config
85 |
86 | def SetupLogging(self: Self) -> None:
87 | """Setup the logger using the configured values."""
88 |
89 | settings: Dict[str, Any] = self.config["logging"]
90 |
91 | if (level := settings["severity"].upper()) != "DEBUG":
92 | try:
93 | logger.remove()
94 | logger.add(stderr, level=level)
95 |
96 | logger.success(f"Set logger severity to {level}")
97 | except Exception as e:
98 | # Fallback to default logger settings
99 | logger.add(stderr, level="DEBUG")
100 |
101 | logger.error(f"Failed to set logger severity to {level}, {e}")
102 |
103 | def LoginPlex(self: Self) -> MyPlexAccount:
104 | """Authenticate with Plex using the configured credentials."""
105 |
106 | settings: Dict[str, Any] = self.config["plex"]
107 |
108 | account: Optional[MyPlexAccount] = None
109 |
110 | if Path("auth.txt").is_file():
111 | try:
112 | with open("auth.txt", "r") as file:
113 | auth: str = file.read()
114 |
115 | account = MyPlexAccount(token=auth)
116 | except Exception as e:
117 | logger.error(f"Failed to authenticate with Plex using token, {e}")
118 |
119 | if not account:
120 | username: str = settings["username"]
121 | password: str = settings["password"]
122 |
123 | if settings["twoFactor"]:
124 | print(f"Enter Verification Code: ", end="")
125 | code: str = input()
126 |
127 | if (code == "") or (code.isspace()):
128 | logger.warning(
129 | "Two-Factor Authentication is enabled but code was not supplied"
130 | )
131 | else:
132 | password = f"{password}{code}"
133 |
134 | try:
135 | account = MyPlexAccount(username, password)
136 | except Exception as e:
137 | logger.critical(f"Failed to authenticate with Plex, {e}")
138 |
139 | exit(1)
140 |
141 | logger.success("Authenticated with Plex")
142 |
143 | try:
144 | with open("auth.txt", "w+") as file:
145 | file.write(account.authenticationToken)
146 | except Exception as e:
147 | logger.error(
148 | f"Failed to save Plex authentication token for future logins, {e}"
149 | )
150 |
151 | return account
152 |
153 | def LoginDiscord(self: Self) -> Presence:
154 | """Authenticate with Discord using the configured credentials."""
155 |
156 | client: Optional[Presence] = None
157 |
158 | while not client:
159 | try:
160 | client = Presence(self.config["discord"]["appId"])
161 | client.connect()
162 | except Exception as e:
163 | logger.error(f"Failed to connect to Discord ({e}) retry in 15s...")
164 |
165 | sleep(15.0)
166 |
167 | logger.success("Authenticated with Discord")
168 |
169 | return client
170 |
171 | def FetchSession(
172 | self: Self, client: MyPlexAccount
173 | ) -> Optional[Union[MovieSession, EpisodeSession, TrackSession]]:
174 | """
175 | Connect to the configured Plex Media Server and return the active
176 | media session.
177 | """
178 |
179 | settings: Dict[str, Any] = self.config["plex"]
180 |
181 | resource: Optional[MyPlexResource] = None
182 | server: Optional[PlexServer] = None
183 |
184 | for entry in settings["servers"]:
185 | for result in client.resources():
186 | if entry.lower() == result.name.lower():
187 | resource = result
188 |
189 | break
190 |
191 | if resource:
192 | break
193 |
194 | if not resource:
195 | logger.critical("Failed to locate configured Plex Media Server")
196 |
197 | exit(1)
198 |
199 | try:
200 | server = resource.connect()
201 | except Exception as e:
202 | logger.critical(
203 | f"Failed to connect to configured Plex Media Server ({resource.name}), {e}"
204 | )
205 |
206 | exit(1)
207 |
208 | sessions: List[Media] = server.sessions()
209 | active: Optional[Union[MovieSession, EpisodeSession, TrackSession]] = None
210 |
211 | if len(sessions) > 0:
212 | i: int = 0
213 |
214 | for entry in settings["users"]:
215 | for result in sessions:
216 | if entry.lower() in [alias.lower() for alias in result.usernames]:
217 | active = sessions[i]
218 |
219 | break
220 |
221 | i += 1
222 |
223 | if not active:
224 | logger.info("No active media sessions found for configured users")
225 |
226 | return
227 |
228 | if type(active) is MovieSession:
229 | return active
230 | elif type(active) is EpisodeSession:
231 | return active
232 | elif type(active) is TrackSession:
233 | return active
234 |
235 | logger.error(f"Fetched active media session of unknown type: {type(active)}")
236 |
237 | def BuildMoviePresence(self: Self, active: MovieSession) -> Dict[str, Any]:
238 | """Build a Discord Rich Presence status for the active movie session."""
239 |
240 | minimal: bool = self.config["discord"]["minimal"]
241 |
242 | result: Dict[str, Any] = {}
243 |
244 | metadata: Optional[Dict[str, Any]] = Perplex.FetchMetadata(
245 | self, active.title, active.year, "movie"
246 | )
247 |
248 | if minimal:
249 | result["primary"] = active.title
250 | else:
251 | result["primary"] = f"{active.title} ({active.year})"
252 |
253 | details: List[str] = []
254 |
255 | if len(active.genres) > 0:
256 | details.append(active.genres[0].tag)
257 |
258 | if len(active.directors) > 0:
259 | details.append(f"Dir. {active.directors[0].tag}")
260 |
261 | if len(details) > 1:
262 | result["secondary"] = ", ".join(details)
263 |
264 | if not metadata:
265 | # Default to image uploaded via Discord Developer Portal
266 | result["image"] = "movie"
267 | result["buttons"] = []
268 | else:
269 | mId: int = metadata["id"]
270 | mType: str = metadata["media_type"]
271 | imgPath: str = metadata["poster_path"]
272 |
273 | result["image"] = f"https://image.tmdb.org/t/p/original{imgPath}"
274 |
275 | result["buttons"] = [
276 | {"label": "TMDB", "url": f"https://themoviedb.org/{mType}/{mId}"}
277 | ]
278 |
279 | result["remaining"] = int((active.duration / 1000) - (active.viewOffset / 1000))
280 | result["imageText"] = active.title
281 |
282 | logger.trace(result)
283 |
284 | return result
285 |
286 | def BuildEpisodePresence(self: Self, active: EpisodeSession) -> Dict[str, Any]:
287 | """Build a Discord Rich Presence status for the active episode session."""
288 |
289 | result: Dict[str, Any] = {}
290 |
291 | metadata: Optional[Dict[str, Any]] = Perplex.FetchMetadata(
292 | self, active.show().title, active.show().year, "tv"
293 | )
294 |
295 | result["primary"] = active.show().title
296 | result["secondary"] = active.title
297 | result["remaining"] = int((active.duration / 1000) - (active.viewOffset / 1000))
298 | result["imageText"] = active.show().title
299 |
300 | if (active.seasonNumber) and (active.episodeNumber):
301 | result["secondary"] += f" (S{active.seasonNumber}:E{active.episodeNumber})"
302 |
303 | if not metadata:
304 | # Default to image uploaded via Discord Developer Portal
305 | result["image"] = "tv"
306 | result["buttons"] = []
307 | else:
308 | mId: int = metadata["id"]
309 | mType: str = metadata["media_type"]
310 | imgPath: str = metadata["poster_path"]
311 |
312 | result["image"] = f"https://image.tmdb.org/t/p/original{imgPath}"
313 |
314 | result["buttons"] = [
315 | {"label": "TMDB", "url": f"https://themoviedb.org/{mType}/{mId}"}
316 | ]
317 |
318 | logger.trace(result)
319 |
320 | return result
321 |
322 | def BuildTrackPresence(self: Self, active: TrackSession) -> Dict[str, Any]:
323 | """Build a Discord Rich Presence status for the active music session."""
324 |
325 | result: Dict[str, Any] = {}
326 |
327 | result["primary"] = active.titleSort
328 | result["secondary"] = f"by {active.artist().title}"
329 | result["remaining"] = int((active.duration / 1000) - (active.viewOffset / 1000))
330 | result["imageText"] = active.parentTitle
331 |
332 | # Default to image uploaded via Discord Developer Portal
333 | result["image"] = "music"
334 | result["buttons"] = []
335 |
336 | logger.trace(result)
337 |
338 | return result
339 |
340 | def FetchMetadata(
341 | self: Self, title: str, year: int, format: str
342 | ) -> Optional[Dict[str, Any]]:
343 | """Fetch metadata for the provided title from TMDB."""
344 |
345 | settings: Dict[str, Any] = self.config["tmdb"]
346 | key: str = settings["apiKey"]
347 |
348 | if not settings["enable"]:
349 | logger.warning(f"TMDB disabled, some features will not be available")
350 |
351 | return
352 |
353 | try:
354 | res: Response = httpx.get(
355 | f"https://api.themoviedb.org/3/search/multi?api_key={key}&query={urllib.parse.quote(title)}"
356 | )
357 | res.raise_for_status()
358 |
359 | logger.debug(f"(HTTP {res.status_code}) GET {res.url}")
360 | logger.trace(res.text)
361 | except Exception as e:
362 | logger.error(f"Failed to fetch metadata for {title} ({year}), {e}")
363 |
364 | return
365 |
366 | data: Dict[str, Any] = res.json()
367 |
368 | for entry in data.get("results", []):
369 | if format == "movie":
370 | if entry["media_type"] != format:
371 | continue
372 | elif title.lower() != entry["title"].lower():
373 | continue
374 | elif not entry["release_date"].startswith(str(year)):
375 | continue
376 | elif format == "tv":
377 | if entry["media_type"] != format:
378 | continue
379 | elif title.lower() != entry["name"].lower():
380 | continue
381 | elif not entry["first_air_date"].startswith(str(year)):
382 | continue
383 |
384 | return entry
385 |
386 | logger.warning(f"Could not locate metadata for {title} ({year})")
387 |
388 | def SetPresence(self: Self, client: Presence, data: Dict[str, Any]) -> bool:
389 | """Set the Rich Presence status for the provided Discord client."""
390 |
391 | title: str = data["primary"]
392 |
393 | data["buttons"].append(
394 | {"label": "Get Perplex", "url": "https://github.com/EthanC/Perplex"}
395 | )
396 |
397 | try:
398 | client.update(
399 | details=title,
400 | state=data.get("secondary"),
401 | end=int(datetime.now().timestamp() + data["remaining"]),
402 | large_image=data["image"],
403 | large_text=data["imageText"],
404 | small_image="plex",
405 | small_text="Plex",
406 | buttons=data["buttons"],
407 | )
408 | except Exception as e:
409 | logger.error(f"Failed to set Discord Rich Presence to {title}, {e}")
410 |
411 | return False
412 |
413 | logger.success(f"Set Discord Rich Presence to {title}")
414 |
415 | return True
416 |
417 |
418 | if __name__ == "__main__":
419 | try:
420 | Perplex.Initialize(Perplex)
421 | except KeyboardInterrupt:
422 | exit()
423 |
--------------------------------------------------------------------------------
/poetry.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "anyio"
3 | version = "3.6.2"
4 | description = "High level compatibility layer for multiple asynchronous event loop implementations"
5 | category = "main"
6 | optional = false
7 | python-versions = ">=3.6.2"
8 |
9 | [package.dependencies]
10 | idna = ">=2.8"
11 | sniffio = ">=1.1"
12 |
13 | [package.extras]
14 | doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
15 | test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"]
16 | trio = ["trio (>=0.16,<0.22)"]
17 |
18 | [[package]]
19 | name = "astroid"
20 | version = "2.14.1"
21 | description = "An abstract syntax tree for Python with inference support."
22 | category = "dev"
23 | optional = false
24 | python-versions = ">=3.7.2"
25 |
26 | [package.dependencies]
27 | lazy-object-proxy = ">=1.4.0"
28 | wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}
29 |
30 | [[package]]
31 | name = "black"
32 | version = "23.1.0"
33 | description = "The uncompromising code formatter."
34 | category = "dev"
35 | optional = false
36 | python-versions = ">=3.7"
37 |
38 | [package.dependencies]
39 | click = ">=8.0.0"
40 | mypy-extensions = ">=0.4.3"
41 | packaging = ">=22.0"
42 | pathspec = ">=0.9.0"
43 | platformdirs = ">=2"
44 |
45 | [package.extras]
46 | colorama = ["colorama (>=0.4.3)"]
47 | d = ["aiohttp (>=3.7.4)"]
48 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
49 | uvloop = ["uvloop (>=0.15.2)"]
50 |
51 | [[package]]
52 | name = "certifi"
53 | version = "2022.12.7"
54 | description = "Python package for providing Mozilla's CA Bundle."
55 | category = "main"
56 | optional = false
57 | python-versions = ">=3.6"
58 |
59 | [[package]]
60 | name = "charset-normalizer"
61 | version = "3.0.1"
62 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
63 | category = "main"
64 | optional = false
65 | python-versions = "*"
66 |
67 | [[package]]
68 | name = "click"
69 | version = "8.1.3"
70 | description = "Composable command line interface toolkit"
71 | category = "dev"
72 | optional = false
73 | python-versions = ">=3.7"
74 |
75 | [package.dependencies]
76 | colorama = {version = "*", markers = "platform_system == \"Windows\""}
77 |
78 | [[package]]
79 | name = "colorama"
80 | version = "0.4.6"
81 | description = "Cross-platform colored terminal text."
82 | category = "main"
83 | optional = false
84 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
85 |
86 | [[package]]
87 | name = "dill"
88 | version = "0.3.6"
89 | description = "serialize all of python"
90 | category = "dev"
91 | optional = false
92 | python-versions = ">=3.7"
93 |
94 | [package.extras]
95 | graph = ["objgraph (>=1.7.2)"]
96 |
97 | [[package]]
98 | name = "h11"
99 | version = "0.14.0"
100 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
101 | category = "main"
102 | optional = false
103 | python-versions = ">=3.7"
104 |
105 | [[package]]
106 | name = "httpcore"
107 | version = "0.16.3"
108 | description = "A minimal low-level HTTP client."
109 | category = "main"
110 | optional = false
111 | python-versions = ">=3.7"
112 |
113 | [package.dependencies]
114 | anyio = ">=3.0,<5.0"
115 | certifi = "*"
116 | h11 = ">=0.13,<0.15"
117 | sniffio = ">=1.0.0,<2.0.0"
118 |
119 | [package.extras]
120 | http2 = ["h2 (>=3,<5)"]
121 | socks = ["socksio (>=1.0.0,<2.0.0)"]
122 |
123 | [[package]]
124 | name = "httpx"
125 | version = "0.23.3"
126 | description = "The next generation HTTP client."
127 | category = "main"
128 | optional = false
129 | python-versions = ">=3.7"
130 |
131 | [package.dependencies]
132 | certifi = "*"
133 | httpcore = ">=0.15.0,<0.17.0"
134 | rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]}
135 | sniffio = "*"
136 |
137 | [package.extras]
138 | brotli = ["brotli", "brotlicffi"]
139 | cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<13)"]
140 | http2 = ["h2 (>=3,<5)"]
141 | socks = ["socksio (>=1.0.0,<2.0.0)"]
142 |
143 | [[package]]
144 | name = "idna"
145 | version = "3.4"
146 | description = "Internationalized Domain Names in Applications (IDNA)"
147 | category = "main"
148 | optional = false
149 | python-versions = ">=3.5"
150 |
151 | [[package]]
152 | name = "isort"
153 | version = "5.12.0"
154 | description = "A Python utility / library to sort Python imports."
155 | category = "dev"
156 | optional = false
157 | python-versions = ">=3.8.0"
158 |
159 | [package.extras]
160 | colors = ["colorama (>=0.4.3)"]
161 | pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
162 | plugins = ["setuptools"]
163 | requirements-deprecated-finder = ["pip-api", "pipreqs"]
164 |
165 | [[package]]
166 | name = "lazy-object-proxy"
167 | version = "1.9.0"
168 | description = "A fast and thorough lazy object proxy."
169 | category = "dev"
170 | optional = false
171 | python-versions = ">=3.7"
172 |
173 | [[package]]
174 | name = "loguru"
175 | version = "0.6.0"
176 | description = "Python logging made (stupidly) simple"
177 | category = "main"
178 | optional = false
179 | python-versions = ">=3.5"
180 |
181 | [package.dependencies]
182 | colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
183 | win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
184 |
185 | [package.extras]
186 | dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
187 |
188 | [[package]]
189 | name = "mccabe"
190 | version = "0.7.0"
191 | description = "McCabe checker, plugin for flake8"
192 | category = "dev"
193 | optional = false
194 | python-versions = ">=3.6"
195 |
196 | [[package]]
197 | name = "mypy-extensions"
198 | version = "1.0.0"
199 | description = "Type system extensions for programs checked with the mypy type checker."
200 | category = "dev"
201 | optional = false
202 | python-versions = ">=3.5"
203 |
204 | [[package]]
205 | name = "packaging"
206 | version = "23.0"
207 | description = "Core utilities for Python packages"
208 | category = "dev"
209 | optional = false
210 | python-versions = ">=3.7"
211 |
212 | [[package]]
213 | name = "pathspec"
214 | version = "0.11.0"
215 | description = "Utility library for gitignore style pattern matching of file paths."
216 | category = "dev"
217 | optional = false
218 | python-versions = ">=3.7"
219 |
220 | [[package]]
221 | name = "platformdirs"
222 | version = "3.0.0"
223 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
224 | category = "dev"
225 | optional = false
226 | python-versions = ">=3.7"
227 |
228 | [package.extras]
229 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
230 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
231 |
232 | [[package]]
233 | name = "plexapi"
234 | version = "4.13.2"
235 | description = "Python bindings for the Plex API."
236 | category = "main"
237 | optional = false
238 | python-versions = ">=3.7"
239 |
240 | [package.dependencies]
241 | requests = "*"
242 |
243 | [[package]]
244 | name = "pylint"
245 | version = "2.16.1"
246 | description = "python code static checker"
247 | category = "dev"
248 | optional = false
249 | python-versions = ">=3.7.2"
250 |
251 | [package.dependencies]
252 | astroid = ">=2.14.1,<=2.16.0-dev0"
253 | colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
254 | dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""}
255 | isort = ">=4.2.5,<6"
256 | mccabe = ">=0.6,<0.8"
257 | platformdirs = ">=2.2.0"
258 | tomlkit = ">=0.10.1"
259 |
260 | [package.extras]
261 | spelling = ["pyenchant (>=3.2,<4.0)"]
262 | testutils = ["gitpython (>3)"]
263 |
264 | [[package]]
265 | name = "pypresence"
266 | version = "4.2.1"
267 | description = "Discord RPC client written in Python"
268 | category = "main"
269 | optional = false
270 | python-versions = ">=3.5"
271 |
272 | [[package]]
273 | name = "requests"
274 | version = "2.28.2"
275 | description = "Python HTTP for Humans."
276 | category = "main"
277 | optional = false
278 | python-versions = ">=3.7, <4"
279 |
280 | [package.dependencies]
281 | certifi = ">=2017.4.17"
282 | charset-normalizer = ">=2,<4"
283 | idna = ">=2.5,<4"
284 | urllib3 = ">=1.21.1,<1.27"
285 |
286 | [package.extras]
287 | socks = ["PySocks (>=1.5.6,!=1.5.7)"]
288 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
289 |
290 | [[package]]
291 | name = "rfc3986"
292 | version = "1.5.0"
293 | description = "Validating URI References per RFC 3986"
294 | category = "main"
295 | optional = false
296 | python-versions = "*"
297 |
298 | [package.dependencies]
299 | idna = {version = "*", optional = true, markers = "extra == \"idna2008\""}
300 |
301 | [package.extras]
302 | idna2008 = ["idna"]
303 |
304 | [[package]]
305 | name = "sniffio"
306 | version = "1.3.0"
307 | description = "Sniff out which async library your code is running under"
308 | category = "main"
309 | optional = false
310 | python-versions = ">=3.7"
311 |
312 | [[package]]
313 | name = "tomlkit"
314 | version = "0.11.6"
315 | description = "Style preserving TOML library"
316 | category = "dev"
317 | optional = false
318 | python-versions = ">=3.6"
319 |
320 | [[package]]
321 | name = "urllib3"
322 | version = "1.26.14"
323 | description = "HTTP library with thread-safe connection pooling, file post, and more."
324 | category = "main"
325 | optional = false
326 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
327 |
328 | [package.extras]
329 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
330 | secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
331 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
332 |
333 | [[package]]
334 | name = "win32-setctime"
335 | version = "1.1.0"
336 | description = "A small Python utility to set file creation time on Windows"
337 | category = "main"
338 | optional = false
339 | python-versions = ">=3.5"
340 |
341 | [package.extras]
342 | dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
343 |
344 | [[package]]
345 | name = "wrapt"
346 | version = "1.14.1"
347 | description = "Module for decorators, wrappers and monkey patching."
348 | category = "dev"
349 | optional = false
350 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
351 |
352 | [metadata]
353 | lock-version = "1.1"
354 | python-versions = "^3.11"
355 | content-hash = "700ed7a0fbc0e6670746945b827b2c1ada9586654612eff723a873f9e85e7499"
356 |
357 | [metadata.files]
358 | anyio = [
359 | {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"},
360 | {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"},
361 | ]
362 | astroid = [
363 | {file = "astroid-2.14.1-py3-none-any.whl", hash = "sha256:23c718921acab5f08cbbbe9293967f1f8fec40c336d19cd75dc12a9ea31d2eb2"},
364 | {file = "astroid-2.14.1.tar.gz", hash = "sha256:bd1aa4f9915c98e8aaebcd4e71930154d4e8c9aaf05d35ac0a63d1956091ae3f"},
365 | ]
366 | black = [
367 | {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"},
368 | {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"},
369 | {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"},
370 | {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"},
371 | {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"},
372 | {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"},
373 | {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"},
374 | {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"},
375 | {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"},
376 | {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"},
377 | {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"},
378 | {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"},
379 | {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"},
380 | {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"},
381 | {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"},
382 | {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"},
383 | {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"},
384 | {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"},
385 | {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"},
386 | {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"},
387 | {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"},
388 | {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"},
389 | {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"},
390 | {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"},
391 | {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"},
392 | ]
393 | certifi = [
394 | {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
395 | {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
396 | ]
397 | charset-normalizer = [
398 | {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"},
399 | {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"},
400 | {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"},
401 | {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"},
402 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"},
403 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"},
404 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"},
405 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"},
406 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"},
407 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"},
408 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"},
409 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"},
410 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"},
411 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"},
412 | {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"},
413 | {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"},
414 | {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"},
415 | {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"},
416 | {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"},
417 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"},
418 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"},
419 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"},
420 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"},
421 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"},
422 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"},
423 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"},
424 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"},
425 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"},
426 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"},
427 | {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"},
428 | {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"},
429 | {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"},
430 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"},
431 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"},
432 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"},
433 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"},
434 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"},
435 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"},
436 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"},
437 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"},
438 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"},
439 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"},
440 | {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"},
441 | {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"},
442 | {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"},
443 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"},
444 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"},
445 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"},
446 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"},
447 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"},
448 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"},
449 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"},
450 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"},
451 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"},
452 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"},
453 | {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"},
454 | {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"},
455 | {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"},
456 | {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"},
457 | {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"},
458 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"},
459 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"},
460 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"},
461 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"},
462 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"},
463 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"},
464 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"},
465 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"},
466 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"},
467 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"},
468 | {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"},
469 | {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"},
470 | {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"},
471 | {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"},
472 | {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"},
473 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"},
474 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"},
475 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"},
476 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"},
477 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"},
478 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"},
479 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"},
480 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"},
481 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"},
482 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"},
483 | {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"},
484 | {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"},
485 | {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"},
486 | ]
487 | click = [
488 | {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
489 | {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
490 | ]
491 | colorama = [
492 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
493 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
494 | ]
495 | dill = [
496 | {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"},
497 | {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"},
498 | ]
499 | h11 = [
500 | {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
501 | {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
502 | ]
503 | httpcore = [
504 | {file = "httpcore-0.16.3-py3-none-any.whl", hash = "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"},
505 | {file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"},
506 | ]
507 | httpx = [
508 | {file = "httpx-0.23.3-py3-none-any.whl", hash = "sha256:a211fcce9b1254ea24f0cd6af9869b3d29aba40154e947d2a07bb499b3e310d6"},
509 | {file = "httpx-0.23.3.tar.gz", hash = "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9"},
510 | ]
511 | idna = [
512 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
513 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
514 | ]
515 | isort = [
516 | {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
517 | {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
518 | ]
519 | lazy-object-proxy = [
520 | {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"},
521 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"},
522 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"},
523 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"},
524 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"},
525 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"},
526 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"},
527 | {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"},
528 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"},
529 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"},
530 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"},
531 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"},
532 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"},
533 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"},
534 | {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"},
535 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"},
536 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"},
537 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"},
538 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"},
539 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"},
540 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"},
541 | {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"},
542 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"},
543 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"},
544 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"},
545 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"},
546 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"},
547 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"},
548 | {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"},
549 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"},
550 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"},
551 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"},
552 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"},
553 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"},
554 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"},
555 | {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"},
556 | ]
557 | loguru = [
558 | {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
559 | {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
560 | ]
561 | mccabe = [
562 | {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
563 | {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
564 | ]
565 | mypy-extensions = [
566 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
567 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
568 | ]
569 | packaging = [
570 | {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
571 | {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
572 | ]
573 | pathspec = [
574 | {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"},
575 | {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"},
576 | ]
577 | platformdirs = [
578 | {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
579 | {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
580 | ]
581 | plexapi = [
582 | {file = "PlexAPI-4.13.2-py3-none-any.whl", hash = "sha256:4a7cd6729061419abd600de9c436bdf9565976a873d0a74487606c4126b98439"},
583 | {file = "PlexAPI-4.13.2.tar.gz", hash = "sha256:2a67b5739ec966e10dec957fea8abe38e9a4ff9d6b58dd0ec6a55ae758cead8e"},
584 | ]
585 | pylint = [
586 | {file = "pylint-2.16.1-py3-none-any.whl", hash = "sha256:bad9d7c36037f6043a1e848a43004dfd5ea5ceb05815d713ba56ca4503a9fe37"},
587 | {file = "pylint-2.16.1.tar.gz", hash = "sha256:ffe7fa536bb38ba35006a7c8a6d2efbfdd3d95bbf21199cad31f76b1c50aaf30"},
588 | ]
589 | pypresence = [
590 | {file = "pypresence-4.2.1-py2.py3-none-any.whl", hash = "sha256:12197b5f51c21e3e555b17f85d3e55023f4ad83b6fff72cd6387659ffd484a02"},
591 | {file = "pypresence-4.2.1.tar.gz", hash = "sha256:691daf98c8189fd216d988ebfc67779e0f664211512d9843f37ab0d51d4de066"},
592 | ]
593 | requests = [
594 | {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
595 | {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
596 | ]
597 | rfc3986 = [
598 | {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"},
599 | {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"},
600 | ]
601 | sniffio = [
602 | {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
603 | {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
604 | ]
605 | tomlkit = [
606 | {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"},
607 | {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"},
608 | ]
609 | urllib3 = [
610 | {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
611 | {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
612 | ]
613 | win32-setctime = [
614 | {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
615 | {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
616 | ]
617 | wrapt = [
618 | {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
619 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"},
620 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"},
621 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"},
622 | {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"},
623 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"},
624 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"},
625 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"},
626 | {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"},
627 | {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"},
628 | {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"},
629 | {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"},
630 | {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"},
631 | {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"},
632 | {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"},
633 | {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"},
634 | {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"},
635 | {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"},
636 | {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"},
637 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"},
638 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"},
639 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"},
640 | {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"},
641 | {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"},
642 | {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"},
643 | {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"},
644 | {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"},
645 | {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"},
646 | {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"},
647 | {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"},
648 | {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"},
649 | {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"},
650 | {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"},
651 | {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"},
652 | {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"},
653 | {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"},
654 | {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"},
655 | {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"},
656 | {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"},
657 | {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"},
658 | {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"},
659 | {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"},
660 | {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"},
661 | {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"},
662 | {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"},
663 | {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"},
664 | {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"},
665 | {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"},
666 | {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"},
667 | {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"},
668 | {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"},
669 | {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"},
670 | {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"},
671 | {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"},
672 | {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"},
673 | {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"},
674 | {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"},
675 | {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"},
676 | {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"},
677 | {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"},
678 | {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"},
679 | {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"},
680 | {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"},
681 | {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"},
682 | ]
683 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "Perplex"
3 | version = "1.0.1"
4 | description = "Discord Rich Presence implementation for Plex."
5 | authors = ["Ethan C <16727756+EthanC@users.noreply.github.com>"]
6 | license = "MIT"
7 |
8 | [tool.poetry.dependencies]
9 | python = "^3.11"
10 | loguru = "^0.6.0"
11 | PlexAPI = "^4.13.2"
12 | httpx = "^0.23.3"
13 | pypresence = "^4.2.1"
14 |
15 | [tool.poetry.dev-dependencies]
16 | pylint = "^2.16.1"
17 | black = "^23.1.0"
18 |
19 | [build-system]
20 | requires = ["poetry-core"]
21 | build-backend = "poetry.core.masonry.api"
22 |
--------------------------------------------------------------------------------
/start.ps1:
--------------------------------------------------------------------------------
1 | # Activate virtual environment
2 | .venv/scripts/activate.ps1
3 |
4 | # Run Python script
5 | python perplex.py
6 |
--------------------------------------------------------------------------------