Running a program in debug without hard coding DEBUG = True in Python - python

I have a small "Hello World" Flask script that takes an output from a program, called rescuetime_api and puts it on a URL /blog. I wanted to run the script in Debug mode and hard-coded it into the top of my program but I was wondering if there is a way to pass this value through from my Bash shell. Thanks in advance for your help.
#Flask tutorial
import rescuetime_api as api
import os
from flask import Flask
app = Flask(__name__)
DEBUG = True
#app.route("/")
def hello():
return "This is my homepage!"
#app.route("/blog")
def blog():
result = api.download_rescuetime_json()[1][1]
return "%s" % result
if __name__ == "__main__":
if os.environ.get("FLASK_TUTORIAL_DEBUG"):
DEBUG = True
print "Running in debug:", DEBUG
app.run(debug=DEBUG)

Your script already checks for the environment variable FLASK_TUTORIAL_DEBUG.
You could just set it in your shell, before executing the program:
export FLASK_TUTORIAL_DEBUG=1
and then run your program:
python myscript.py
And remember to unset the variable when you don't need it:
unset FLASK_TUTORIAL_DEBUG

Related

Python Flask script auto-closes when run as .pyw file (workaround included)

Problem
I've created a basic python script, using flask to render an HTML page. On Windows 10, the script works perfectly as a *.py file, but when run as a *.pyw file, the page is not rendered.
In Task Manager, instances of python are opened and closed within seconds after running the script as *.pyw.
Code
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=80)
Workaround
Run the *.py version with the following lines added to the code:
import ctypes
...
...
...
if __name__ == '__main__':
cytypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 0)
app.run(debug=True, host="0.0.0.0", port=80)
Code above hides the console, and starts the flask app successfully.
However, I am still interested in an explanation as to why the *.pyw method won't work, if anyone has an idea.
.pyw-files would ran on pythonw.exe rather than python.exe. The difference is, that pythonw.exe does not run in a console by default and runs asynchronous. This would mean that flask starts and runs in the background untill everything else terminates. Since you to not have anything else in your application, the programm ends directly.

Testing a sever launching cli application - Python, Flask

Question
How to test a blocking cli application in Python?
What I am trying to accomplish
I have a manage.py file, which is used to start the flask development web server (and other admin stuff that are out of the scope of this question). Typically I would run this as python manage.py runserver, but for keeping this question simple and relevant I have edited that file (see Minimal, Reproducible Example) to just run the server. So the below command works
$ python manage.py
* Serving Flask app "app" (lazy loading)
* Environment: production...
The issue comes with testing the functionality of this cli application. Click has the CliRunner.invoke(), which allows one to test cli applications. But in this particular case, it fails as the server is already running.
from manage import runserver
from click.testing import CliRunner
import requests
import unittest
class TestManage(unittest.TestCase):
def test_runserver(self):
runner = CliRunner()
runner.invoke(runserver)
# It blocks above, does not go below!
r = requests.get('http://127.0.0.1')
assert r.status_code == 200
if __name__ == '__main__':
unittest.main()
Attempts at solution
After trying many approaches I have found a "solution", which is to spawn a Process to start the server, run the tests and then terminating the process on exit (this is included in the example). This feels more like a hack rather than a "real" solution.
Minimal, Reproducible Example
Folder structure
flask_app/
- app.py
- manage.py
- test_manage.py
app.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return 'Hello, World!'
manage.py
import click
from app import app
#click.command()
def runserver():
app.run()
if __name__ == "__main__":
runserver()
test_manage.py
from manage import runserver
from multiprocessing import Process
from click.testing import CliRunner
import requests
import unittest
class TestManage(unittest.TestCase):
def setUp(self):
self.runner = CliRunner()
self.server = Process(
target=self.runner.invoke,
args=(runserver, )
)
self.server.start()
def test_runserver(self):
r = requests.get('http://127.0.0.1')
assert r.status_code == 200
def tearDown(self):
self.server.terminate()
if __name__ == '__main__':
unittest.main()
And run the test using $ python test_manage.py.

Script using web.py runs indefinitely and produces no result

I'm learning python from Learn Python the Hard Way, and am currently on excercise 50 (https://learnpythonthehardway.org/book/ex50.html). When I run the script in PowerShell on Windows, it runs indefinitely and doesn't produce the predicted result (printing "Hello World" in the web browser). I'm using Python 2.7 The command line looks like this:
$ python bin/app.py
http://0.0.0.0:8080/
and the script doesn't terminate.
I'm running this script from the exercise:
import web
urls = (
'/', 'Index'
)
app = web.application(urls, globals())
render = web.template.render('templates/')
class Index(object):
def GET(self):
greeting = "Hello World"
return render.index(greeting = greeting)
if __name__ == "__main__":
app.run()
It's not supposed to terminate. It's running a web server; the exercise wants you to go to the address printed - http://0.0.0.0:8080/ - in your web browser, where you will see the message.
If you want to terminate the local server press ctr+c or ctrl+z in the powershell

In python, how can I run a command-line program that does not return until I send Ctrl+D to it

I'm writing python unit tests that test against a REST API that needs to be running as another process.
The REST server is a tomcat application that I call from the shell to run in development mode, so what I am looking to do in the python test is:
Start the server, return when the server is up.
Run unit tests
Send the server Ctrl+D so it shuts down gracefully.
Is there a way to use a single point of entry for python so that the server starts and unit tests run all from one python script call?
I've look around at python subprocess and multithreading in python, but I still don't quite see how to get there from here.
For those that are familiar, this is an Atlassian JIRA plugin we are developing, so the actual shell command is "atlas-run".
Since no one has offered any code to help with this problem, I would do something like the following. Turns out pexpect is very powerful and you don't need the signal module.
import os
import sys
import pexpect
def run_server():
server_dir = '/path/to/server/root'
current_dir = os.path.abspath(os.curdir)
os.chdir(server_dir)
server_call = pexpect.spawn('atlas-run')
server_response = server_call.expect(['Server Error!', 'Sever is running!'])
os.chdir(current_dir)
if server_response:
return server_call #return server spawn object so we can shutdown later
else:
print 'Error starting the server: %s'%server_response.after
sys.exit(1)
def run_unittests():
# several ways to do this. either make a unittest.TestSuite or run command line
# here is the second option
unittest_dir = '/path/to/tests'
pexpect.spawn('python -m unittest discover -s %s -p "*test.py"'%unittest_dir)
test_response = pexpect.expect('Ran [0-9]+ tests in [0-9\.]+s') #catch end
print test_response.before #print output of unittests before ending.
return
def main():
server = run_sever()
run_unittests()
server.sendcontrol('d') #shutdown server
if __name__ == "__main__":
main()

is there any way to run bottle application in daemon mode

I have a web application built on bottle(python) frame work and I want to run it in daemon mode.Is there any way to run it in daemon mode
Thanks
Sure you can. Install BottleDaemon 0.1.0 on your OS and than change your router file like so:
from bottledaemon import daemon_run
from bottle import route
#route("/hello")
def hello():
return "Hello World"
# The following lines will call the BottleDaemon script and launch a daemon in the background.
if __name__ == "__main__":
daemon_run()

Categories