Python Tornado AttributeError: module 'test' has no attribute '__path__' - python

I am attempting to just run the Hello World code from Tornado docs
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
Except I am getting an error: AttributeError: module 'test' has no attribute '__path__'
I am just using IDLE to run test.py
I thought this was due to my Windows 10 computer not having Python accessible to PATH but even with adding in the python 3.6 to PATH I am still getting the same error. Any ideas?
The screenshot is how I added python to PATH and I think I got it correct..
------EDIT------
Ill add some screenshots of the errors/tracebacks I am running into. 1st one is the command prompt below when the test.py is ran in IDLE 3.6 in Windows 10.
If there is an import error, I can import Tornado just fine thru IDLE interpreter.
I also tried running this hello World code in IPython 3.7, and I get this error:

Solution: Run your file without the -m argument.
Another solution would be to provide the file name without the .py extension:
python -m test
This will also work.
Explanation:
The -m argument tells Python to run a module (file) present in the Python path. It doesn't take the name of the file, it takes the name of the module. The difference is that the file name contains .py suffix, whereas the module name doesn't.
So you can run the test.py file like this, too: python -m test.
When to use -m argument:
The -m argument is there for convenience. For example, if you want to run python's default http server (which comes with python), you'd write this command:
python -m http.server
This will start the http server for you. The convenience that -m argument gives you is that you can write this command from anywhere in your system and python will automatically look for the package called http in your the system's Path.
Without the -m argument, if you wanted to run the http server, you'd have to give it's full path like:
python C:\path\to\python\installation\http\server.py
So, -m argument makes it easy to run modules (files) present in the Path.
With Tornado would you happen to know how to kill the Python interpreter? A CNTRL-C doesn't do anything.
I use Linux and Ctrl-C works fine for me. On Windows you can try Ctrl-D or Ctrl-Z. Or here are some answers: Stopping python using ctrl+c

Related

Fix "Fatal Python error: Py_Initialize: can't initialize sys standard streams"

I have two python environments with different versions running in parallel. When I execute a python script (test2.py) from one python environment in the other python environment, I get the following error:
Fatal Python error: Py_Initialize: can't initialize sys standard streams
Traceback (most recent call last):
File "C:\ProgramData\Miniconda3\envs\GMS_VENV_PYTHON\lib\io.py", line 52, in <module>
File "C:\ProgramData\Miniconda3\envs\GMS_VENV_PYTHON\lib\abc.py", line 147
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
^
SyntaxError: invalid syntax
So my setup is this:
Python 3.7
(test.py)
│
│ Python 3.5.6
├───────────────────────────────┐
┆ │
┆ execute test2.py
┆ │
┆ 🗲 Error
How can I fix this?
For dm-script-people: How can I execute a module with a different python version in Digital Micrograph?
Details
I have two python files.
File 1 (test.py):
# execute in Digital Micrograph
import os
import subprocess
command = ['C:\\ProgramData\\Miniconda3\\envs\\legacy\\python.exe',
os.path.join(os.getcwd(), 'test2.py')]
print(*command)
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Subprocess result: '{}', '{}'".format(result.stdout.decode("utf-8"), result.stderr.decode("utf-8")))
and File 2 (test2.py)
# only executable in python 3.5.6
print("Hi")
in the same directory. test.py is executing test2.py with a different python version (python 3.5.6, legacy environment).
My python script (test.py) is running in the python interpreter in a third party program (Digital Micrograph). This program installs a miniconda python enviromnent called GMS_VENV_PYTHON (python version 3.7.x) which can be seen in the above traceback. The legacy miniconda environment is used only for running test2.py (from test.py) in python version 3.5.6.
When I run test.py from the command line (also in the conda GMS_VENV_PYTHON environment), I get the expected output from test2.py in test.py. When I run the exact same file in Digital Micrograph, I get the response
Subprocess result: '', 'Fatal Python error: Py_Initialize: can't initialize sys standard streams
Traceback (most recent call last):
File "C:\ProgramData\Miniconda3\envs\GMS_VENV_PYTHON\lib\io.py", line 52, in <module>
File "C:\ProgramData\Miniconda3\envs\GMS_VENV_PYTHON\lib\abc.py", line 147
print(f"Class: {cls.__module__}.{cls.__qualname__}", file=file)
^
SyntaxError: invalid syntax
'
This tells me the following (I guess):
The test2.py is called since this is the error output of the subprocess call. So the subprocess.run() function seems to work fine
The paths are in the GMS_VENV_PYTHON environment which is wrong in this case. Since this is test2.py, they should be in the legacy paths
There is a SyntaxError because a f-string (Literal String Interpolation) is used which is introduced with python 3.6. So the executing python version is before 3.6. So the legacy python environment is used.
test2.py uses either use io nor abc (I don't know what to conclude here; are those modules loaded by default when executing python?)
So I guess this means, that the standard modules are loaded (I don't know why, probably because they are always loaded) from the wrong destination.
How can I fix this? (See What I've tried > PATH for more details)
What I've tried so far
Encoding
I came across this post "Fatal Python error: Py_Initialize: can't initialize sys standard streams LookupError: unknown encoding: 65001" telling me, that there might be problems with the encoding. I know that Digital Micrograph internally uses ISO 8859-1. I tried to use python -X utf8 and python -X utf8 (test2.py doesn't care about UTF-8, it is ASCII only) as shown below. But neither of them worked
command = ['C:\\ProgramData\\Miniconda3\\envs\\legacy\\python.exe',
"-X", "utf8=0",
os.path.join(os.getcwd(), 'test2.py')]
PATH
As far as I can tell, I think this is the problem. The answer "https://stackoverflow.com/a/31877629/5934316" of the post "PyCharm: Py_Initialize: can't initialize sys standard streams" suggests to change the PYTHONPATH.
So to specify my question:
Is this the way to go?
How can I set the PYTHONPATH for only the subprocess (while executing python with other libraries in the main thread)?
Is there a better way to have two different python versions at the same time?
Thank you for your help.
Background
I am currently writing a program for handling an electron microscope. I need the "environment" (the graphical interface, the help tools but also hardware access) from Digital Micrograph. So there is no way around using it. And DigitalMicrograph does only support python 3.7.
On the other hand I need an external module which is only available for python 3.5.6. Also there is no way around using this module since it controlls other hardware.
Both rely on python C modules. Since they are compiled already, there is no possibility to check if they work with other versions. Also they are controlling highly sensitive aperatures where one does not want to change code. So in short words: I need two python versions parallel.
I was actually quite close. The problem is, that python imports invalid modules from a wrong location. In my case modules were imported from another python installation due to a wrong path. Modifying the PYTHONPATH according to "https://stackoverflow.com/a/4453495/5934316" works for my example.
import os
my_env = os.environ.copy()
my_env["PYTHONHOME"] = "C:\\ProgramData\\Miniconda3\\envs\\legacy"
my_env["PYTHONPATH"] = "C:\\ProgramData\\Miniconda3\\envs\\legacy;"
my_env["PATH"] = my_env["PATH"].replace("C:\\ProgramData\\Miniconda3\\envs\\GMS_VENV_PYTHON",
"C:\\ProgramData\\Miniconda3\\envs\\legacy")
command = ["C:\\ProgramData\\Miniconda3\\envs\\legacy\\python.exe",
os.path.join(path, "test2.py")]
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=my_env)
For Digital Micrograph users: The python environment is saved in the global tags in "Private:Python:Python Path". So replace:
import DigitalMicrograph as DM
# ...
success, gms_venv = DM.GetPersistentTagGroup().GetTagAsString("Private:Python:Python Path")
if not success:
raise KeyError("Python path is not set.")
my_env["PATH"] = my_env["PATH"].replace(gms_venv, "C:\\ProgramData\\Miniconda3\\envs\\legacy")
I had set "PYTHONPATH" as "D:\ProgramData\Anaconda3" for my python (base) python environment before, but i found when I had changed to another env my python still import basic python package from "D:\ProgramData\Anaconda3",which means it get the wrong basic package with the wrong "System environment variables" config.
so I delete "PYTHONPATH" from my windows "System environment variables", and that will be fixed.

Python script within a Pipenv as a windows service with NSSM

Using How do you run a Python script as a service in Windows? I can get a python script to run as a service. Tested it with the following code I made:
import os
from time import sleep
from random import *
# import flask <-- This line breaks it only when run from NSSM
count = 0
while True:
num = randint(1, 10000)
count+=1
os.mkdir("C:\\temp\\" + str(count) + '_' + str(num))
sleep(2)
I tested the executable and arguments to put into NSSM by first running the following:
cd C:\pipenvfolder\foo
C:\Users\Username\AppData\Local\Programs\Python\Python36\Scripts\pipenv.exe
run python main.py
And it starts the script successfully, even if it has imports to packages installed in the pipenv (e.g. flask). I then created a NSSM service with:
nssm.exe install ServiceName "C:\Users\Username\AppData\Local\Programs\Python\Python36\Scripts\pipenv.exe"
"run python main.py"
nssm set ServiceName AppDirectory
"C:\pipenvfolder\foo"
And every 2 seconds it creates a directory in c:\temp. All is good. However now I wish to import one of the installed Pipenv packages, i.e. the flask package installed within the pipenv. So I added "import flask" to the test script above.
I then set up NSSM to have an error log and checked why it was failing to start, and it is failing to import the flask module:
Traceback (most recent call last):
File "main.py", line 7, in <module>
import flask
ModuleNotFoundError: No module named 'flask'
The nssm service must be starting in the correct app directory or else it would not find main.py. Calling it from the correct directory is what specifies the pipenv. Hence I cannot figure out why the pipenv is not being used to run the script in the same way as when run via the command line.
Create a batch file which calls your virtual environment.
Get the virtualenv path:
pipenv --venv
service.bat
call path/to/.virtualenv/Scripts/activate.bat
call python main.py
Install the service with nssm which calls this batch file.
I doubt this is going to get any answers, but if someone else has the same issue.
I got around the issueby making an exe using pyinstaller. It is fairly quick and easy to do. Then I passed the .exe into NSSM as the executable to be run.

python gives ImportError: No module named "" when triggered in a perl program

In my perl program which runs the python script
I have provided the PYTHONPATH env param with the path for the lib and i have run the python script. I am getting
ImportError: No module named "....."
my $script = "/path/pythonscript.py";
$ENV{'PYTHONPATH'} = "/path/lib";
system("python $script");
Whereas when i run the same python script on command line in the same directory where the script executes in my perl program, it is working.
Can anyone give me some pointers on why this is happening.
Try printing the contents of sys.path and compare the difference e.g. change your python script to
import sys
print(sys.path)
Most likely there is a difference here and this is causing the module to not be found.
I once had a similar problem. I solved it by creating an executable script (chmod) and making that script run instead of the python script. The script simply contained a cd to the directory and a python3 program. py

Running mayapy on mac

I am trying to run a python script using maya's python interpreter. I am writing this script to be placed in a pipeline, so that maya runs in batchmode. Nothing is happening when I run this command:
maya -batch -script maya.py $1
I get the following message after running this command:
I also tried using the python interpreter directly with a test file
/Applications/Autodesk/maya2017/Maya.app/Contents/bin/mayapy test.py
test.py looks like this
`import maya.standalone
try:
maya.standalone.initialize()
except:
print "standalone already running"`
I get this error ImportError: No module named cmds
I have looked at this post, but it did not help me. What am I doing wrong?

executing standalone fabric script by calling it by its name, without the .py extension

I have a fabric script called fwp.py that I run without calling it throug fab by using:
if __name__ == '__main__':
# imports for standalone mode only
import sys
import fabric.main
fabric.main.main(fabfile_locations=[__file__])
The thing is then have to call the script by calling fwp.py. I'd like to rename it as fwp to be able to call it as fwp. But doing that would result in
Fatal error: Couldn't find any fabfiles!
Is there a way to make Python/Fabric import this file, despite the lack of a ".py" extension?
To reiterate and clarify:
I'm not using the "fab" utility (e.g. as fab task task:parameter); just calling my script as fwp.py task task:parameter, and would like to be able to call it as fwp task task:parameter.
Update
It's not a duplicate of this question. The question is not "How to run a stand-alone fabric script?", but "How to do so, while having a script without a .py" extension.
EDIT: Original answer corrected
The fabric.main.main() function automatically adds .py to the end of supplied fabfile locations (see https://github.com/fabric/fabric/blob/master/fabric/main.py#L93). Unfortunately that function also uses Python's import machinery to load the file so it has to look like a module or package. Without reimplementing much of the fabric.main module I don't think it will be possible. You could try monkey-patching both fabric.main.find_fabfiles and fabric.main.load_fabfiles to make it work.
Origininal answer (wrong)
I can get this to work unaltered on a freshly installed fabric package. The following will execute with a filename fwp and executable permission on version 1.10.1, Python2.7. I would just try upgrading fabric.
#!/usr/bin/env python
from fabric.api import *
import fabric.main
def do():
local('echo "Hello World"')
if __name__ == '__main__':
fabric.main.main(fabfile_locations=[__file__])
Output:
$ ./fwp do
Hello World
Done

Categories

Resources