I'm trying to get the websockets tutorial code running and I'm getting this error: ModuleNotFoundError: No module named 'websockets.asyncio'; 'websockets' is not a package
. I know there are several questions about this already, and I've tried all the suggestions found there, to no avail.
My code:
import asyncio
import sys
from websockets.asyncio.server import serve
async def handler(websocket):
while True:
message = await websocket.recv()
print(message)
async def main():
async with serve(handler, "", 8001):
await asyncio.get_running_loop().create_future() # run forever
if __name__ == "__main__":
asyncio.run(main())
I know Python looks for package in sys.path. When I print sys.path, I get:
['/Users/taylorwofford/Desktop', '/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages', '/Library/Frameworks/Python.framework/Versions/3.13/lib/python313.zip', '/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13', '/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/lib-dynload']
When I open /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages
, lo and behold, there it is:
taylorwofford@Taylors-Air \~ % cd /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages
taylorwofford@Taylors-Air site-packages % ls
Django-5.1.2.dist-info pip-24.2.dist-info
README.txt sqlparse
asgiref sqlparse-0.5.1.dist-info
asgiref-3.8.1.dist-info websockets <--- here!!!
django websockets-13.1.dist-info
pip
taylorwofford@Taylors-Air site-packages %
I thought maybe it had something to do with my Python version. I'm running 3.13:
taylorwofford@Taylors-Air site-packages % python3 --version
Python 3.13.0
I verified the expected Python was being run in the script. I added print(sys.version_info)
and the result was sys.version_info(major=3, minor=13, micro=0, releaselevel='final', serial=0)
-- 3.13, as expected. When I run python3 pip list
, I get
taylorwofford@Taylors-Air site-packages % python3 pip list
Package Version
-----------------
asgiref 3.8.1
Django 5.1.2
pip 24.2
sqlparse 0.5.1
websockets 13.1 <--- here!
I'm not sure what else to do. Everything looks correct to me.
I tried checking which Python version I'm using, confirmed the script I'm trying to run is using the same version, checked the package I'm looking for is installed via pip3, and confirmed it's located in a directory in sys.path.
When Python runs a script it prepends script's directory to sys.path
. This allows to import additional modules from the script's directory. Unfortunately it means you can easily overshadow modules/packages from the standard library or 3rd-party modules installed with pip
.
Your script is named websockets.py
. With sys.path
modification explained above import websockets
imports your script and import websockets.asyncio
fails because your script is not a package, it's a module without subpackages.
To fix the problem rename the script to something unique or not importable.
mv websockets.py websockets-test.py
should help.
Note for the future — don't give you modules, packages and scripts the same names as modules/packages from the standard library or 3rd-party modules. Never import email
from your script named email.py
. Never import test
from your script named test.py
. email
(without extension) or test
are ok, they're not importable so they don't shadow Python packages; executable script test
shadows /bin/test
though.