How to see errors or exceptions in a Python script? - python

I'm completely new to working with Python (I have a PHP background)
I'm used to PHP's Error Handling and Logging. Yet, with Python I'm getting a 500 Error on a very simple script that should work.
Is there a way to turn on Error Handling with Python? As 500 Error doesn't tell me much of anything, except that something is not right.
I have looked on the net for an answer to this, but I'm not finding a solution to what should be very obvious.

Your question is asking how to see errors or exceptions (not how to handle then, though of course you need to handle these errors as well), and from the 500 error and PHP background it seems to imply you are doing web programming with Python.
There are many ways to do so in Python, here is some that I tend to use:
in production use logging module to log errors. There are lots of tools that can help you such as Sentry [source code here]. You can read more on logging here.
in development, run your script with python -m pdb myscript.py which will start your script in debugger mode, then enter c (continue) to continue the script until error occurs, and now you will be able to see what the states are in the interactive PDB (Python debugger) prompt.
in development, if you are using a framework (or your script) that relies on WSGI, you can use the graphical, interactive JavaScript based in-browser helper Werkzeug which allows you debug at every level of the call stack.
And, to point out the most obvious one, Python interpreter will print out the stack trace if the program crashes, for eg:
→ python -c 'pprint "hello"'
File "<string>", line 1
pprint "hello"
^
SyntaxError: invalid syntax
# print.py is just one line: print 'hello world'
→ python print.py
File "print.py", line 1
pprint 'hello world'
^
SyntaxError: invalid syntax
UPDATE:
It seems like you aren't using any frameworks, and you are behind a host which from the look of it, didn't tell you how exactly it is serving your Python script. Now, since all you want is to see the stack trace in the browser, you can do the following based on what your hosts uses:
If your script is running behind a server via CGI, all you need to do is to use the Python cgitb module to print the stack trace on the HTML page:
import cgitb
cgitb.enable()
However, it is very likely the shared hosting you signed up is using mod_python with Apache, so turning on PythonDebug in the Apache config file should print the stack trace in the browser:
PythonDebug On
For Apache with mod_wsgi, there's a better article written than I could summarize here: mod_wsgi Debugging Techniques

Related

How to debug a python script launched by a third party app

I'm using Linux Eclipse (pydev) as IDE to develop python scripts that are launched by an application written in C++. I can debug the python script without problems in the IDE, but the environment is not real (the C++ program sends and receives messages through the stdin/stdout and it's a complex communication channel that I can't fully reproduce writing the messages by hand).
Until now I was using log messages to debug (poor man's debug) but it's getting too complex. When I do something similar in PHP I can just leave xdebug listening and add breakpoints in Netbeans. Very neat and easy. Is it possible to do something like that in Python 3.X (with Eclipse or other IDE)?
NOTE: I know there is a Pydev / Attach to Process functionality, but it doesn't work. Always fails to attach.
NOTE2: There is also a built-in "breakpoint()" in Python 3.7 but it links to a debugger and if also fails, the IDE never gets the control.
After some research, this is the best option I have found. Without any other solution provided, I post it just in case anyone has the same problem.
Python has an integrated debugger: pdb. It works as a module and it doesn't allow to use it if you don't have the window control (i.e. you launch the script).
To solve this there are some coders that have created modules that add a layer on pdb. I have tried some and the most easy and still visual interesting is rpudb (but have a look also to this).
To install it:
pip3 install https://github.com/msbrogli/rpudb/archive/master.zip
(if you install it using the pip3 install rpudb command it will install an old version only valid for python 2)
Then, you use it just adding an import and a function call:
import rpudb
.....
rpudb.set_trace('127.0.0.1', 4444)
.....
Launch the program and it will stop in the set_trace call. To debug it (and continue) open a terminal and launch a telnet like this:
telnet 127.0.0.1 4444
You will have a visual debugger in front of you with the advantage that you can not only debug local programs, but also remote (just change the IP).
I was able to attach PyCharm to a running python process and use break points using PyCharm attach to process
I created a bash script which exec a python script, should work the same with C++

Running Python Script on My Server

I am trying to run this script on my server.
#!/usr/bin/python
print "Content-type:text/html\r\n\r\n"
print '<html>'
print '<head>'
print '<title>Hello Word - First CGI Program</title>'
print '</head>'
print '<body>'
print '<h2>Hello Word! This is my first CGI program</h2>'
print '</body>'
print '</html>'
I have that code in a python file. I uploaded the file to cgi-bin folder. I then set permission's so every box was ticked (Full Permission). I then attempted to view the page. But I get the error below.
500: Internal server error
This error is generated when a script running on the server could not be implemented or permissions are incorrectly assigned for files or directories
Troubleshooting suggestions:
Temporarily disable any rewrite rules by renaming your .htaccess file if it exists.
Ensure that any CGI or Perl scripts have at least .755. permissions.
If trying to run PHP and you get this error, you may have an invalid php.ini in your /cgi-bin, or may be missing your php.dat file in this folder.
How can I fix this so I can start writing scripts an get on with my website?
All the code does is "Hello World", the script work on other servers. What has a php.dat got to do with me an my python. How am I meant to understand a PHP file when it's half in machine language.... E.g.
Ü™ ì™ ð™ ô™ ø™ ü™ š
š
PHP is irrelevant in this case. It's mentioned in case you are using PHP, but you are not, so you can ignore it.
There are so many possible causes of this error so start at the beginning and work your way through.
First thing to check is the server error log files, if you have access to them they will likely reveal the problem straight away.
Next check whether your server is properly configured to run .py scripts as cgi. Also, check the cgi-bin directory permissions.
Verify that the python binary is located at /usr/bin/python on the server. BTW, a better alternative "shebang" is:
#!/usr/bin/env python
because it is less sensitive to path.
Errors in the code can also cause http 500. Your code works fine for Python 2. It's unlikely, but the server might be using Python 3?
From the other question you say that you are using Python 3.4. The script that you show will run in Python 2, but not in Python 3 because the syntax of the print statement has changed - it is now a function.
To fix the script so that it will run in Python 3, change all of your print statements into functions:
#!/usr/bin/env python
print("Content-type:text/html\r\n\r\n")
print('<html>')
print('<head>')
print('<title>Hello Word - First CGI Program</title>')
print('</head>')
print('<body>')
print('<h2>Hello Word! This is my first CGI program</h2>')
print('</body>')
print('</html>')
I have also changed the "shebang" at the top of the script to run whichever python is on the path.
If this doesn't fix the problem, look at the suggestions that I made in my previous answer, i.e. look in the server logs for errors, check your file and directory permissions, make sure that you are running the correct Python version etc.
Finally, talk to your hosting provider - I am sure that they can advise you how to set it up properly and there probably will be instructions on their site - find them and follow them.

How to properly debug a python3.3 curses application using pdb?

When using pdb to debug a curses application, the interactive debugger is useless, since curses messes up the terminal screen. Debugging post mortem works though, but that is a bit limited.
So what we probably need is having the debugger work in a terminal separately from the debuggee (the application that is being debugged).
Some alternatives which apply remote debugging (such as xpdb) appear either not to work with python 3.3 or give weird errors for other reasons.
So how can I use pdb in a different terminal, or in another proper way?
Use some debugger's functionalities for attach to a running process. For instance you can try:
gdb python <pid>
See how here Python Wiki DebuggingWithGdb.
being the pid of the process you want to debug. Also there is WinPdb that allows you to connect to a remote or local process. WinPdb is well documented and I think is your best option.
I've found that this bit of advice from the Python documentation helps:
A common problem when debugging a curses application is to get your
terminal messed up when the application dies without restoring the
terminal to its previous state. In Python this commonly happens when
your code is buggy and raises an uncaught exception. Keys are no
longer echoed to the screen when you type them, for example, which
makes using the shell difficult. In Python you can avoid these
complications and make debugging much easier by importing the module
curses.wrapper. It supplies a wrapper() function that takes a
callable. It does the initializations described above, and also
initializes colors if color support is present. It then runs your
provided callable and finally deinitializes appropriately. The
callable is called inside a try-catch clause which catches exceptions,
performs curses deinitialization, and then passes the exception
upwards. Thus, your terminal won’t be left in a funny state on
exception.
Please see here for info.

running an ironpython script from python : sandbox, loadFromRemoteSources

I am kind of stuck with Iron Python now. All I want to do is to run an ironpython script from python. In my ironpython script I import a .net assembly called mydll.dll.
I thought of 2 ways to do this. The first one was to use pyc.py and make an exe file from the ironpython script. It did not work (I can't remember what was the error message but I remember wasting considerable time trying).
The second way I thought of recently was simply to call ipy.exe from my python script using subprocess.popen. Unfortunately it comes up with an error about "sandboxing" and "loadFromRemoteSources".
Here is the code that brings the error in my python script:
process = subprocess.Popen(["ipy.exe", "myironpythonscript.py"])
Here is what is in myironpythoncript.py:
from clr import AddReferenceToFile
AddReferenceToFile ('mydll.dll')
Does any one knows what's wrong?
OK I just figured it out.
It actually works, the thing is you need to add a config file called ipy.exe.config containing the following :
<configuration>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>
see here -> How do I setup configuration when I use command line to build C#/.NET?

import problem with twisted.web server

I'm just getting started with twisted.web, and I'm having trouble importing a Python module into a .rpy script.
in C:\py\twisted\mysite.py, I have this:
from twisted.web.resource import Resource
from twisted.web import server
class MySite(Resource):
def render_GET(self, request):
request.write("<!DOCTYPE html>")
request.write("<html><head>")
request.write("<title>Twisted Driven Site</title>")
request.write("</head><body>")
request.write("<h1>Twisted Driven Website</h1>")
request.write("<p>Prepath: <pre>{0}</pre></p>".format(request.prepath))
request.write("</body></html>")
request.finish()
return server.NOT_DONE_YET
and in C:\py\twisted\index.rpy, I have this:
import mysite
reload(mysite)
resource = mysite.MySite()
I ran twistd -n web --port 8888 --path C:\py\twisted in command prompt and the server started successfully. But when I requested localhost:8888 I got a (huge) stack trace originating from an ImportError:
<type 'exceptions.ImportError'>: No module named mysite
I can import the module from the interpreter, and if i just execute index.rpy as a python script, I don't get the import error. The documentation on this subject is a bit vague, it just says "However, it is often a better idea to define Resource subclasses in Python modules. In order for changes in modules to be visible, you must either restart the Python process, or reload the module:" (from here).
Does anyone know the proper way to do this?
Short answer: you need to set PYTHONPATH to include C:\py\twisted.
Long answer...
An rpy script is basically just some Python code, like any other Python code. So an import in a rpy script works just like an import in any other Python code. For the most common case, this means that the directories in sys.path are visited one by one, in order, and if a .py file matching the imported name is found, that file is used to define the module.
sys.path is mostly populated from a static definition including things like C:\Python26\Lib\ and from the PYTHONPATH environment variable. However, there's one extra thing worth knowing about. When you run "python", the current working directory is added to the front of sys.path. When you run "python C:\foo\bar\baz.py", C:\foo\bar\' is added to the front ofsys.path. But when you run "twistd ...", nothing useful is added tosys.path`.
This last behavior probably explains why your tests work if you run the rpy script directly, or if you run python and try to import the module interactively, but fail when you use twistd. Adding C:\py\twisted to the PYTHONPATH environment variable should make the module importable when the rpy script is run from the server you start with twistd.

Categories

Resources