My server.py is as follows,
from flask import Flask, jsonify, Response, redirect
import json
from UIAccess import UIAccess
app=Flask(__name__)
#app.route('/Hello/<username>')
def id_no(username):
id= obj.get_id(username)
return json.dumps(id)
if __name__ == '__main__':
obj=UIAccess()
app.run(threaded=True)
when I run the program and load the page using my browser I am able to view the output of 'id_no' but if I run the same program using twisted with the command,
twistd web --wsgi server.app
I get an internal server error, I am wondering whether this is the correct way to do this?
You only create obj if __name__ == '__main__', which it does not when you run with something besides python server.py. But the id_no view depends on obj being defined, so it fails. Move obj = UIAccess() out of the guard block.
Related
The following scenario:
I have a Raspberry Pi running as a server. Currently I am using a Python script with Flask and I can also access the Raspberry Pi from my PC. (The flask server runs an react app.)
But the function should be extended. It should look like the following:
2nd Python script is running all the time. This Python script fetches data from an external API every second and processes it. If certain conditions are met, the data should be processed and then the data should be communicated to the Python Flask server. And the Flask server then forwards the data to the website running on the computer.
How or which method is best to program this "interprocess communication". Are there any libraries? I tried Celery, but then it throws up my second Python script whenever I want to access the external API, so I don't know if this is the right choice.
What else would be the best approach? Threading? Direct interprocess communication?
If important, this is how my server application looks so far:
from gevent import monkey
from flask import Flask, render_template
from flask_socketio import SocketIO
monkey.patch_all()
app = Flask(__name__, template_folder='./build', static_folder='./build/static')
socket_io = SocketIO(app)
#app.route('/')
def main():
return render_template('index.html')
#socket_io.on('fromFrontend')
def handleInput(input):
print('Input from Frontend: ' + input)
send_time()
#socket_io.on('time')
def send_time():
socket_io.emit('time', {'returnTime': "some time"})
if __name__ == '__main__':
socket_io.run(app, host='0.0.0.0', port=5000, debug=True)
Well i found a solution for my specific problem i implemented it with a thread as follows:
import gevent.monkey
gevent.monkey.patch_all()
from flask import Flask, render_template
from flask_socketio import SocketIO
import time
import requests
from threading import Thread
app = Flask(__name__, template_folder='./build', static_folder='./build/static')
socket_io = SocketIO(app)
#app.route('/')
def main():
thread = Thread(target=backgroundTask)
thread.daemon = True
thread.start()
return render_template('index.html')
#socket_io.on('fromFrontend')
def handleInput(input):
print('Input from Frontend: ' + input)
#socket_io.on('time')
def send_time():
socket_io.emit('time', {'returnTime': 'hi frontend'})
def backgroundTask():
# do something here
# access socket to push some data
socket_io.emit('time', {'returnTime': "some time"})
if __name__ == '__main__':
socket_io.run(app, host='0.0.0.0', port=5000, debug=True)
I have a Python script that pulls data from a 3 rd party API. Currently this Pyhton script is automated on server side.
There are few instances where I have to toggle the script manually for new data updates. For the manual toggle I have to login to the server each time and run it from command line. Is there a way where I can create web url or something similar and just run that URL to make that script run from the browser address bar.
One approach you could take is to use Flask, which is a minimal web framework. Here's an example of how you could use it:
from flask import Flask
from your_script import your_func
app = Flask(__name__)
#app.route('/run')
def run_command():
your_func()
return 'Executed your function!'
if __name__ == '__main__':
app.run(debug=False, port=8080)
If you run this code you'd get a web server running on port 8080 that executes your function when you access the url. Here's a tutorial in the Flask documentation to get you started.
I think the easiest way to do this is by using Flask.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
# your code here
return 'Hello, World!'
I have been trying to follow the tutorials to get flask apps to run on Heroku, like this one: https://dev.to/emcain/how-to-set-up-a-twitter-bot-with-python-and-heroku-1n39.
They all tell you to put this in your code in a file server.py:
from flask import Flask
app = Flask(__name__)
app.run(host='0.0.0.0')
And then run the app via the following command:
python3 server.py
But the tutorials don't explain how to connect the actual function you want to run using the app. In my case, I have a File testbot.py that has the function test(arg1) that contains the code I want to execute:
def test(arg1):
while(1):
#do stuff with arg1 on twitter
I want to do something like this:
from flask import Flask
from testbot import test
from threading import Thread
app = Flask(__name__)
app.addfunction(test(arg1='hardcodedparameter'))
app.run(host='0.0.0.0')
So that when the app runs my test() function executes with the argument. Right now my server is starting, but nothing is happening.
Am I thinking about this correctly?
*Edit: I got it working with the solution, so my server.py now looks like this:
from flask import Flask
from testbot import test
def main_process():
test("hardcodeparam")
app = Flask(__name__)
Thread(target=main_process).start()
app.run(debug=True,host='0.0.0.0')
And now test runs as expected.
Before app.run, register the function with a path, e.g.
#app.route('/')
def test(): # no argument
... do one iteration
return 'ok'
Then visiting the URL will trigger the function. Sites such as https://cron-job.org/ can automate that visiting on a regular basis for free, as suggested here.
If the regular intervals aren't good enough, then you could try:
#app.route('/')
def index(): # no argument
return 'ok'
def test():
while True:
# do stuff
from threading import Thread
Thread(target=test).start()
app.run(...)
You will probably still need to have a job regularly visiting the URL so that Heroku sees that the server is alive and in use.
I'm trying to create a python Flask REST web API. Since Flask development server is not suitable for production, I tried to use cherrypy application server.
Following is the Flask app I tried to expose via cherrypy
from flask import Flask,request
from flask_restful import Api,Resource, reqparse
app= Flask(__name__)
api = Api(app)
class Main (Resource):
def get(self):
return "Hello Flask"
if __name__ == '__main__':
api.add_resource(Main, "/testapp/")
app.run(debug=True)
Following is the cherrypy script I have created
try:
from cheroot.wsgi import Server as WSGIServer, PathInfoDispatcher
except ImportError:
from cherrypy.wsgiserver import CherryPyWSGIServer as WSGIServer, WSGIPathInfoDispatcher as PathInfoDispatcher
from stack import app
d = PathInfoDispatcher({'/': app})
server = WSGIServer(('127.0.0.1', 8080), d)
if __name__ == '__main__':
try:
server.start()
print("started")
except KeyboardInterrupt:
server.stop()
I have saved this script as "run.py" in my project directory. When I run this it doesn't show any error, which made me to thin this is correct.
But unfortunately I cant access this using the url
Theoretically, url for this API should be some thing like follow
http://127.0.0.1:8080/testapp/
But it throws 404 with the message
"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
What am I doing wrong ?
The
api.add_resource(Main, "/testapp/")
in your file stack.py is not executed if the file is included from your run.py
as the condition
if __name__ == '__main__':
...
is not true (in the context of stack.py).
Moving the call to api.add_resource(...) to a position outside the if-main-condition (so it is always executed) should solve the issue.
The answer that I found on the web is to use request.args.get. However, I cannot manage it to work. I have the following simple example:
from flask import Flask
app = Flask(__name__)
#app.route("/hello")
def hello():
print request.args['x']
return "Hello World!"
if __name__ == "__main__":
app.run()
I go to the 127.0.0.1:5000/hello?x=2 in my browser and as a result I get:
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.
What am I doing wrong?
The simple answer is you have not imported the request global object from the flask package.
from flask import Flask, request
This is easy to determine yourself by running the development server in debug mode by doing
app.run(debug=True)
This will give you a stacktrace including:
print request.args['x']
NameError: global name 'request' is not defined
http://localhost:5000/api/iterators/opel/next?n=5
For something like the case before
from flask import Flask, request
n = request.args.get("n")
Can do the trick