Why this code is not running on heroku? (Internal server error)
import os
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
a = 10
b = 20
c = a + b
return c
if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
Logs:
Starting process with command python app.py
a = 1
^
SyntaxError: invalid syntax
File "app.py", line 8
This code is working (Python hello world from heroku guides)
import os
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return 'Hello World!'
if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
Sounds like that not your code is being executed. After all your line was a = 10 and the log file complains about a line stating a = 1.
Or maybe there's a strange (invisible?) character between the 1 and the 0.
I'd propose to change that value from 10 to 42 for testing and see in what way the error log message changes.
Related
I am trying to run a flask server from another module and then close the server (it's not the main point of the application), currently the code looks like this for webserver.py
from flask import Flask, render_template
from flask_classful import FlaskView
import os
from werkzeug.utils import secure_filename
from flask import request
host = 'localhost'
debug = True
app = Flask (__name__)
app.config
#app.route('/')
def main():
return render_template("index.html")
def run():
if __name__ == 'Refactor2':
app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
def shutdown_server():
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
def shutdownServer():
shutdown_server()
return "Server is shutting down"
I am then trying to run this in the following module (named Refactor2):
import webserver
class buyer:
def __init__(self, email, password):
self.email = email
self.password = password
def server_run(self):
run()
print("Server has been started")
However, the server does not run and I cannot navigate to the webpage. There are no error messages shown.
Seems like an unusual way to launch a Flask app, but with that aside...
Assuming you're running this with python Refactor2.py, __name__ will be 'webserver'.
This can be demonstrated with a minimal example:
$ cat webserver.py
def run():
print (__name__)
$ cat Refactor2.py
import webserver
webserver.run()
$ python Refactor2.py
webserver
So in your webserver module you could do do:
def run():
if __name__ == 'webserver':
app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
Or just:
def run():
app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
And call it like:
import webserver
# ...
class buyer:
# ...
def server_run(self):
webserver.run()
print("Server has been started")
Of course, that 'Server has been started' won't actually be reached until the server (the webserver.run call) has completed and the server has stopped.
Again, this seems like an odd way to launch an application. I suggest you investigate the docs on how to run Flask in production, as it seems what you're trying to acheive is the job of an orchestration system, and not the python process itself. In a production env, you should use a WSGI server like gunicorn, instead of the dev server (app.run). Granted, perhaps you know this already ;)
__name__ gives the name of the current module. So in your run() method __name__ is probably resolving to webserver. I'd suggest passing the name as a variable to run() from server_run()
webserver.py
def run(name):
if name == 'Refactor2':
app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
Refactor2
import webserver
class buyer:
def __init__(self, email, password):
self.email = email
self.password = password
def server_run(self):
run(__name__)
print("Server has been started")
Note that if Refactor2 is in a package you might get a dotted module name, like 'src.Refactor2'. It might be better to pass a more explicit name to run, as if you rename Refactor2 you'll need to update your hardcode in webserver.py too. Something like
def server_run(self):
webserver.run('buyer')
print("Server has been started")
and
(webserver.py)
def run(name):
if name == 'buyer':
app.run(ssl_context = (r"path_to_cert", r"path_to_key"), host = "localhost", port = 443)
edit: not sure if you provided a full code example, but it also looks like maybe you're not calling the right run() method in server_run() - it looks like it should be called on the webserver module, which I edited my answer to reflect
I have a Flask App and a Tensorboad server. Is there a way by which I can map the Tensorboard server to one of the endpoints of Flask so that as soon as I hit that endpoint it triggers the Tensorboard server?
Flask application
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/hello-world', methods=['GET', 'POST'])
def say_hello():
return jsonify({'result': 'Hello world'})
if __name__ == "__main__":
app.run(host=host, port=5000)
Tensorboard server code:
from tensorboard.program import TensorBoard, setup_environment
def tensorboard_main(host, port, logdir):
configuration = list([""])
configuration.extend(["--host", host])
configuration.extend(["--port", port])
configuration.extend(["--logdir", logdir])
tensorboard = TensorBoard()
tensorboard.configure(configuration)
tensorboard.main()
if __name__ == "__main__":
host = "0.0.0.0"
port = "7070"
logdir = '/tmp/logdir'
tensorboard_main(host, port, logdir)
I tried creating an endpoint in Flask app and then added tensorboard_main(host, port, logdir) in the hope that if I hit the endpoint then the server will start but I got no luck.
I found out that to integrate a TensorBoard server into a larger Flask app, the best way would be to compose the applications at the WSGI level.
The tensorboard.program API allows us to pass a custom server
class. The signature here is that server_class should be a callable which takes the TensorBoard WSGI app and returns a server that satisfies the TensorBoardServer interface.
Hence the code is:
import os
import flask
import tensorboard as tb
from werkzeug import serving
from werkzeug.middleware import dispatcher
HOST = "0.0.0.0"
PORT = 7070
flask_app = flask.Flask(__name__)
#flask_app.route("/hello-world", methods=["GET", "POST"])
def say_hello():
return flask.jsonify({"result": "Hello world"})
class CustomServer(tb.program.TensorBoardServer):
def __init__(self, tensorboard_app, flags):
del flags # unused
self._app = dispatcher.DispatcherMiddleware(
flask_app, {"/tensorboard": tensorboard_app}
)
def serve_forever(self):
serving.run_simple(HOST, PORT, self._app)
def get_url(self):
return "http://%s:%s" % (HOST, PORT)
def print_serving_message(self):
pass # Werkzeug's `serving.run_simple` handles this
def main():
program = tb.program.TensorBoard(server_class=CustomServer)
program.configure(logdir=os.path.expanduser("~/tensorboard_data"))
program.main()
if __name__ == "__main__":
main()
You can use multiprocessing here: create one process for flask and another for tensorboard, then run it on the same host.
Code:
from multiprocessing import Process
from tensorboard.program import TensorBoard
from flask import Flask, jsonify
app = Flask(__name__)
def tensorboard_main(host, port, logdir):
configuration = list([""])
configuration.extend(["--host", host])
configuration.extend(["--port", port])
configuration.extend(["--logdir", logdir])
tensorboard = TensorBoard()
tensorboard.configure(configuration)
tensorboard.main()
def flask_main(app, host, port):
return app.run(host=host, port=port)
#app.route("/hello-world", methods=["GET", "POST"])
def say_hello():
return jsonify({"result": "Hello world"})
if __name__ == "__main__":
host = "0.0.0.0"
port_for_tensorboard = "7070"
port_for_flask = "5000"
logdir = "/tmp/logdir"
process_for_tensorboard = Process(target=tensorboard_main, args=(host, port_for_tensorboard, logdir))
process_for_flask = Process(target=flask_main, args=(app, host, port_for_flask))
process_for_tensorboard.start()
process_for_flask.start()
process_for_tensorboard.join()
process_for_flask.join()
If you want that inside flask endpoint tensorboard will be show some things, then you need to look at shared data from one process to another (think it would be more complicated than this example)
I'm having an issue with dockers, I followed official docker tutorial to deploy a web app (and luckily a python/flask one) but when I tried to deploy my app when I come to the connection part it failed and reply "Connection was reset"
Code
import json
import threading
import thread
import io
from flask import Flask, render_template, request
from flask_socketio import SocketIO
# Global variables
app = Flask(__name__)
lock = threading.Semaphore(0)
IOCReplay.lock = lock
async_mode = None
socketio = SocketIO(app)
IOCReplay.socketio = socketio
#app.route("/")
def root():
return render_template('index.html')
#app.route("/dependencies")
def getDependencies():
data = ''
with open('./dependencies.json') as data_file:
data = json.load(data_file)
return json.dumps(data)
if __name__ == "__main__":
socketio.run(app, port=5000)
docker run -d -P guitest:1
6d95689601b8(...)
docker ps
CONTAINER ID IMAGE COMMAND
6d95689601b8 guitest:1 "python test.py"
CREATED STATUS PORTS NAMES
4 seconds ago Up 2 seconds 0.0.0.0:32771->5000/tcp loving_boyd
Dockerfile is OK.
Issue
And so when I'm logging into 0.0.0.0:32771 it says "Connection was reset"
I saw from docker FAQ that to correct this problem, i have to "change the service’s configuration on [my] localhost so that the service accepts requests from all IPs"
Ok I have solved all my problems! Thanks to #n2o
The problem was incorrect arguments for socketio.run(app)
Previous:
from flask import Flask, render_template, request
from flask_socketio import SocketIO
# Code here #
if __name__ == "__main__":
socketio.run(app, port=5000)
Fixed:
import os
from flask import Flask, render_template, request
from flask_socketio import SocketIO
# code here #
if __name__ == "__main__":
port = int(os.environ.get('PORT', 5000))
socketio.run(app, host='0.0.0.0', port=port)
I'm trying to automate the running of a script. Unfortunately, when I deploy to Heroku, my script doesn't run. I have attached the code for my server. 'newsAgg' is a reference to my script.
Can anyone clear up why my script file is not run when deployed? (It works locally)
from flask import Flask
import newsAgg as N
import threading
import os
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World!'
def set_interval(func, sec):
def func_wrapper():
set_interval(func, sec)
func()
t = threading.Timer(sec, func_wrapper)
t.start()
return t
newsInterval = set_interval(N.init, 3600)
N.init()
newsInterval()
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
How to specify listening address and port in web.py? Something like:
web.application( urls, host="33.44.55.66", port=8080 )
Edit
I would like to avoid using the default web.py command line parsing
From API docmentation of web.py:
module web.httpserver
function runsimple(func,server_address=('0.0.0.0', 8080))
Runs CherryPy WSGI server hosting WSGI app func. The directory static/ is hosted statically.
Example code
import web
class MyApplication(web.application):
def run(self, port=8080, *middleware):
func = self.wsgifunc(*middleware)
return web.httpserver.runsimple(func, ('0.0.0.0', port))
if __name__ == "__main__":
app = MyApplication(urls, globals())
app.run(port=8888)
If you're using web.py's built-in webserver, you can just append the port to the command:
python app.py 8080
I haven't tried ever with the listening address, but perhaps it will accept 1.2.3.4:8080 as the format.
you can see the follow code in wsgi.py:
server_addr = validip(listget(sys.argv, 1, ''))
if os.environ.has_key('PORT'): # e.g. Heroku
server_addr = ('0.0.0.0', intget(os.environ['PORT']))
return httpserver.runsimple(func, server_addr)
so, you can set the web server port by add environ variable:
import os
os.environ["PORT"] = "80"
URLS = ("/", index)
class index:
def GET:
....
if __name__ == "__main__":
app = web.application(URLS, globals())
web.httpserver.runsimple(app.wsgifunc(), ("0.0.0.0", 8888))