How to run a bokeh server without 'bokeh server --show' command? - python-3.x

I want to run a bokeh interactive application without using "bokeh serve --show" command. Instead, I want to use 'python script_name.py' syntax.
Is there any way to do this?

bigreddot is correct, but the commands given there won't start a bokeh server by itself; you'll need an existing Tornado server running; so here's a standalone solution given in bokeh's docs in the same section:-
Here's the relevant section that starts the server. For the complete example refer to the example code from bokeh's documentation
server = Server({'/': bkapp}, num_procs=4)
server.start()
if __name__ == '__main__':
print('Opening Bokeh application on http://localhost:5006/')
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()

This is covered in the project documentation:
https://docs.bokeh.org/en/latest/docs/user_guide/server.html#embedding-bokeh-server-as-a-library
from bokeh.server.server import Server
server = Server(
bokeh_applications, # list of Bokeh applications
io_loop=loop, # Tornado IOLoop
**server_kwargs # port, num_procs, etc.
)
# start timers and services and immediately return
server.start()

Related

How do I profile Flask?

I've a very simply flask application, like:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def sth():
return 'STH'
.
I'd like to profile (cProfile, profile) it in a way that it collects the profiling information from the start of the webserver until the end of the webserver run, and writes the data only at the end of the run. I need the results written into a file, and not into any database.
By starting the webserver with
/path/venv/bin/python -m cProfile -m flask --debug --app entry.py run
command, it works as expected, however, for some reason I'd like to add this logic into the entry.py file. (Note the -m cProfile switch.).
What'd be the best way to achieve this?
I tried to play around with the cProfile.run() and app.run(), but that did not really work, and also not advised to use in production.
I also tried the profilerMiddleware from werkzeug.middleware.profile and the flask_profiler, but had no luck with my goal.
Thanks.

How do you host a multi-page Dash application on IIS?

I am trying to host a multi-page Dash application on IIS for internal use at work. I have been able to get single-page Dash applications, such as below to work.
from flask import Flask
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
server=Flask(__name__)
app = dash.Dash(__name__, suppress_callback_exceptions=True, show_undo_redo=True, server=server)
app.layout = html.Div([])
#app.callback(Output('page-content', 'children'),
Input('url', 'pathname'))
def hello():
return "Single page dash app works but not multi-page"
if __name__ == "__main__":
app.run_server(host='0.0.0.0', port=84)
However, when I try to use it on multi-page dash applications, as described in the user manual here, it doesn't work correctly. I am able to host the application using Waitress, but would prefer something more stable and secure. IIS is how my company hosts other internal applications, so I was asked to host it that way. When attempting to use what I believe is the correct settings and handler mappings, I receive an error message on the page that simply says:
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
I believe that the issue is due to the fact that the flask application behind my Dash application is created in one script, and the entry point to the overall application is in another. I am not sure how to reconcile this, as the example page in the Dash documentation says that it must be this way.
So, how can I make this work?
cheers

Am I using application dispatching in Flask correctly?

I am fairly new to Flask applications, but well versed in Python. I have recently begun making web applications instead of regular application and I'm trying to gather some of them on a single server. Enter "Application Dispatching".
I was hoping to be able to develop an app locally and then deploy it on the server using dispatching. This means that locally I will have a script that launches the Flask app (wsgi.py), which imports stuff in the application. Now, once I add it to the dispatcher, I import the new application. This means that before the wsgi.py was a script and now it is a module - all hell breaks loose.
dispatcher.py:
from flask import Flask
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.exceptions import NotFound
from app1 import app as app1
from app2 import app as app2
from app3 import app as app3
from app4 import app as app4
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(NotFound(), {
"/app1": app1,
'/app2': app2,
'/app3': app3,
'/app4': app4,
})
if __name__ == "__main__":
app.run()
app1\__init__.py: (works like this, but merely a proof of concept / simple app)
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index_one():
return "Hi im 1"
if __name__ == "__main__":
app.run()
Both of these work - the dispatcher and the app1 can be run independently. Now, let's say I need to import a module to make app1 more functional:
from flask import Flask
import db
...
Since the dispatcher is in a parent directory, in order for it to work I need to do something like this:
from . import db
# or
from app1 import db
Now the application doesn't work independently anymore. I would like to avoid either having to refactor the application every time it needs to be deployed or adding a lot of boilerplate code like this:
if __name__ == "__main__":
import db
else:
from . import db
In any case this doesn't work when configuring the app with app.config.from_object("config.Config") as it can't be forced to be relative import (?) and otherwise can't find it without explicitly telling it which module it resides in.
From the tutorial, I got the sense that I could isolate the applications from each other:
Application dispatching is the process of combining multiple Flask
applications on the WSGI level. You can combine not only Flask
applications but any WSGI application. This would allow you to run a
Django and a Flask application in the same interpreter side by side if
you want. The usefulness of this depends on how the applications work
internally.
The fundamental difference from Large Applications as Packages is that
in this case you are running the same or different Flask applications
that are entirely isolated from each other. They run different
configurations and are dispatched on the WSGI level.
What am I doing wrong and can I get it working like I describe, by being able to launch the applications isolated or on the dispatcher, without changing my code or adding a bunch of unrelated boilerplate code to make it work?
I figured it out myself and indeed was using application dispatcher wrong. It will always integrate the different applications into one server instance.
Instead, I found out that using nginx could be used to forward to different server instances, thus completely separating the applications in each virtual environment.

is there a way to run flask on a thread?

in order to implement a system which exposes REST-api and run another functionality simultaneously, i tried to use flask like the flask like the following:
app = Flask(__name__)
app.run(threaded=True)
foo()
but foo function never starts.
I would to understand how to solve the problem or get an alternative option to implement it.
Thanks!
Going to the documentation for Flask.run() we see that the options provided (such as threaded) are forwarded to the underlying function werkzeug.run_simple(). The documentation for werkzeug.run_simple() says the following about the threaded parameter:
threaded – should the process handle each request in a separate thread?
This means that each REST call will be handled in a separate thread, but does not start the server in the background (which seems to be what you want). Instead, you can use the Process class from multiprocessing:
from flask import Flask
app = Flask(__name__)
from multiprocessing import Process
p = Process(target=app.run)
p.start()
foo()
This will start your flask app in the background, letting you run other functions after starting the app.

Flask + Bokeh Server on Azure Web App Service

I want to host my bokeh server app in Azure Web App Services. Following the example in flask_embed.py I created a minimal example with a bokeh server process running on localhost:5006 and serving it with server_document in a flask route. Locally, in my computer, it runs normally without any errors:
from threading import Thread
from bokeh.embed import server_document
from bokeh.server.server import Server
from bokeh.models.widgets import Select, Div
from bokeh.layouts import column
from flask import Flask
from flask import render_template
from tornado.ioloop import IOLoop
app = Flask(__name__)
# This is the bokeh page
def modify_doc(doc):
dropdown = Select(title="Cities", options=["New York", "Berlin"])
title_row = Div(text="Home Page")
main_layout = column([
title_row,
dropdown
])
doc.add_root(main_layout)
doc.title = "My bokeh server app"
# This is the subprocess serving the bokeh page
def bk_worker():
server = Server(
{'/bkapp': modify_doc},
io_loop=IOLoop(),
allow_websocket_origin=["*"],
)
server.start()
server.io_loop.start()
Thread(target=bk_worker).start()
# This is the flask route showing the bokeh page
#app.route("/", methods=["GET"])
def my_app():
script = server_document("http://localhost:5006/bkapp")
return render_template("embed.html", script=script, template="Flask")
However, when I push it to the Azure web app, the page is blank and by inspecting the page an error message is shown:
GET https://<my-azure-site>.azurewebsites.net:5006/bkapp/autoload.js?bokeh-autoload-element=0bfb1475-9ddb-4af5-9afe-f0c4a681d7aa&bokeh-app-path=/bkapp&bokeh-absolute-url=https://<my-azure-site>.azurewebsites.net:5006/bkapp net::ERR_CONNECTION_TIMED_OUT
It seems like I don't have access to the localhost of the remote Azure server. Actually, it's not yet clear to me if the bokeh server runs/is allowed to run at all. In the server_document function I have tried putting server_document("<my-azure-site>:5006/bkapp") but the problem remains the same.
Any help is appreciated.
This post is related to another question: Bokeh embedded in flask app in azure web app
I realize this is from a while ago, but I've spent many hours in the past several days figuring this out, so this is for future people:
The issue is that server_document() is just creating a <script> tag that gets embedded into a jinja2 template, where it executes.
Locally it's not an issue because your bokeh server is running on YOUR MACHINE'S localhost:5006. To demonstrate, you can see that you can navigate directly to localhost:5006/bkapp to see your bokeh document.
Once you're hosting it on Azure, server_document() is creating the exact same script that a browser will try to execute - that is, your browser is going to try to execute a <script> tag that references localhost:5006, except that there isn't anything running on localhost:5006 because your bokeh app is actually running on Azure's server now.
I'm not sure what the best way to do it is, but the essence of it is that you need server_document() to point to the bokeh server that's running remotely. To do this you'll need to make sure that {your_remote_bokeh_server}:5006 is publicly accessible.

Resources