I'm currently developing a web service in WSGI, but the script crashes on the line where I am executing my query. I'm using the exact same code as other working web services, and even simplified my query for testing purposes, but to no avail.
The real problem is that while I can manually print stuff to the error_log specified in my VirtualHost, there is no log for the error that occurs when the script crashes.
All I know now is that the print before the line is written to the log, but the print after isn't. How can I print the error to the log and get to the root of my problem?
The code (simplified a bit):
webservice.wsgi:
def application(environ, start_response):
ENV = environ.get('APPLICATION_ENV', 'DEV')
connector = ConnectorObj(confParams['dbname'], confParams['host'], confParams['port'], confParams['user'], confParams['password'])
method = environ.get('REQUEST_METHOD', '')
if (method == 'POST'):
content_body = json.loads(request_body)
han = HandlerObj(connector)
res = han.getBld()
start_response('200 OK', [('content-type', 'application/json; charset=utf-8'), ('Access-Control-Allow-Origin', '*')])
return(res)
getBld:
def getBld(self):
print "execute query"
self.cur.execute("""
SELECT * FROM adr.bld
""")
print "after executing query"
After doing the post call, I can see that "execute query" is being printed to the error_log, but then it just crashes and doesn't get to "after executing query".
Again, I'm not asking what is wrong with my actual code (I would have to provide much more in order to make sense of it), but simply how I can get an error trace somehow so I can start to debug it myself..
It depends on the database you use. If it is some open source I would recommend taking the source codes and compiling it with enabled debug mode which will result DB to create log file for itself which can point to the error.
Related
I am building a Flask webapp and it uses the OpenBabel API (chemistry toolkit) to generate some files for me. When I call this particular function it seems to work fine and generate the files in the directory that I want. However, once it gets back to Flask it crashes and Flask does not render the html template, instead redirecting me to This page isn’t working 127.0.0.1 didn’t send any data. I found that when removing the code in the function it works normally. So it's likely a problem with OpenBabel. The Openbabel function does not ouput any errors itself and seemingly even returns at the end, based on debugging.
I have tried many things from other SO answers, including changing my host to 0.0.0.0, adding threaded=True and some other solutions. All to no avail. I tried debugging it for a long time, but now I am lost because I have tried everything I know. All I could get was a SystemExit exception from Flask. Sometimes it was able to run the print statement following it, but more often it crashes immediately. I have no clue where the problem may lie. Appreciate any help I can get. A sample of the code (shortened it a bit):
#app.route("/", methods=["POST", "GET"])
def form_handler():
if request.method == "POST":
smiles = request.form["smiles_molecule"]
pdb_file = request.files["pdb_molecule"]
no_conformers = int(request.form["no_conformers"])
scoring = request.form["score"]
if smiles:
pattern = re.compile('[^A-Za-z0-9]+')
smiles_no_special_chars = re.sub(pattern, "", smiles)
mol_path = os.path.join(app.config["MOLECULE_UPLOADS"], smiles_no_special_chars[0:10])
if os.path.exists(mol_path):
shutil.rmtree(mol_path)
os.mkdir(mol_path)
os.chdir(mol_path)
x = conf_gen.gen_and_write_confs(smiles, no_conformers, scoring) #<- breaks down here
print(x)
return render_template("index.html", mole=smiles_no_special_chars[0:10])
The function that is called:
def gen_and_write_confs(molecule, no_confs, scoring):
"""Generate and write the conformers to PDB. Takes mol, number of conformers and
scoring method: RCS, MECS and ECS: OBRMSDConformerScore,
OBMinimizingEnergyConformerScore and OBEnergyConformerScore. See OpenBabel docs."""
mole = pybel.readstring("can", molecule)
mole.addh()
mole.make3D()
mole = mole.OBMol
mole.SetChainsPerceived(True)
cs_obj = ob.OBConformerSearch()
cs_obj.Setup(mole, no_confs, 5, 5, 25)
if scoring == "RCS":
score = ob.OBRMSDConformerScore()
elif scoring == "MECS":
score = ob.OBMinimizingEnergyConformerScore()
else:
score = ob.OBEnergyConformerScore()
cs_obj.SetScore(score)
cs_obj.Search()
cs_obj.GetConformers(mole)
mole.DeleteNonPolarHydrogens()
return "Test"
If needed I can upload the project on Github. It does require installing a few dependencies and I am using conda for that right now, but I could make it available through pip too since OpenBabel is available in pip.
Ps: no single error message is shown after it crashes
The purpose is to have the area method return json serialized data using cgi and restful services. When I run request_area() my console displays 500 internal server error and when I check my error log it says 'End of script output before headers: measurement.py'
Here is measurement.py
#!/usr/bin/python3
__author__ = 'charles'
import json
import logging
import db_utility, db_access
def send_data(data):
logging.debug(str(data))
dataJ = json.dumps(data)
logging.debug("custJ " + str(dataJ))
lng = len(dataJ)
logging.debug("len " + str(lng))
print("Content-Type: application/json; charset=UTF-8")
print("Content-Length: " + str(lng))
print()
print(dataJ)
def area():
areas = db_access.get_all_areas()
# print(areas)
send_data(areas)
And here is request_area()
import requests
r = requests.get("http://localhost/cgi-bin/measurements_rest/measurement.py/area")
print(r.text)
Oh and the function being called in area(), get_all_areas()
def get_all_areas():
"""
Returns a list of dictionaries representing all the rows in the
area table.
"""
cmd = 'select * from area'
crs.execute(cmd)
return crs.fetchall()
I can not figure out what I am doing wrong.
As you are using apache to call your program, apache will place in the
environment several variables with info on the cgi call and the url.
The one of interest to you is PATH_INFO which contains the string remaining
unparsed by apache, ie area. In your python main you need to
os.getenv('PATH_INFO') and recognised the word and call your function.
Alternatively, use a framework like cherrypy which
does this sort of work for you.
Also, you are printing stuff before the Content-type etc headers. Remove
print(areas)
So, I'm a complete noob when it comes to this kind of thing, and I need some help. I work in software QA for an ecommerce company, and we started using Saucelabs for our automated testing. I'm in the process of learning python but really know next to nothing at this point. I can build a decent test in Selenium IDE, export in Python/Selenium Webdriver, and run the test. Not an issue. However, how do I set the pass/fail flag on the interface? One of our devs wrote a parallel script so I can run a large number of tests at one time, but in order to do so I need to be able to see at a glance which tests have passed and which ones have failed. Can you help me? Thanks!
Also, any tutorials you are aware of on Selenium Webdriver would be helpful too! Really want to learn this stuff!
I did it this way, first you need to import some things
# These next imports for reporting Test status to Sauce Labs
import sys
import httplib
import base64
try:
import json
except ImportError:
import simplejson as json
Then you need this config
#Config to connect to SauceLabs REST API
config = {"username": "yourusernamehere",
"access-key": "youraccesskeyhere"}
Then you put your tests. At the end, before your TearDown you need to include
# Curl call to SauceLabs API to report Job Result
def set_test_status(self, jobid, passed):
base64string = base64.encodestring('%s:%s' % (config['username'], config['access-key']))[:-1]
body_content = json.dumps({"passed": passed})
connection = httplib.HTTPConnection("saucelabs.com")
connection.request('PUT', '/rest/v1/%s/jobs/%s' % (config['username'], jobid),
body_content,
headers={"Authorization": "Basic %s" % base64string})
result = connection.getresponse()
return result.status == 200
Then in your tearDown you need to include some kind of if logic. I did it this way (and it works)
def tearDown(self):
# sys.exc_info should be (None, None, None) if everything is OK, it fills with some values if something went wrong
# This if reports to Sauce Labs the outcome of the Test where True = Pass and False = Failed
if sys.exc_info() == (None, None, None):
self.set_test_status(self.driver.session_id, True)
else:
self.set_test_status(self.driver.session_id, False)
self.driver.quit()
self.assertEqual([], self.verificationErrors)
That did the trick for me
You can use Sauce labs REST API to mark your test pass/failed. You can find some example code given here
So I installed python on my server and I'm using the wsgi_module with apache.
Do all my python programs have to use this format:
def application(environ, start_response):
headers = []
headers.append(('Content-Type', 'text/plain'))
write = start_response('200 OK', headers)
input = environ['wsgi.input']
output = cStringIO.StringIO()
print >> output, "test"
output.write(input.read(int(environ.get('CONTENT_LENGTH', '0'))))
return [output.getvalue()]
Is there anyway to set it up so I can write python scripts and just have:
print "test"
Yes, your script certainly need to have callable (not necessarily a function, it can also be a class with __call__ method defined) that accepts environ and *start_response* arguments as it is a part of wsgi standard and that is the way how it works.
The way you'd like to write scripts in PHP-style like "print something" doesn't work. There's a currently dead initiative called initially PSP (Python Server Pages) that mixed up code and templates, but it couldn't gain popularity as it's certainly not a Python-way of writing applications.
I have web.py configured for my Apache server by installing flups. However when I go to my application, the html code is printed instead of the html page. (See below).
Content-Type: text/html
<HTML><HEAD><TITLE>Login Details</TITLE></HEAD><BODY>.......</BODY></HTML>
I created another file Test.py in the same directory with the following code
#!/usr/bin/python
print "Content-Type: text/html\n\n"
print "<html><head></head><body>Present</body></html>"
This prints out the page fine. Both the files have the same executable permissions.(chmod 755).
Any ideas why this is happening?
Update: Just found out. If I change the return statement to a print inside the GET method for my app, it prints out the form fine, but also prints out the cookie, session id, etc.. at the end. What do I need to configure to make the return work as expected?
Adding a sample code which would cause the issue:
#!/usr/bin/python
import web
urls = ("/CodeAnalyzer", "CodeAnalyzer")
app = web.application(urls, globals())
class CodeAnalyzer:
def GET(self):
init="Content-Type: text/html\n\n"
form="<html><head></head><body>Hello World</body><html>"
return init+form
if __name__ == "__main__":
app.run()
The issue was in the line
init="Content-Type: text/html\n\n"
That was the incorrect way to pass the header in web.py. The issue was resolved after replacing it with
web.header('Content-Type','text/html; charset=utf-8', unique=True)