[BUG] 2.0.5 does not work with Tidal on windows
Describe the bug
I installed latest Python version, latest ffmep and uses this line to install streamrip pip3 install streamrip --upgrade
Then I tried and failed hard
C:\Windows\system32>rip search tidal playlist 'rap'
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiodns\__init__.py:58 in │
│ __init__ │
│ │
│ 55 │ │ if sys.platform == 'win32': │
│ 56 │ │ │ if not isinstance(self.loop, asyncio.SelectorEventLoop): │
│ 57 │ │ │ │ try: │
│ > 58 │ │ │ │ │ import winloop │
│ 59 │ │ │ │ │ if not isinstance(self.loop , winloop.Loop): │
│ 60 │ │ │ │ │ │ raise RuntimeError( │
│ 61 │ │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: http │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
ModuleNotFoundError: No module named 'winloop'
During handling of the above exception, another exception occurred:
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ in _run_module_as_main:198 │
│ in _run_code:88 │
│ │
│ ... 19 frames hidden ... │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiohttp\resolver.py:93 in │
│ __init__ │
│ │
│ 90 │ │ if aiodns is None: │
│ 91 │ │ │ raise RuntimeError("Resolver requires aiodns library") │
│ 92 │ │ │
│ > 93 │ │ self._resolver = aiodns.DNSResolver(*args, **kwargs) │
│ 94 │ │ │
│ 95 │ │ if not hasattr(self._resolver, "gethostbyname"): │
│ 96 │ │ │ # aiodns 1.1 is not available, fallback to DNSResolver.query │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiodns\__init__.py:63 in │
│ __init__ │
│ │
│ 60 │ │ │ │ │ │ raise RuntimeError( │
│ 61 │ │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: http │
│ 62 │ │ │ │ except ModuleNotFoundError: │
│ > 63 │ │ │ │ │ raise RuntimeError( │
│ 64 │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: https:// │
│ 65 │ │ kwargs.pop('sock_state_cb', None) │
│ 66 │ │ timeout = kwargs.pop('timeout', None) │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
RuntimeError: aiodns needs a SelectorEventLoop on Windows. See more: https://github.com/saghul/aiodns/issues/86
I researched that and found this bug: https://github.com/nathom/streamrip/issues/729
When I run pip3 install aiohttp==3.9.5 I get this error
C:\Windows\system32>pip3 install aiohttp==3.9.5
Collecting aiohttp==3.9.5
Using cached aiohttp-3.9.5.tar.gz (7.5 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: aiosignal>=1.1.2 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from aiohttp==3.9.5) (1.3.2)
Requirement already satisfied: attrs>=17.3.0 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from aiohttp==3.9.5) (24.3.0)
Requirement already satisfied: frozenlist>=1.1.1 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from aiohttp==3.9.5) (1.5.0)
Requirement already satisfied: multidict<7.0,>=4.5 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from aiohttp==3.9.5) (6.1.0)
Requirement already satisfied: yarl<2.0,>=1.0 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from aiohttp==3.9.5) (1.18.3)
Requirement already satisfied: idna>=2.0 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from yarl<2.0,>=1.0->aiohttp==3.9.5) (3.10)
Requirement already satisfied: propcache>=0.2.0 in c:\users\trj\appdata\local\programs\python\python313\lib\site-packages (from yarl<2.0,>=1.0->aiohttp==3.9.5) (0.2.1)
Building wheels for collected packages: aiohttp
Building wheel for aiohttp (pyproject.toml) ... error
error: subprocess-exited-with-error
× Building wheel for aiohttp (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [93 lines of output]
*********************
* Accelerated build *
*********************
running bdist_wheel
running build
running build_py
creating build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\abc.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\base_protocol.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\client.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\client_exceptions.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\client_proto.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\client_reqrep.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\client_ws.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\compression_utils.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\connector.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\cookiejar.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\formdata.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\hdrs.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\helpers.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\http.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\http_exceptions.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\http_parser.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\http_websocket.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\http_writer.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\locks.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\log.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\multipart.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\payload.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\payload_streamer.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\pytest_plugin.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\resolver.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\streams.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\tcp_helpers.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\test_utils.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\tracing.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\typedefs.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_app.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_exceptions.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_fileresponse.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_log.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_middlewares.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_protocol.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_request.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_response.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_routedef.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_runner.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_server.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_urldispatcher.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\web_ws.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\worker.py -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\__init__.py -> build\lib.win-amd64-cpython-313\aiohttp
running egg_info
writing aiohttp.egg-info\PKG-INFO
writing dependency_links to aiohttp.egg-info\dependency_links.txt
writing requirements to aiohttp.egg-info\requires.txt
writing top-level names to aiohttp.egg-info\top_level.txt
reading manifest file 'aiohttp.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching 'aiohttp' anywhere in distribution
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*.pyd' found anywhere in distribution
warning: no previously-included files matching '*.so' found anywhere in distribution
warning: no previously-included files matching '*.lib' found anywhere in distribution
warning: no previously-included files matching '*.dll' found anywhere in distribution
warning: no previously-included files matching '*.a' found anywhere in distribution
warning: no previously-included files matching '*.obj' found anywhere in distribution
warning: no previously-included files found matching 'aiohttp\*.html'
no previously-included directories found matching 'docs\_build'
adding license file 'LICENSE.txt'
writing manifest file 'aiohttp.egg-info\SOURCES.txt'
copying aiohttp\_cparser.pxd -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_find_header.pxd -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_headers.pxi -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_helpers.pyi -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_helpers.pyx -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_http_parser.pyx -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_http_writer.pyx -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\_websocket.pyx -> build\lib.win-amd64-cpython-313\aiohttp
copying aiohttp\py.typed -> build\lib.win-amd64-cpython-313\aiohttp
creating build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_cparser.pxd.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_find_header.pxd.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_helpers.pyi.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_helpers.pyx.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_http_parser.pyx.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_http_writer.pyx.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\_websocket.pyx.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
copying aiohttp\.hash\hdrs.py.hash -> build\lib.win-amd64-cpython-313\aiohttp\.hash
running build_ext
building 'aiohttp._websocket' extension
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for aiohttp
Failed to build aiohttp
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (aiohttp)
I have Visual C++ 14.0 x86 and x64 installed and even downloaded it again and choose "repair". Did not work.
Then I downloaded from https://visualstudio.microsoft.com/visual-cpp-build-tools/, but I have no idea what I have to select to install
Command Used
rip search tidal playlist 'rap'
and
pip3 install aiohttp==3.9.5
Debug Traceback
[19:37:24] DEBUG Showing all debug logs cli.py:102
DEBUG Removing dirs set() artwork.py:19
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiodns\__init__.py:58 in │
│ __init__ │
│ │
│ 55 │ │ if sys.platform == 'win32': │
│ 56 │ │ │ if not isinstance(self.loop, asyncio.SelectorEventLoop): │
│ 57 │ │ │ │ try: │
│ > 58 │ │ │ │ │ import winloop │
│ 59 │ │ │ │ │ if not isinstance(self.loop , winloop.Loop): │
│ 60 │ │ │ │ │ │ raise RuntimeError( │
│ 61 │ │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: http │
│ │
│ ┌──────────────────────────── locals ─────────────────────────────┐ │
│ │ kwargs = {} │ │
│ │ loop = None │ │
│ │ nameservers = None │ │
│ │ self = <aiodns.DNSResolver object at 0x000001A466F3B0E0> │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
ModuleNotFoundError: No module named 'winloop'
During handling of the above exception, another exception occurred:
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ in _run_module_as_main:198 │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ alter_argv = False │ │
│ │ code = <code object <module> at 0x000001A4641A5E30, file │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\__main… │ │
│ │ line 1> │ │
│ │ main_globals = { │ │
│ │ │ '__name__': '__main__', │ │
│ │ │ '__doc__': None, │ │
│ │ │ '__package__': '', │ │
│ │ │ '__loader__': <zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\">, │ │
│ │ │ '__spec__': ModuleSpec(name='__main__', loader=<zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\">, │ │
│ │ origin='C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts… │ │
│ │ │ '__annotations__': {}, │ │
│ │ │ '__builtins__': <module 'builtins' (built-in)>, │ │
│ │ │ '__file__': │ │
│ │ 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\rip.e… │ │
│ │ │ '__cached__': │ │
│ │ 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\rip.e… │ │
│ │ │ 're': <module 're' from │ │
│ │ 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\re\\__ini… │ │
│ │ │ ... +2 │ │
│ │ } │ │
│ │ mod_name = '__main__' │ │
│ │ mod_spec = ModuleSpec(name='__main__', loader=<zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\">, │ │
│ │ origin='C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts… │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ in _run_code:88 │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ cached = 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\rip.e… │ │
│ │ code = <code object <module> at 0x000001A4641A5E30, file │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\__main… │ │
│ │ line 1> │ │
│ │ fname = 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\rip.e… │ │
│ │ init_globals = None │ │
│ │ loader = <zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\"> │ │
│ │ mod_name = '__main__' │ │
│ │ mod_spec = ModuleSpec(name='__main__', loader=<zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\">, │ │
│ │ origin='C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts… │ │
│ │ pkg_name = '' │ │
│ │ run_globals = { │ │
│ │ │ '__name__': '__main__', │ │
│ │ │ '__doc__': None, │ │
│ │ │ '__package__': '', │ │
│ │ │ '__loader__': <zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\">, │ │
│ │ │ '__spec__': ModuleSpec(name='__main__', loader=<zipimporter object │ │
│ │ "C:\Users\trj\AppData\Local\Programs\Python\Python313\Scripts\rip.exe\">, │ │
│ │ origin='C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts… │ │
│ │ │ '__annotations__': {}, │ │
│ │ │ '__builtins__': <module 'builtins' (built-in)>, │ │
│ │ │ '__file__': │ │
│ │ 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\rip.e… │ │
│ │ │ '__cached__': │ │
│ │ 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\rip.e… │ │
│ │ │ 're': <module 're' from │ │
│ │ 'C:\\Users\\trj\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\re\\__ini… │ │
│ │ │ ... +2 │ │
│ │ } │ │
│ │ script_name = None │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ in <module>:7 │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py:1161 in │
│ __call__ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py:1082 in │
│ main │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py:1697 in │
│ invoke │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py:1443 in │
│ invoke │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py:788 in │
│ invoke │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\decorators.py:33 in │
│ new_func │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\rip\cli.py:28 │
│ in wrapper │
│ │
│ 25 def coro(f): │
│ 26 │ @wraps(f) │
│ 27 │ def wrapper(*args, **kwargs): │
│ > 28 │ │ return asyncio.run(f(*args, **kwargs)) │
│ 29 │ │
│ 30 │ return wrapper │
│ 31 │
│ │
│ ┌─────────────────────────── locals ────────────────────────────┐ │
│ │ args = (<click.core.Context object at 0x000001A466EF6FD0>,) │ │
│ │ kwargs = { │ │
│ │ │ 'source': 'tidal', │ │
│ │ │ 'media_type': 'playlist', │ │
│ │ │ 'query': "'rap'", │ │
│ │ │ 'first': False, │ │
│ │ │ 'output_file': None, │ │
│ │ │ 'num_results': 100 │ │
│ │ } │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\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): │
│ │
│ ┌─────────────────────────────── locals ───────────────────────────────┐ │
│ │ debug = None │ │
│ │ loop_factory = None │ │
│ │ main = <coroutine object search at 0x000001A466EE56D0> │ │
│ │ runner = <asyncio.runners.Runner object at 0x000001A466F38830> │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\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) │
│ │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ context = <_contextvars.Context object at 0x000001A46704A480> │ │
│ │ coro = <coroutine object search at 0x000001A466EE56D0> │ │
│ │ self = <asyncio.runners.Runner object at 0x000001A466F38830> │ │
│ │ sigint_handler = functools.partial(<bound method Runner._on_sigint of │ │
│ │ <asyncio.runners.Runner object at 0x000001A466F38830>>, main_task=<Task │ │
│ │ finished name='Task-1' coro=<search() done, defined at │ │
│ │ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\str… │ │
│ │ exception=RuntimeError('aiodns needs a SelectorEventLoop on Windows. See │ │
│ │ more: https://github.com/saghul/aiodns/issues/86')>) │ │
│ │ task = <Task finished name='Task-1' coro=<search() done, defined at │ │
│ │ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\str… │ │
│ │ exception=RuntimeError('aiodns needs a SelectorEventLoop on Windows. See │ │
│ │ more: https://github.com/saghul/aiodns/issues/86')> │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\asyncio\base_events.py:720 in │
│ run_until_complete │
│ │
│ 717 │ │ if not future.done(): │
│ 718 │ │ │ raise RuntimeError('Event loop stopped before Future completed.') │
│ 719 │ │ │
│ > 720 │ │ return future.result() │
│ 721 │ │
│ 722 │ def stop(self): │
│ 723 │ │ """Stop running the event loop. │
│ │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ future = <Task finished name='Task-1' coro=<search() done, defined at │ │
│ │ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip… │ │
│ │ exception=RuntimeError('aiodns needs a SelectorEventLoop on Windows. See more: │ │
│ │ https://github.com/saghul/aiodns/issues/86')> │ │
│ │ new_task = False │ │
│ │ self = <ProactorEventLoop running=False closed=True debug=False> │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\rip\cli.py:371 │
│ in search │
│ │
│ 368 │ │ │ │ │ source, media_type, query, output_file, num_results │
│ 369 │ │ │ │ ) │
│ 370 │ │ │ else: │
│ > 371 │ │ │ │ await main.search_interactive(source, media_type, query) │
│ 372 │ │ │ await main.resolve() │
│ 373 │ │ │ await main.rip() │
│ 374 │
│ │
│ ┌─────────────────────────────── locals ───────────────────────────────┐ │
│ │ cfg = <streamrip.config.Config object at 0x000001A466F38440> │ │
│ │ ctx = <click.core.Context object at 0x000001A466EF6FD0> │ │
│ │ first = False │ │
│ │ main = <streamrip.rip.main.Main object at 0x000001A466F397F0> │ │
│ │ media_type = 'playlist' │ │
│ │ num_results = 100 │ │
│ │ output_file = None │ │
│ │ query = "'rap'" │ │
│ │ source = 'tidal' │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\rip\main.py:168 │
│ in search_interactive │
│ │
│ 165 │ │ await asyncio.gather(*[item.rip() for item in self.media]) │
│ 166 │ │
│ 167 │ async def search_interactive(self, source: str, media_type: str, query: str): │
│ > 168 │ │ client = await self.get_logged_in_client(source) │
│ 169 │ │ │
│ 170 │ │ with console.status(f"[bold]Searching {source}", spinner="dots"): │
│ 171 │ │ │ pages = await client.search(media_type, query, limit=100) │
│ │
│ ┌────────────────────────────── locals ───────────────────────────────┐ │
│ │ media_type = 'playlist' │ │
│ │ query = "'rap'" │ │
│ │ self = <streamrip.rip.main.Main object at 0x000001A466F397F0> │ │
│ │ source = 'tidal' │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\rip\main.py:142 │
│ in get_logged_in_client │
│ │
│ 139 │ │ │ prompter = get_prompter(client, self.config) │
│ 140 │ │ │ if not prompter.has_creds(): │
│ 141 │ │ │ │ # Get credentials from user and log into client │
│ > 142 │ │ │ │ await prompter.prompt_and_login() │
│ 143 │ │ │ │ prompter.save() │
│ 144 │ │ │ else: │
│ 145 │ │ │ │ with console.status(f"[cyan]Logging into {source}", spinner="dots"): │
│ │
│ ┌──────────────────────────────────── locals ────────────────────────────────────┐ │
│ │ client = <streamrip.client.tidal.TidalClient object at 0x000001A466F39A90> │ │
│ │ prompter = <streamrip.rip.prompter.TidalPrompter object at 0x000001A466F3ABA0> │ │
│ │ self = <streamrip.rip.main.Main object at 0x000001A466F397F0> │ │
│ │ source = 'tidal' │ │
│ └────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\rip\prompter.py │
│ :101 in prompt_and_login │
│ │
│ 98 │ │ return len(self.config.session.tidal.access_token) > 0 │
│ 99 │ │
│ 100 │ async def prompt_and_login(self): │
│ > 101 │ │ device_code, uri = await self.client._get_device_code() │
│ 102 │ │ login_link = f"https://{uri}" │
│ 103 │ │ │
│ 104 │ │ console.print( │
│ │
│ ┌────────────────────────────────── locals ──────────────────────────────────┐ │
│ │ self = <streamrip.rip.prompter.TidalPrompter object at 0x000001A466F3ABA0> │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\client\tidal.py │
│ :282 in _get_device_code │
│ │
│ 279 │ async def _get_device_code(self) -> tuple[str, str]: │
│ 280 │ │ """Get the device code that will be used to log in on the browser.""" │
│ 281 │ │ if not hasattr(self, "session"): │
│ > 282 │ │ │ self.session = await self.get_session() │
│ 283 │ │ │
│ 284 │ │ data = { │
│ 285 │ │ │ "client_id": CLIENT_ID, │
│ │
│ ┌───────────────────────────────── locals ─────────────────────────────────┐ │
│ │ self = <streamrip.client.tidal.TidalClient object at 0x000001A466F39A90> │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\streamrip\client\client.p │
│ y:55 in get_session │
│ │
│ 52 │ async def get_session(headers: dict | None = None) -> aiohttp.ClientSession: │
│ 53 │ │ if headers is None: │
│ 54 │ │ │ headers = {} │
│ > 55 │ │ return aiohttp.ClientSession( │
│ 56 │ │ │ headers={"User-Agent": DEFAULT_USER_AGENT}, │
│ 57 │ │ │ **headers, │
│ 58 │ │ ) │
│ │
│ ┌─── locals ───┐ │
│ │ headers = {} │ │
│ └──────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiohttp\client.py:359 in │
│ __init__ │
│ │
│ 356 │ │ │ │ ) │
│ 357 │ │ │
│ 358 │ │ if connector is None: │
│ > 359 │ │ │ connector = TCPConnector(loop=loop) │
│ 360 │ │ │
│ 361 │ │ if connector._loop is not loop: │
│ 362 │ │ │ raise RuntimeError("Session and connector has to use same event loop") │
│ │
│ ┌─────────────────────────────────────────── locals ───────────────────────────────────────────┐ │
│ │ auth = None │ │
│ │ auto_decompress = True │ │
│ │ base_url = None │ │
│ │ conn_timeout = None │ │
│ │ connector = None │ │
│ │ connector_owner = True │ │
│ │ cookie_jar = None │ │
│ │ cookies = None │ │
│ │ headers = { │ │
│ │ │ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) │ │
│ │ Gecko/20100101 Firefox/83.0' │ │
│ │ } │ │
│ │ loop = <ProactorEventLoop running=False closed=True debug=False> │ │
│ │ max_field_size = 8190 │ │
│ │ max_line_size = 8190 │ │
│ │ proxy = None │ │
│ │ proxy_auth = None │ │
│ │ raise_for_status = False │ │
│ │ read_bufsize = 65536 │ │
│ │ read_timeout = <_SENTINEL.sentinel: 1> │ │
│ │ requote_redirect_url = True │ │
│ │ self = <aiohttp.client.ClientSession object at 0x000001A466F3ACF0> │ │
│ │ skip_auto_headers = None │ │
│ │ timeout = <_SENTINEL.sentinel: 1> │ │
│ │ trace_configs = None │ │
│ │ trust_env = False │ │
│ │ version = HttpVersion(major=1, minor=1) │ │
│ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiohttp\connector.py:869 │
│ in __init__ │
│ │
│ 866 │ │ │
│ 867 │ │ self._ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) │
│ 868 │ │ if resolver is None: │
│ > 869 │ │ │ resolver = DefaultResolver(loop=self._loop) │
│ 870 │ │ self._resolver = resolver │
│ 871 │ │ │
│ 872 │ │ self._use_dns_cache = use_dns_cache │
│ │
│ ┌──────────────────────────────────────── locals ────────────────────────────────────────┐ │
│ │ enable_cleanup_closed = False │ │
│ │ family = <AddressFamily.AF_UNSPEC: 0> │ │
│ │ fingerprint = None │ │
│ │ force_close = False │ │
│ │ happy_eyeballs_delay = 0.25 │ │
│ │ interleave = None │ │
│ │ keepalive_timeout = <_SENTINEL.sentinel: 1> │ │
│ │ limit = 100 │ │
│ │ limit_per_host = 0 │ │
│ │ local_addr = None │ │
│ │ loop = <ProactorEventLoop running=False closed=True debug=False> │ │
│ │ resolver = None │ │
│ │ self = <aiohttp.connector.TCPConnector object at 0x000001A466F3AE40> │ │
│ │ ssl = True │ │
│ │ ssl_context = None │ │
│ │ timeout_ceil_threshold = 5 │ │
│ │ ttl_dns_cache = 10 │ │
│ │ use_dns_cache = True │ │
│ │ verify_ssl = True │ │
│ └────────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiohttp\resolver.py:93 in │
│ __init__ │
│ │
│ 90 │ │ if aiodns is None: │
│ 91 │ │ │ raise RuntimeError("Resolver requires aiodns library") │
│ 92 │ │ │
│ > 93 │ │ self._resolver = aiodns.DNSResolver(*args, **kwargs) │
│ 94 │ │ │
│ 95 │ │ if not hasattr(self._resolver, "gethostbyname"): │
│ 96 │ │ │ # aiodns 1.1 is not available, fallback to DNSResolver.query │
│ │
│ ┌──────────────────────────────── locals ────────────────────────────────┐ │
│ │ args = () │ │
│ │ kwargs = {} │ │
│ │ loop = <ProactorEventLoop running=False closed=True debug=False> │ │
│ │ self = <aiohttp.resolver.AsyncResolver object at 0x000001A466F3AF90> │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python313\Lib\site-packages\aiodns\__init__.py:63 in │
│ __init__ │
│ │
│ 60 │ │ │ │ │ │ raise RuntimeError( │
│ 61 │ │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: http │
│ 62 │ │ │ │ except ModuleNotFoundError: │
│ > 63 │ │ │ │ │ raise RuntimeError( │
│ 64 │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: https:// │
│ 65 │ │ kwargs.pop('sock_state_cb', None) │
│ 66 │ │ timeout = kwargs.pop('timeout', None) │
│ │
│ ┌──────────────────────────── locals ─────────────────────────────┐ │
│ │ kwargs = {} │ │
│ │ loop = None │ │
│ │ nameservers = None │ │
│ │ self = <aiodns.DNSResolver object at 0x000001A466F3B0E0> │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
RuntimeError: aiodns needs a SelectorEventLoop on Windows. See more: https://github.com/saghul/aiodns/issues/86
Config File
vanilla installation
Operating System
Windows 10 Pro 22H2, all updates until January 2025
streamrip version
rip, version 2.0.5
Screenshots and recordings
No response
Additional context
No response
I haven't done too much research into how streamrip retrieves its data but I know Tidal's v1 API has been removed which would mean the app would need to be updated to accept the newer v2 API standard.
I should also add that you should run the dev branch instead as it is up-to-date. pip3 install git+https://github.com/nathom/streamrip.git@dev
I haven't done too much research into how streamrip retrieves its data but I know Tidal's v1 API has been removed which would mean the app would need to be updated to accept the newer v2 API standard.
Since the bug is "ModuleNotFoundError: No module named 'winloop'" im quite sure this has nothing to do with Tidal, which is also confirmed in https://github.com/nathom/streamrip/issues/729, but maybe I misunderstand it?
I should also add that you should run the
devbranch instead as it is up-to-date.pip3 install git+https://github.com/nathom/streamrip.git@dev
This sadly leads to the next error
C:\Windows\system32>pip3 install git+https://github.com/nathom/streamrip.git@dev
Collecting git+https://github.com/nathom/streamrip.git@dev
Cloning https://github.com/nathom/streamrip.git (to revision dev) to e:\temp\pip-req-build-4iooccdp
ERROR: Error [WinError 2] The system cannot find the file specified while executing command git version
ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?
ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?
Is git installed and in your PATH? This seems to be looking like a broken Python/Git install more than a broken streamrip. Make sure you're on Python 3.11 and not 3.12 or greater as it may break dependencies on Windows (looks like you're on 3.13). Either downgrade to or install 3.11 along your current version and try again. Also check and fix git as needed. Google how-to as this help is for streamrip and not Git, Python and its dependencies.
Also check and fix git as needed. Google how-to as this help is for streamrip and not Git, Python and its dependencies.
Im sorry to say so, but i followed the install guide 1:1 It tells me to install Python (version 3.10 or greater), no mention of 3.11 or not 3.12/3.13 It does not tell me to install git.
Im not sure why I deserve this harsh answer when clearly the installation guide is not up to date and I just ask how to overcome this. Of course you can make projects as mysterious to newbies as you want, but please dont tell people they cant ask for help how to install streamrip when the install guide is missing a whole lot of stuff. Installation of ffmpeg is also mentioned and I can teach myself how to do that, but how would know that I need to install git or whatever if its not mentioned at all?
I am on Python 3.13.3, uninstalled and installed 3.11.9
rip search tidal playlist 'rap' This gives me exact the same error as before: RuntimeError: aiodns needs a SelectorEventLoop on Windows. See more: https://github.com/saghul/aiodns/issues/86
Installed now git with "winget install --id Git.Git -e --source winget"
Tried "pip3 install git+https://github.com/nathom/streamrip.git@dev", same error as above. git is not in the path, added "C:\Program Files\Git" to the path
Now "pip3 install git+https://github.com/nathom/streamrip.git@dev" works
Sadly, same error as before
C:\Windows\system32>rip search tidal playlist 'rap'
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ C:\Users\trj\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiodns\__init__.py:58 in │
│ __init__ │
│ │
│ 55 │ │ if sys.platform == 'win32': │
│ 56 │ │ │ if not isinstance(self.loop, asyncio.SelectorEventLoop): │
│ 57 │ │ │ │ try: │
│ > 58 │ │ │ │ │ import winloop │
│ 59 │ │ │ │ │ if not isinstance(self.loop , winloop.Loop): │
│ 60 │ │ │ │ │ │ raise RuntimeError( │
│ 61 │ │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: http │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
ModuleNotFoundError: No module named 'winloop'
During handling of the above exception, another exception occurred:
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ in _run_module_as_main:198 │
│ in _run_code:88 │
│ │
│ ... 19 frames hidden ... │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiohttp\resolver.py:93 in │
│ __init__ │
│ │
│ 90 │ │ if aiodns is None: │
│ 91 │ │ │ raise RuntimeError("Resolver requires aiodns library") │
│ 92 │ │ │
│ > 93 │ │ self._resolver = aiodns.DNSResolver(*args, **kwargs) │
│ 94 │ │ │
│ 95 │ │ if not hasattr(self._resolver, "gethostbyname"): │
│ 96 │ │ │ # aiodns 1.1 is not available, fallback to DNSResolver.query │
│ │
│ C:\Users\trj\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiodns\__init__.py:63 in │
│ __init__ │
│ │
│ 60 │ │ │ │ │ │ raise RuntimeError( │
│ 61 │ │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: http │
│ 62 │ │ │ │ except ModuleNotFoundError: │
│ > 63 │ │ │ │ │ raise RuntimeError( │
│ 64 │ │ │ │ │ │ 'aiodns needs a SelectorEventLoop on Windows. See more: https:// │
│ 65 │ │ kwargs.pop('sock_state_cb', None) │
│ 66 │ │ timeout = kwargs.pop('timeout', None) │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
RuntimeError: aiodns needs a SelectorEventLoop on Windows. See more: https://github.com/saghul/aiodns/issues/86
The reason for sticking with 3.11 was some dependencies weren't updated for use in Windows but worked fine for *nix-type OSs such as Linux and MacOS. That was some time ago and may have been fixed, but I stuck with 3.11 for stability, not bleeding edge.
Now check your version of aiohttp and make sure it's 3.9.5, using pip3 list. If it's higher than 3.9.5, then downgrade by pip3 install aiohttp==3.9.5.
The reason for sticking with 3.11 was some dependencies weren't updated for use in Windows but worked fine for *nix-type OSs such as Linux and MacOS. That was some time ago and may have been fixed, but I stuck with 3.11 for stability, not bleeding edge.
Now check your version of aiohttp and make sure it's 3.9.5, using
pip3 list. If it's higher than 3.9.5, then downgrade bypip3 install aiohttp==3.9.5.
Thank you, that finally worked and I can login to Tidal. Thank you so much for help. I hope this conversation will also help other Windows users.