I'm trying to build an API that execute a script with some variables,
those variables are in the POST msg, like {'command': 'start', 'name': 'var'}..
The thing is that I can't find the function the extraction those exact values and not all of the data.
after a few days I tried with flask but that idea is the same.
from flask import Flask, request
from flask_restful import Api, Resource
import os
script = 'python /home/USER/somepath/client.py start '
app = Flask(__name__)
api = Api(app)
class Netflix(Resource):
def get(self):
return "Success", 201
def post(self):
name = request.data
os.system(script+name)
print(name)
return "Success", 201
api.add_resource(Netflix, "/netflix")
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=8000)
class Netflix(Resource):
def get(self):
return "Success", 201
def post(self):
command = request.headers.get('command')
name = request.headers.get('name')
print(command+' '+name)
os.system(script+command+' '+name)
return "Success", 201
Related
Here is the code
import os
import redis
import flask
import json
import urllib.parse
from flask import Flask, Response, request, render_template, abort
from flask_cors import CORS, cross_origin
#from flask.ext.cors import CORS, cross_origin
app = Flask(__name__)
app.config['CORS_HEADERS'] = 'Content-Type'
redis_handle = redis.Redis('localhost')
requiredFields = ("id", "title", "name") # fields required for user object
#app.route('/')
#cross_origin()
def hello():
return 'Hello World!'
#app.route('/users/<user_id>', methods=['GET'])
#cross_origin()
def get_user(user_id):
response = {}
# user_id = request.args.get("id")
user = redis_handle.get(user_id)
if not user:
response["msg"] = "no user found"
return Response(json.dumps(response), status=404, mimetype="application/json")
return user
#app.route('/users', methods=['POST'])
#cross_origin()
def save_user():
data = request.get_json(force=True)
response = {}
if all(field in data for field in requiredFields):
redis_handle.set(data["id"], json.dumps(data))
return Response(status=201)
else:
missing_key = str([val for val in requiredFields if val not in dict(data).keys()])
response["msg"] = "required key " + missing_key + " not found"
return Response(json.dumps(response), status=400)
#app.route('/users/<user_id>', methods=['DELETE'])
#cross_origin()
def delete_user(user_id):
response = {}
resp = redis_handle.delete(user_id)
if resp == 0:
response["msg"] = "no such entity found"
status = 404
else:
response["msg"] = "Delete op is successful"
status = 200
return Response(json.dumps(response), status=status)
#app.route('/clear', methods=['GET'])
#cross_origin()
def clear_data():
redis_handle.flushall()
return "ok!"
if __name__ == "__main__":
app.run(debug=True)
As of my knowledge, I have even included the method = "POST" as well but still don't know what is going wrong.
I tried to create a small crud application using redis, python, flask but couldn't encountering this issue. Can someone tell me where and what am I doing wrong?
Browsers don't run POST methods outside of a <form> entry or AJAX function. Therefore, you're running a GET, which "isn't allowed".
Unclear what you expected, but to see all users, you'll need to edit your route to first add the GET method, then if so, return a response that returns/renders all users rather than checking the request json body, which won't exist for GET requests
If you only wanted to get one user, edit the url to include the user ID
The browser will use the GET method for URLs that you input in URL/search bar but you don't have any function decorated with #app.route('/users', methods=['GET']).
If you want to create a user with POST /users then it would be easier to use some HTTP client like https://www.postman.com, https://insomnia.rest, etc. or even fetch in the browser's console.
I am very new to working with Python Flask and i wanted to try a simple API-example:
from flask import Flask, jsonify, request
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
some_json = request.get_json()
return {'you sent': some_json}, 201
class Multi(Resource):
def get(self,num):
return {'result': num*10}
api.add_resource(HelloWorld, '/')
api.add_resource(Multi,'/multi/<int:num>')
if __name__ == '__main__':
app.run(debug=True)
and if I type in the terminal
-H "Content-Type: application/json" -X POST -d '{"name":"xyz","address":"myaddress"}' http://127.0.0.1:5000/
I get the following message:
{
"message": "The method is not allowed for the requested URL."
}
I hope someone can help me with this...
Since your are calling the POST HTTP method. You should rename 'get' function in class HelloWorld to 'post'. 'HelloWorld' class can also have both 'get' and a 'post' functions if '/' endpoint should serves both.
from flask import Flask, jsonify, request
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def post(self):
some_json = request.get_json()
return {'you sent': some_json}, 201
class Multi(Resource):
def get(self,num):
return {'result': num*10}
api.add_resource(HelloWorld, '/')
api.add_resource(Multi,'/multi/<int:num>')
if __name__ == '__main__':
app.run(debug=True)
I use Flask for setting up APIs. For some simple tests I return html tags. Using Flask_restplus however returns a string. I would like to know why and how I could change this? Of course I could use Jinja but I'd like to know how to change this in this small example.
from flask import Flask, request
from flask_restplus import Resource, Api, fields
app = Flask(__name__)
api = Api(app)
# This code returns HTML
#app.route('/test1')
def language():
language = request.args.get('language')
message = '<h1>Hello world! I speak {}</h1>'.format(language)
return message
# This code returns string e.g. '<h1>Hello wolrd! I speak english</h1>
#api.route('/hello')
class HelloWorld(Resource):
def get(self):
language = request.args.get('language')
message = '<h1>Hello world! I speak {}</h1>'.format(language)
return message
if __name__ == '__main__':
app.debug = True
app.run(port=4996)
As commented #app.route returns html and #api.route returns a string
Here is the code:
from flask import Flask, request, jsonify, Response
from flask_restplus import Resource, Api, fields
app = Flask(__name__)
api = Api(app)
# This code returns HTML
#app.route('/test1')
def language():
language = request.args.get('language')
message = '<h1>Hello world! I speak {}</h1>'.format(language)
return message
def output_html(data, code, headers=None):
resp = Response(data, mimetype='text/html', headers=headers)
resp.status_code = code
return resp
# This code returns string e.g. '<h1>Hello wolrd! I speak english</h1>
#api.route('/hello')
class HelloWorld(Resource):
def get(self):
language = request.args.get('language')
message = '<h1>Hello world! I speak {}</h1>'.format(language)
return output_html(message, 200)
if __name__ == '__main__':
app.debug = True
app.run(port=4996)
I have a small flask todo app, and trying to deploy it in heroku, but getting errors and I am unable to solve it, source code is here, this is working perfectly,
error screenshot can be seen here => http://prntscr.com/kyfwmy
Here is my app.py:
from flask import Flask, render_template, request, jsonify, url_for, redirect
from flask_cors import CORS
from flask_pymongo import PyMongo, pymongo
import sys, time
from bson.json_util import dumps, ObjectId
app = Flask(__name__)
app.config['MONGO_DBNAME']='todo'
app.config['MONGO_URI']='mongodb://todo_task:todo_task*123*#ds111082.mlab.com:11082/todo'
mongo = PyMongo(app)
cors = CORS(app, resources={r'/ajax/*': {"origins": '*'}})
#app.route('/')
def index():
_tasks = mongo.db.tasks.find().sort('created_at', pymongo.DESCENDING)
return render_template('index.html', tasks=_tasks)
#app.route('/add_task', methods=['POST'])
def add_task():
if request.method == 'POST':
tasks = mongo.db.tasks
data = {
'task': request.form['task'],
'status': 'view',
'created_at': time.strftime('%d-%m-%Y %H:%M:%S'),
'updated_at': time.strftime('%d-%m-%Y %H:%M:%S')
}
tasks.insert(data)
return redirect(url_for('index'))
#app.route('/destroy_task')
def task_destroy():
if request.method == 'GET':
id = request.args.get('id')
tasks = mongo.db.tasks
result = tasks.find_one({'_id': ObjectId(id)})
tasks.remove(result)
return redirect(url_for('index'))
#app.route('/ajax/task_update', methods=['POST'])
def task_update():
id = request.form['id']
tasks = mongo.db.tasks
result = tasks.find_one({'_id': ObjectId(id)})
if result['status'] == 'completed':
result['status'] = 'view'
res = {"status": 'view'}
else:
result['status'] = 'completed'
res = {"status": 'completed'}
result['updated_at'] = time.strftime('%d-%m-%Y %H:%M:%S')
tasks.save(result)
return jsonify({'status': res})
#app.route('/actives')
def actives():
tasks = mongo.db.tasks
_tasks = tasks.find({'status': 'view'}).sort('created_at', pymongo.DESCENDING)
return render_template('index.html', tasks=_tasks)
#app.route('/completes')
def completes():
tasks = mongo.db.tasks
_tasks = tasks.find({'status': 'completed'}).sort('created_at', pymongo.DESCENDING)
return render_template('index.html', tasks=_tasks)
#app.route('/clear_completes')
def clear_completes():
tasks = mongo.db.tasks
tasks.remove({'status': 'completed'})
return redirect(url_for('index'))
app.run(debug=True)
https://github.com/IrfanMumtaz/python-todo-app
You're not telling Flask what port to use, so it's trying to use port 5000 (its default):
app.run(debug=True)
Heroku tells you what port to use via the PORT environment variable. You need to use that variable's value when you run your application.
Something like this should work:
import os
# ...
app.run(port=os.getenv('PORT', 5000))
You will probably also want to disable debug mode:
Attention:
Even though the interactive debugger does not work in forking environments (which makes it nearly impossible to use on production servers), it still allows the execution of arbitrary code. This makes it a major security risk and therefore it must never be used on production machines.
I'm trying to deploy simple Azure web application. I create it exactly as described here
https://learn.microsoft.com/en-us/azure/app-service/app-service-web-get-started-python
but replaced code in main.py with following (and update requirements.txt of course):
from flask import Flask, request
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
todos = {}
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
class TodoSimple(Resource):
def get(self, todo_id):
return {todo_id: todos[todo_id]}
def put(self, todo_id):
todos[todo_id] = request.form['data']
return {todo_id: todos[todo_id]}
api.add_resource(HelloWorld, '/')
api.add_resource(TodoSimple, '/<string:todo_id>')
if __name__ == '__main__':
app.run(debug=True)
Everything works fine locally, but there are issues with deployed version:
-- http://my-app-name-here.azurewebsites.net is just fine and prints {'hello': 'world'} as expected
-- other commands provided by TodoSimple are not accessible.
For example following query
curl http://my-app-name-here.azurewebsites.net/todo -d "data=Remember the milk" -X PUT
would result with "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." response.
Update: it's all fine when ran locally
$curl http://localhost:5000/todo -d "data=Remember the milk" -X PUT
{
"todo": "Remember the milk"
}
Does anyone know what I'm missing with this app deployment?
Update2: approach without flask_restful won't work either:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
#app.route('/data')
def get_data():
return 'The data.'
if __name__ == '__main__':
app.run()
Calling http://my-app-name-here.azurewebsites.net/data results in "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." message again.