Error running sync command: 'str' object cannot be interpreted as an integer
usma0118 opened this issue · comments
Confirmation
- I have read the README.md on the project homepage
- I have checked if identical issue already exists
- I have tried downgrading to find version that can be used as a workaround
The problem
Error when running container.
I have copied config and able to run sync in python venv without any issues.
Originally posted by @usma0118 in #1969
Steps to reproduce the behavior
Trying to run plex trakt sync in docker (kubernetes).
After deployment, i am getting TypeError: 'str' object cannot be interpreted as an integer
Error trace / logs
User
WARNING plextraktsync without command is deprecated. Executing "plextraktsync sync"
INFO PlexTraktSync [0.30.10]
INFO Connecting with url: http://plex.media.svc.cluster.local:32400, timeout 30 seconds
ERROR ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
INFO Connecting with url: https://192-100-1-202.*************************.plex.direct:32400, timeout 30 seconds
INFO Sync Movie sections: ['Movies', ***', '***']
INFO Sync Show sections: ['*****', '*****', 'Cartoon', 'Documentary shows', 'TV Shows']
INFO Enable sync plugin 'AddCollectionPlugin': False
INFO Enable sync plugin 'ClearCollectedPlugin': False
INFO Enable sync plugin 'LikedListsPlugin': False
INFO Enable sync plugin 'SyncRatingsPlugin': True
INFO Enable sync plugin 'SyncWatchedPlugin': True
INFO Enable sync plugin 'TraktListsPlugin': False
INFO Enable sync plugin 'WatchListPlugin': False
INFO Enable sync plugin 'WatchProgressPlugin': False
Processing Movies 0% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1/791 [ 0:00:00 < -:--:-- , ? it/s ]
ERROR 'str' object cannot be interpreted as an integer
╭───────────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────────╮
│ /app/plextraktsync/cli.py:26 in wrap │
│ │
│ 23 │ │ │ cmd = getattr(module, name) │
│ 24 │ │ │ │
│ 25 │ │ │ try: │
│ ❱ 26 │ │ │ │ cmd(*args, **kwargs) │
│ 27 │ │ │ except EOFError as e: │
│ 28 │ │ │ │ raise ClickException(f"Program requested terminal, No terminal is │
│ connected: {e}") │
│ 29 │ │ │ except ClickException as e: │
│ │
│ /app/plextraktsync/commands/sync.py:76 in sync │
│ │
│ 73 │ │ │ w.print_plan(print=logger.info) │
│ 74 │ │ if dry_run: │
│ 75 │ │ │ logger.info("Enabled dry-run mode: not making actual changes") │
│ ❱ 76 │ │ run_async(runner, walker=w, dry_run=config.dry_run) │
│ 77 │
│ │
│ /usr/local/lib/python3.12/site-packages/decorator.py:232 in fun │
│ │
│ 229 │ │ def fun(*args, **kw): │
│ 230 │ │ │ if not kwsyntax: │
│ 231 │ │ │ │ args, kw = fix(args, kw, sig) │
│ ❱ 232 │ │ │ return caller(func, *(extras + args), **kw) │
│ 233 │ fun.__name__ = func.__name__ │
│ 234 │ fun.__doc__ = func.__doc__ │
│ 235 │ fun.__wrapped__ = func │
│ │
│ /app/plextraktsync/decorators/coro.py:13 in coro │
│ │
│ 10 │ │
│ 11 │ https://github.com/pallets/click/issues/85#issuecomment-503464628 │
│ 12 │ """ │
│ ❱ 13 │ return asyncio.run(f(*args, **kwargs)) │
│ 14 │
│ │
│ /usr/local/lib/python3.12/asyncio/runners.py:194 in run │
│ │
│ 191 │ │ │ "asyncio.run() cannot be called from a running event loop") │
│ 192 │ │
│ 193 │ with Runner(debug=debug, loop_factory=loop_factory) as runner: │
│ ❱ 194 │ │ return runner.run(main) │
│ 195 │
│ 196 │
│ 197 def _cancel_all_tasks(loop): │
│ │
│ /usr/local/lib/python3.12/asyncio/runners.py:118 in run │
│ │
│ 115 │ │ │
│ 116 │ │ self._interrupt_count = 0 │
│ 117 │ │ try: │
│ ❱ 118 │ │ │ return self._loop.run_until_complete(task) │
│ 119 │ │ except exceptions.CancelledError: │
│ 120 │ │ │ if self._interrupt_count > 0: │
│ 121 │ │ │ │ uncancel = getattr(task, "uncancel", None) │
│ │
│ /usr/local/lib/python3.12/asyncio/base_events.py:687 in run_until_complete │
│ │
│ 684 │ │ if not future.done(): │
│ 685 │ │ │ raise RuntimeError('Event loop stopped before Future completed.') │
│ 686 │ │ │
│ ❱ 687 │ │ return future.result() │
│ 688 │ │
│ 689 │ def stop(self): │
│ 690 │ │ """Stop running the event loop. │
│ │
│ /app/plextraktsync/commands/sync.py:13 in run_async │
│ │
│ 10 │
│ 11 @coro │
│ 12 async def run_async(runner, **kwargs): │
│ ❱ 13 │ await runner.sync(**kwargs) │
│ 14 │
│ 15 │
│ 16 def sync( │
│ │
│ /app/plextraktsync/sync/Sync.py:46 in sync │
│ │
│ 43 │ │ pm.hook.init(sync=self, pm=pm, is_partial=is_partial, dry_run=dry_run) │
│ 44 │ │ │
│ 45 │ │ if self.config.need_library_walk: │
│ ❱ 46 │ │ │ async for movie in walker.find_movies(): │
│ 47 │ │ │ │ await pm.ahook.walk_movie(movie=movie, dry_run=dry_run) │
│ 48 │ │ │ │
│ 49 │ │ │ async for episode in walker.find_episodes(): │
│ │
│ /app/plextraktsync/plan/Walker.py:90 in find_movies │
│ │
│ 87 │ │
│ 88 │ async def find_movies(self) -> Generator[Media, Any, None]: │
│ 89 │ │ async for plex in self.get_plex_movies(): │
│ ❱ 90 │ │ │ movie = self.mf.resolve_any(plex) │
│ 91 │ │ │ if not movie: │
│ 92 │ │ │ │ continue │
│ 93 │ │ │ yield movie │
│ │
│ /app/plextraktsync/media/MediaFactory.py:38 in resolve_any │
│ │
│ 35 │ │ │ return None │
│ 36 │ │ │
│ 37 │ │ for guid in guids: │
│ ❱ 38 │ │ │ m = self.resolve_guid(guid, show) │
│ 39 │ │ │ if m: │
│ 40 │ │ │ │ self.logger.debug(f"Resolved {guid} of {guid.pm} to {m}") │
│ 41 │ │ │ │ return m │
│ │
│ /app/plextraktsync/media/MediaFactory.py:67 in resolve_guid │
│ │
│ 64 │ │ │ if show: │
│ 65 │ │ │ │ tm = self.trakt.find_episode_guid(guid, show.seasons) │
│ 66 │ │ │ else: │
│ ❱ 67 │ │ │ │ tm = self.trakt.find_by_guid(guid) │
│ 68 │ │ except (TraktException, RequestException) as e: │
│ 69 │ │ │ self.logger.warning(f"{guid.title_link}: Skipping {guid}: Trakt errors: │
│ {e}", extra={"markup": True}) │
│ 70 │ │ │ return None │
│ │
│ /app/plextraktsync/trakt/TraktApi.py:253 in find_by_guid │
│ │
│ 250 │ │ if guid.type == "episode" and guid.is_episode: │
│ 251 │ │ │ return self.find_by_episode_guid(guid) │
│ 252 │ │ else: │
│ ❱ 253 │ │ │ tm = self.search_by_id(guid.id, id_type=guid.provider, media_type=guid.type) │
│ 254 │ │ │ if tm is None and guid.type == "movie": │
│ 255 │ │ │ │ if self.search_by_id(guid.id, id_type=guid.provider, media_type="show"): │
│ 256 │ │ │ │ │ self.logger.warning(f"Found match using show search: │
│ {guid.title_link}", extra={"markup": True}) │
│ │
│ /usr/local/lib/python3.12/site-packages/decorator.py:232 in fun │
│ │
│ 229 │ │ def fun(*args, **kw): │
│ 230 │ │ │ if not kwsyntax: │
│ 231 │ │ │ │ args, kw = fix(args, kw, sig) │
│ ❱ 232 │ │ │ return caller(func, *(extras + args), **kw) │
│ 233 │ fun.__name__ = func.__name__ │
│ 234 │ fun.__doc__ = func.__doc__ │
│ 235 │ fun.__wrapped__ = func │
│ │
│ /app/plextraktsync/decorators/rate_limit.py:19 in rate_limit │
│ │
│ 16 │ retry = 0 │
│ 17 │ while True: │
│ 18 │ │ try: │
│ ❱ 19 │ │ │ return fn(*args, **kwargs) │
│ 20 │ │ except RateLimitException as e: │
│ 21 │ │ │ if retry == retries: │
│ 22 │ │ │ │ logger.error(f"Trakt Error: {e}") │
│ │
│ /usr/local/lib/python3.12/site-packages/decorator.py:232 in fun │
│ │
│ 229 │ │ def fun(*args, **kw): │
│ 230 │ │ │ if not kwsyntax: │
│ 231 │ │ │ │ args, kw = fix(args, kw, sig) │
│ ❱ 232 │ │ │ return caller(func, *(extras + args), **kw) │
│ 233 │ fun.__name__ = func.__name__ │
│ 234 │ fun.__doc__ = func.__doc__ │
│ 235 │ fun.__wrapped__ = func │
│ │
│ /app/plextraktsync/decorators/retry.py:24 in retry │
│ │
│ 21 │ count = 0 │
│ 22 │ while True: │
│ 23 │ │ try: │
│ ❱ 24 │ │ │ return fn(*args, **kwargs) │
│ 25 │ │ except ( │
│ 26 │ │ │ BadRequest, │
│ 27 │ │ │ BadResponseException, │
│ │
│ /app/plextraktsync/trakt/TraktApi.py:293 in search_by_id │
│ │
│ 290 │ │ │ │
│ 291 │ │ │ return None │
│ 292 │ │ │
│ ❱ 293 │ │ search = trakt.sync.search_by_id( │
│ 294 │ │ │ media_id, id_type=id_type, media_type=media_type │
│ 295 │ │ ) │
│ 296 │ │ if not search: │
│ │
│ /usr/local/lib/python3.12/site-packages/trakt/core.py:573 in inner │
│ │
│ 570 │ │ """ │
│ 571 │ │ @wraps(f) │
│ 572 │ │ def inner(*args, **kwargs): │
│ ❱ 573 │ │ │ self._bootstrap() │
│ 574 │ │ │ resp = self._get_first(f, *args, **kwargs) │
│ 575 │ │ │ if not isinstance(resp, tuple): │
│ 576 │ │ │ │ # Handle cached property responses │
│ │
│ /usr/local/lib/python3.12/site-packages/trakt/core.py:504 in _bootstrap │
│ │
│ 501 │ │ # Check token validity and refresh token if needed │
│ 502 │ │ if (not OAUTH_TOKEN_VALID and OAUTH_EXPIRES_AT is not None │
│ 503 │ │ │ │ and OAUTH_REFRESH is not None): │
│ ❱ 504 │ │ │ _validate_token(self) │
│ 505 │ │
│ 506 │ @staticmethod │
│ 507 │ def _get_first(f, *args, **kwargs): │
│ │
│ /usr/local/lib/python3.12/site-packages/trakt/core.py:399 in _validate_token │
│ │
│ 396 │ """Check if current OAuth token has not expired""" │
│ 397 │ global OAUTH_TOKEN_VALID │
│ 398 │ current = datetime.now(tz=timezone.utc) │
│ ❱ 399 │ expires_at = datetime.fromtimestamp(OAUTH_EXPIRES_AT, tz=timezone.utc) │
│ 400 │ if expires_at - current > timedelta(days=2): │
│ 401 │ │ OAUTH_TOKEN_VALID = True │
│ 402 │ else: │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: 'str' object cannot be interpreted as an integer
Error: Error running sync command: 'str' object cannot be interpreted as an integer
Expected behavior
sync should work
Inspect of problematic items
No response
Workarounds
No response
Config file contents
---
cache:
path: $PTS_CACHE_DIR/trakt_cache
excluded-libraries:
- Music
config:
dotenv_override: true
logging:
append: false
debug: false
filename: plextraktsync.log
sync:
plex_to_trakt:
collection: false
ratings: true
watched_status: true
# If plex_to_trakt watchlist=false and trakt_to_plex watchlist=true
# the Plex watchlist will be overwritten by Trakt watchlist
watchlist: false
trakt_to_plex:
liked_lists: false
ratings: true
watched_status: true
watchlist: false
watchlist_as_playlist: true
# Setting for whether ratings from one platform should have priority.
# Valid values are trakt, plex or none. (default: plex)
# none - No rating priority. Existing ratings are not overwritten.
# trakt - Trakt ratings have priority. Existing Plex ratings are overwritten.
# plex - Plex ratings have priority. Existing Trakt ratings are overwritten.
rating_priority: plex
watch:
add_collection: false
remove_collection: true
scrobble_threshold: 90
username_filter: true
xbmc-providers:
movies: imdb
shows: tvdb
Install method
docker-compose
Version
0.30.10@sha256:87845233a95ed875db07084984f2040403daf6eb411ddd52dbd60e1b0c967665
Python Version
3.7
Plex Server Version
1.4.0
Operating System and Version
Kubernetes running on Ubuntu server
Seems something wrong with your trakt api credentials: .pytrakt.json
Very likely, You can delete the file to work around the problem.
But to fix the problem you need to provide example of the file. Redact out actual token values to keep your privacy when sharing.
here goes .pytrakt
{"CLIENT_ID": "************************************", "CLIENT_SECRET": "***********************************","OAUTH_TOKEN": "*****************************************************500a6192","OAUTH_REFRESH": "19fd25fe0028e0b****************************************************f","OAUTH_EXPIRES_AT": "1724853786"}
ok, found the issue. since i was mounting .pytrakt file from externasecret (kubernetes).
it was creating expires at as string.
Now fixed.