i'm trying to make an app in flask-python that using a json post send an audio using the gtts google library as the answer, but my method doesn't work. My code is the following.
from gtts import gTTS
from flask import Flask, send_file, request
app = Flask(__name__)
#app.route("/")
def t2s():
text = request.get_json()
obj = gTTS(text = text, slow = False, lang = 'en')
obj.save('audio.wav')
return send_file('audio.wav')
if __name__ == "__main__":
app.run(port=3000 , debug=True, use_reloader=True, host='0.0.0.0')
any suggestions?, i'm using postman.
Thanks a lot for the possible help
Flask as default doesn't get POST requests and you have to use methods=['POST', 'GET']
from gtts import gTTS
from flask import Flask, send_file, request
app = Flask(__name__)
#app.route("/", methods=['POST', 'GET'])
def t2s():
text = request.get_json()
print(text)
obj = gTTS(text = text, slow = False, lang = 'en')
obj.save('audio.wav')
return send_file('audio.wav')
if __name__ == "__main__":
app.run(host='0.0.0.0', port=3000)
And test (using mplayer on Linux):
import requests
import os
data = 'Hello World'
r = requests.post('http://127.0.0.1:3000/', json=data)
open('output.wav', 'wb').write(r.content)
os.system('mplayer output.wav')
Related
I'm trying to verify that the Webhook received is coming from Shopify. They have this doc, but it doesn't work (getting type errors).
Here's what I have so far. It produces no errors, but the verify_webhook function always returns false.
from flask import Flask, request, abort
import hmac
import hashlib
import base64
app = Flask(__name__)
SECRET = '...'
def verify_webhook(data, hmac_header):
digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
genHmac = base64.b64encode(digest)
return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))
#app.route('/', methods=['POST'])
def hello_world(request):
print('Received Webhook...')
data = request.get_data()
hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
verified = verify_webhook(data, hmac_header)
if not verified:
return 'Integrity of request compromised...', 401
print('Verified request...')
if __name__ == '__main__':
app.run()
What am I doing wrong?
Answer:
from flask import Flask, request, abort
import hmac
import hashlib
import base64
app = Flask(__name__)
SECRET = '...'
def verify_webhook(data, hmac_header):
digest = hmac.new(SECRET.encode('utf-8'), data, hashlib.sha256).digest()
genHmac = base64.b64encode(digest)
return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))
#app.route('/', methods=['POST'])
def hello_world(request):
print('Received Webhook...')
data = request.data # NOT request.get_data() !!!!!
hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
verified = verify_webhook(data, hmac_header)
if not verified:
return 'Integrity of request compromised...', 401
print('Verified request...')
if __name__ == '__main__':
app.run()
Issue was in the data = request.get_data() line.
I have setup authentication on my flask backed Dash-plotly app using Kong oauth2 plugin. I want to send the authentication header to my dash app on the /dash route. I tried sending the same via my flask backend in the resp header.
from flask import Blueprint, Flask, flash, render_template, request, jsonify, Response, redirect, make_response, url_for, session
from flask_cors import CORS, cross_origin
from .. import server
import requests, logging, json, ast
login_controller = Blueprint(
'login_controller', __name__, template_folder='templates')
def check(username, password):
# test case
if(username == "admin" and password == "admin"):
session['logged_In'] = True
val = '1'
else:
flash("Invalid Username or/and password")
val = None
return val
#login_controller.route("/login", methods=['POST'])
def login():
if(request.method == 'POST'):
error = None
val = check(request.form['username'], request.form['password'])
if session.get("logged_In") and val:
# kong access token will be available here
Session[KONG_ACCESS_TOKEN]
resp = make_response(redirect("/dash"))
resp.headers['Authorization'] = "Bearer "+KONG_ACCESS_TOKEN
resp.set_cookie("login_auth", val, 60*15)
logging.info("Authentication successful")
return resp
else:
resp = make_response(redirect("/"))
logging.info("Authentication failed")
return resp
I am correctly getting the header in the resp from the login route but it does not show up in the request header and I get unauthorized response on redirection to /dash
Here, is my app.py for the Dash app
import flask, os, dash, logging
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from ..server import server
from logging.handlers import RotatingFileHandler
external_stylesheets = [
"some stylesheets"
]
df = pd.read_csv(open(os.path.abspath(
"example.csv")), 'r', delimiter=',')
logging.info('Dash Application launched on Flask server')
app = dash.Dash(__name__, server=server,
external_stylesheets=external_stylesheets, url_base_pathname="/dash")
app.config.suppress_callback_exceptions = True
data = df.copy()
def indicator(text, id_value, size):
return html.Div(
[
html.Div(
text,
className="class1"
),
html.Div(
id_value,
id=text,
className="class2"
),
],
className=size,
)
Appreciate any help in this regards.
This question already has answers here:
Read file data without saving it in Flask
(8 answers)
Opening a file that has been uploaded in Flask
(2 answers)
Closed 4 years ago.
With server.py running:
from flask import Flask, request, Response
app = Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got files: %s' % request.files)
return Response()
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
send a request using client.py:
import json, requests
dictionary_1 = {"file": {"url": "https://bootstrap.pypa.io/get-pip.py"}}
files = [('dictionary_1', ('get-pip.py', json.dumps(dictionary_1), 'application/json'))]
response = requests.post('http://127.0.0.1:5000/test', files=files)
Server logs that it received a request:
got files: ImmutableMultiDict([('dictionary_1', <FileStorage: u'get-pip.py' ('application/json')>)])
Apparently, the dictionary_1 was received as FileStorage object.
How to turn the received FileStorage into the Python dictionary?
edited later
The possible duplicate post does not clarify how to send and unpack the Python dictionary object sent via requests(files=list())
This is happening because you're posting files instead of data. This should work:
import flask
app = flask.Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got data: {}'.format(flask.request.json))
return Response()
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
and then send data to your app by
import requests
dictionary_1 = {"file": {"url": "https://bootstrap.pypa.io/get-pip.py"}}
response = requests.post('http://127.0.0.1:5000/test', json=dictionary_1)
In your example there's no need to post the file unless I'm misunderstanding something
Solution # 1:
from flask import Flask, request, Response
import StringIO, json
app = Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got files: %s' % request.files)
for key, file_storage in request.files.items():
string_io = StringIO.StringIO()
file_storage.save(string_io)
data = json.loads(string_io.getvalue())
print('data: %s type: %s' % (data, type(data)) )
return Response()
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
Solution # 2:
from flask import Flask, request, Response
import tempfile, json, os, time
app = Flask(__name__)
#app.route('/test', methods=['GET','POST'])
def route():
print('got files: %s' % request.files)
for key, _file in request.files.items():
tmp_filepath = os.path.join(tempfile.mktemp(), str(time.time()))
if not os.path.exists(os.path.dirname(tmp_filepath)):
os.makedirs(os.path.dirname(tmp_filepath))
_file.save(tmp_filepath)
with open(tmp_filepath) as f:
json_data = json.loads(f.read())
print type(json_data), json_data
return Response(json_data)
if __name__ == '__main__':
app.run('0.0.0.0', 5000)
I have two servers where one is trying to get a file from the other. I am using Flask get requests to send simple data back and forth (strings, lists, JSON objects, etc.).
I also know how to send just a file, but I need to send an error code with my data.
I'm using something along the following lines:
Server 1:
req = requests.post('https://www.otherserver.com/_download_file', data = {'filename':filename})
Server 2:
#app.route('/_download_file', methods = ['POST'])
def download_file():
filename = requests.form.get('filename')
file_data = codecs.open(filename, 'rb').read()
return file_data
Server 1:
with codecs.open('new_file.xyz', 'w') as f:
f.write(req.content)
...all of which works fine. However, I want to send an error code variable along with file_data so that Server 1 knows the status (and not the HTTP status, but an internal status code).
Any help is appreciated.
One solution that comes to my mind is to use a custom HTTP header.
Here is an example server and client implementation.
Of course, you are free to change the name and the value of the custom header as you need.
server
from flask import Flask, send_from_directory
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
response = send_from_directory(directory='your-directory', filename='your-file-name')
response.headers['my-custom-header'] = 'my-custom-status-0'
return response
if __name__ == '__main__':
app.run(debug=True)
client
import requests
r = requests.post(url)
status = r.headers['my-custom-header']
# do what you want with status
UPDATE
Here is another version of the server based on your implementation
import codecs
from flask import Flask, request, make_response
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
filename = request.form.get('filename')
file_data = codecs.open(filename, 'rb').read()
response = make_response()
response.headers['my-custom-header'] = 'my-custom-status-0'
response.data = file_data
return response
if __name__ == '__main__':
app.run(debug=True)
Testing Flask applications is done with:
# main.py
from flask import Flask, request
app = flask.Flask(__name__)
#app.route('/')
def index():
s = 'Hello world!', 'AJAX Request: {0}'.format(request.is_xhr)
print s
return s
if __name__ == '__main__':
app.run()
Then here is my test script:
# test_script.py
import main
import unittest
class Case(unittest.TestCase):
def test_index():
tester = app.test_client()
rv = tester.get('/')
assert 'Hello world!' in rv.data
if __name__ == '__main__':
unittest.main()
In the test output, I'll get:
Hello world! AJAX Request: False
Question
How do I test my app with AJAX requests?
Try this:-
def test_index():
tester = app.test_client()
response = tester.get('/', headers=[('X-Requested-With', 'XMLHttpRequest')])
assert 'Hello world!' in response.data
import json
def test_index():
data = json.dumps({})
client = app.test_client()
headers = {
'Content-Type': 'application/json',
}
response = client.post('/', data=data, headers=headers)
data = json.loads(response.data)
assert data
`