You cannot use relative imports if you run the ipmi_server directly.
The reason for this is that the relative imports are used relatively to the __name__
of the current file.
Referring to the official python docs
A module’s __name__
is set equal to __main__
when read from standard input, a script, or from an interactive prompt.
You were running the module as a script thus relative imports will not work.
You can run this as a package from the root folder of your project (notice this is executed as a package, thus I've omitted the .py
extension)
python -m ipmi_management.ipmi_server
Or alternatively replace the relative imports by absolute imports as documented here:
from ipmi_management.ipmi_util import ipmi_handler
Edit -01
Well as explained well in this answer this would work only if you would import the script interactively.
When executing the script from commandline the sys.path[0] will be equal to the path of the directory that contains the module that you are executing.
Even running the module from the project root likewise: python ipmi_management/ipmi_server.py
will make no difference.
For example if your module was located at:
/home/user/projects/qiyun_ipmi_management/ipmi_management/ipmi_server.py', sys.path[0] would be equal to
/home/user/projects/qiyun_ipmi_management/ipmi_management/'
The way python imports work, as documented here, the interpreter will simply have no clue where to find the ipmi_management
package.
While the first option I suggested still holds, running a module from within a package is not recommended, you should adapt your project to allow for the ipmi_management
to be used as package:
Change the ipmi_server.py
code as the following:
def run_server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
while True:
conn, addr = s.accept()
with conn:
print('Connected by', addr)
if addr and addr[0] not in allowed_ip_list:
conn.sendall('invalid ip')
else:
while True:
data = conn.recv(1024)
if not data:
break
add a __main__.py
module to your ipmi_management
package which then makes use of the ipmi_server.py
code like so:
from ipmi_management.ipmi_server import run_server
def main():
run_server()
if __name__ == '__main__':
main()
And by running python -m ipmi_management
from the project root will result in the ipmi_server.py being called and the server being run.
Note that I still used absolute imports as they are recommended by PEP-8
Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path):
If you really wish to run the ipmi_server.py
module directly, you could use insert the parent directory of that module to sys.path but this is considered unpythonic and generally a bad habit as it makes the python importing system even more obscure.