Serve Dash plotly app with Twisted Web Server - python

Dash is a dashboard-related python library that is based on Flask. The default dash app will run a Flask server, which is as they stated, "not recommended for production environment". I have managed to find Twisted library which can do decent html handling. The problem is, I know how to use Twisted to host flask sites, but I do not know how to do the same for dash app. There is a nice library which integrates both flask and twisted together.
https://github.com/cravler/flask-twisted
To use it, one just need to use the following lines:
server = flask.Flask(__name__)
app = dash.Dash(__name__, server = server)
twisted = Twisted(server)
twisted.run(host='0.0.0.0',port=8050, debug=False)
Now, for learning purposes, I am trying to recreate the same functionality without flask-twisted. I tried my best to follow the source code in the module but still cannot recreate the same result. The page http://127.0.0.1:8082/my_flask/ is stuck at "Loading...". What did I do wrong?
if __name__ == '__main__':
resource = WSGIResource(reactor, reactor.getThreadPool(), server)
site = Site(WSGIRootResource(resource, {}))
server.run
root = Resource()
root.putChild(b'my_flask', site)
reactor.listenTCP(8082, Site(root))
reactor.run()

Related

Creating an API to execute a python script

I have a python script app.py in my local server (path=Users/soubhik.b/Desktop) that generates a report and mails it to certain receivers. Instead of scheduling this script on my localhost, i want to create an API which can be accessed by the receivers such that they would get the mail if they hit the API with say a certain id.
With the below code i can create an API to display a certain text. But, what do i modify to run the script through this?
Also if i want to place the script in a server instead of localhost, how do i configure the same?
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return ("hello world")
if __name__ == '__main__':
app.run(debug=True)
Python Version is 2.7
A good way to do this would be to put the script into a function, then import that function in your Flask API file and run it using that. For hosting on a web server you can use Python Anywhere if you are a beginner else heroku is also a good option.
If you are tying to achieve something using Python-Flask API than you can have a close look at this documentations and proceed further https://www.flaskapi.org/, http://flask.pocoo.org/docs/1.0/api/
Apart from these here are few basic examples and references you can refer for a quickstart :
1-https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask
2- https://flask-restful.readthedocs.io/en/latest/
3- https://realpython.com/flask-connexion-rest-api/
You could do something like this
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class ExecuteScript:
def printScript:
return "Hello World"
api.add_resource(ExecuteScript, '/printScript')
if __name__ == '__main__':
app.run(debug=True)

Angular-cli with any other server

I'm relatively new to Angular 2, and I'm trying to build an app using the angular-cli system. This works and I can ng-serve and the application comes up. However, it seems like a huge pain in the ass to try and serve the application with anything other than the ng-serve system. In particular I'm trying to serve the application built with angular-cli with a Python Flask app. The amount of hoops I'm seemingly having to jump through trying to get this to work is making me crazy! I want to do this because I want to serve a REST API with the Python/Flask app that will respond to the HTTP services requests from the Angular 2 application.
Here are the relevant versions I'm using:
node - 6.2.2
npm - 2.9.5
angular 2 - rc.4
angular-cli - 1.0.0-beta.9
python - 2.7.5
flask - 0.10.1
How can I serve an Angular app while using Flask?
I've actually sort of solved the problem. I have a directory named "smoke" (short for smoke and mirrors ), and inside there I ran the angular-cli command:
ng new static
This created the angular-cli start out application in the static directory. Then I created this (simplified) Python Flask application:
import os
from flask import Flask, send_from_directory, redirect
from flask.ext.restful import Api
from gevent import monkey, pywsgi
monkey.patch_all()
def create_app():
app = Flask("press_controller")
# map the root folder to index.html
#app.route("/")
def home():
return redirect("/index.html")
#app.route("/<path:path>")
def root(path):
"""
This is the cheesy way I figured out to serve the Angular2 app created
by the angular-cli system. It essentially serves everything from
static/dist (the distribution directory created by angular-cli)
"""
return send_from_directory(os.path.join(os.getcwd(), "static/dist"), path)
return app
if __name__ == "__main__":
app = create_app()
server = pywsgi.WSGIServer(("0.0.0.0", 5000), app)
server.serve_forever()
else:
app = create_app()
This way I can navigate to http://localhost:5000 and the application will serve up the Angular app just like "ng serve" does. Now I can add in my REST API endpoints as I wanted and have Angular services access them to populate the application.
There's no requirement that Flask serves the frontend application.
Really all Flask would be doing with an Angular app is serving static files, something that is better handled by a web server like Nginx in production, or the framework's tools like ng-serve in development.
Meanwhile, Flask would act as the backend api server that your frontend app communicates with. Use request.get_json() and return jsonify(...) to get and respond with JSON data.
Run the two separately, they work together over HTTP only. This also simplifies working with backend vs. frontend developers: all they need to know about is the api to communicate between the two. However, since the frontend is being served on a different port than the backend, you'll need to set up Flask appropriately to allow CORS requests, for example with Flask-CORS.
Old question but I came across it when setting up my new project. I'm using a a more recent version of angular cli (7.3.1) and Flask (1.0.2) but the setup is pretty similar to yours. I should note that this is by no means the cleanest setup, and I'm sure the same could be achieved with webpack only, but I felt this way was a bit easier to follow (I've found webpack config can be a nightmare). My directory structure is as follows (after building):
client // this is my angular project
src
angular.json
server // this is my flask server
templates
index.html // generated from ng build
static
vendor.js // generated from ng build
pollyfills.js
...
Makefile
In angular.json, you'll want to point the build path to your flask server:
"build": {
"builder": "#angular-devkit/build-angular:browser",
"options": {
"outputPath": "../server/static",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"es5BrowserSupport": true
},
...
In my server, configure the static url:
app = Flask(__name__, static_url_path='')
And finally in the makefile, execute the build command, and copy the template file into the templates folder:
all:
cd client && ng build --prod;
mv server/static/index.html server/templates/ ;
.PHONY : all
Again, not the most elegant solution but pretty straight forward to get rolling with the angular cli (rather than getting the hands dirty with webpack).

How to rewrite python jsronrpc2 application to be able to function as wsgi app

I am having some problems understanding how a application written in python jsonrpc2 is related to a wgsi application.
I have a json rpc test application in a file called greeting.py
It is a simple test case
def hello(name=None,greeting=None):
# Print to stdout the greeting
result = "From jsonrpc you have: {greeting} , {name}".format(greeting=greeting,name=name)
# print result
# You can basically now return the string result
return result
Using the jsonrpc2 module I am able to POST json to this function which then returns a json response.
Sample post :
self.call_values_dict_webpost = dict(zip(["jsonrpc","method","id","params"],["2.0","greeting.hello","2",["Hari","Hello"]]))
Response returned as json:
u"jsonrpc": u"2.0", u"id": u"2", u"result": u"From jsonrpc you have: Hello , Hari"
I start the server with an entry point defined in the jsonrpc2 module which essentially does the following
from jsonrpc2 import JsonRpcApplication
from wsgiref.simple_server import make_server
app = JsonRpcApplication()
app.rpc.add_module("greeting")
httpd = make_server(host, port, app)
httpd.serve_forever()
I can currently run this jsonrpc2 server as a standalone "web app" and test it approproately.
I wanted to understand how to go from this simple function web app to a wsgi web app that reads and writes json without using a web framework such as flask or django ( which I know some of)
I am looking for whether there is a simple conceptual step that makes my function above compatible with a wsgi "callable" : or am I just better off using flask or django to read/receive json "POST" and write json response.
I don't know that particular module, but it looks like your app object is the WSGI application. All you do in that code is instantiate the app, then create a server for it via wsgiref. So instead of doing that, just point your real WSGI server - Apache/mod_wsgi, or gunicorn, or whatever - to that app object in exactly the same way as you would serve Flask or Django.

Getting the Server URL in Google App Engine using python

How do I get App Engine to generate the URL of the server it is currently running on?
If the application is running on development server it should return
http://localhost:8080/
and if the application is running on Google's servers it should return
http://application-name.appspot.com
You can get the URL that was used to make the current request from within your webapp handler via self.request.url or you could piece it together using the self.request.environ dict (which you can read about on the WebOb docs - request inherits from webob)
You can't "get the url for the server" itself, as many urls could be used to point to the same instance.
If your aim is really to just discover wether you are in development or production then use:
'Development' in os.environ['SERVER_SOFTWARE']
Here is an alternative answer.
from google.appengine.api import app_identity
server_url = app_identity.get_default_version_hostname()
On the dev appserver this would show:
localhost:8080
and on appengine
your_app_id.appspot.com
If you're using webapp2 as framework chances are that you already using URI routing in you web application.
http://webapp2.readthedocs.io/en/latest/guide/routing.html
app = webapp2.WSGIApplication([
webapp2.Route('/', handler=HomeHandler, name='home'),
])
When building URIs with webapp2.uri_for() just pass _full=True attribute to generate absolute URI including current domain, port and protocol according to current runtime environment.
uri = uri_for('home')
# /
uri = uri_for('home', _full=True)
# http://localhost:8080/
# http://application-name.appspot.com/
# https://application-name.appspot.com/
# http://your-custom-domain.com/
This function can be used in your Python code or directly from templating engine (if you register it) - very handy.
Check webapp2.Router.build() in the API reference for a complete explanation of the parameters used to build URIs.

Web interface for a twisted application

I have a application written in Twisted and I want to add a web interface to control and monitor it. I'll need plenty of dynamic pages that show the current status and configuration, so I hoped for a framework that offers at least a templating language with inheritance and some basic routing.
Since I am using Twisted anyways I wanted to use twisted.web - but it's templating language is too basic and it seems that the only framework, Nevow is quite dead (it's on launchpad but the homepage and wiki are down and I can't find any documentation).
So what are my options?
Is there any other twisted.web based framework?
Are there other frameworks that work with twisted's reactor?
Should I just get a web framework (I'm thinking web.py or flask) and run it in a thread?
Thanks for your answers.
Since Nevow is still down and I didn't want to write routing and support for a templating lib myself, I ended up using Flask. It turned out to be quite easy:
# make a Flask app
from flask import Flask, render_template, g
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
# run in under twisted through wsgi
from twisted.web.wsgi import WSGIResource
from twisted.web.server import Site
resource = WSGIResource(reactor, reactor.getThreadPool(), app)
site = Site(resource)
# bind it etc
# ...
It works flawlessly so far.
You can bind it directly into the reactor like the example below:
reactor.listenTCP(5050, site)
reactor.run()
If you need to add children to a WSGI root visit this link for more details.
Here is an example showing how to combine WSGI Resource with a static child.
from twisted.internet import reactor
from twisted.web import static as Static, server, twcgi, script, vhost
from twisted.web.resource import Resource
from twisted.web.wsgi import WSGIResource
from flask import Flask, g, request
class Root( Resource ):
"""Root resource that combines the two sites/entry points"""
WSGI = WSGIResource(reactor, reactor.getThreadPool(), app)
def getChild( self, child, request ):
# request.isLeaf = True
request.prepath.pop()
request.postpath.insert(0,child)
return self.WSGI
def render( self, request ):
"""Delegate to the WSGI resource"""
return self.WSGI.render( request )
def main():
static = Static.File("/path/folder")
static.processors = {'.py': script.PythonScript,
'.rpy': script.ResourceScript}
static.indexNames = ['index.rpy', 'index.html', 'index.htm']
root = Root()
root.putChild('static', static)
reactor.listenTCP(5050, server.Site(root))
reactor.run()
Nevow is the obvious choice. Unfortunately the divmod web server hardware and the backup server hardware failed at the same time. They are attempting to recover the data and publish it on launchpad, but it may take a while.
You could also use basically any existing template module with twisted.web; Jinja2 comes to mind.

Categories

Resources