Google Drive API Webhook - python-3.x

I have set up a google drive webhook through the "watch property"(https://developers.google.com/drive/api/v2/reference/files/watch) and it is working well and submitting a response as soon as any changes are detected on the watch file. However, the request body (i.e.posted_data=request.get_data( )) as below comes back empty (i.e. None). I have tried other options such as request.json but still empty. Does anyone have any ideas on what I am possibly doing wrong? My Python Flask webhook code is below and works well (i.e. any file updates are posted) except that it returns an empty data type (i.e.posted_data=request.get_data( ) is None). Any suggestions are highly appreciated!
from datetime import datetime
from flask import Flask, request, jsonify
import pytz
def get_timestamp():
dt=datetime.now(pytz.timezone('US/Central'))
return dt.strftime(("%Y-%m-%d %H:%M:%S"))
app = Flask(__name__)
#app.route('/webhook', methods=['POST','GET'])
def webhook():
if request.method=='GET':
return '<h1> This is a webhook listener!</h1>'
if request.method == 'POST':
posted_data=request.get_data( )
print("We have received a request =====>",posted_data)
cur_date=get_timestamp()
print("Date and time of update ====>",cur_date)
http_status=jsonify({'status':'success'}),200
else:
http_status='',400
return http_status
if __name__ == '__main__':
app.run(port=5000)

The above code works except that google will post their response as headers (i.e. request.headers). See updated code below.
from datetime import datetime
from flask import Flask, request, jsonify
import pytz
def get_timestamp():
dt=datetime.now(pytz.timezone('US/Central'))
return dt.strftime(("%Y-%m-%d %H:%M:%S"))
app = Flask(__name__)
#app.route('/webhook', methods=['POST','GET'])
def webhook():
if request.method=='GET':
return '<h1> This is a webhook listener!</h1>'
if request.method == 'POST':
print(request.headers)
cur_date=get_timestamp()
print("Date and time of update ====>",cur_date)
http_status=jsonify({'status':'success'}),200
else:
http_status='',400
return http_status
if __name__ == '__main__':
app.run(port=5000)

Related

How to return 401 in flask despite authorization

I am new to flask and I want to return 401 error, I am not using authentication, I am simply using a parameter api_key to check whether the user is authenticated.
I've tried abort(401) and return false, but it returns error 400 'Bad Request', is this the default way it returns a 401. Or is there a different way to do this?
My Code:
import flask
from flask import jsonify, request, Response
from flask_cors import CORS, cross_origin
from GoogleNews import GoogleNews
googlenews = GoogleNews()
googlenews.set_lang('en')
googlenews.set_period('1d')
googlenews.set_encode('utf-8')
app=flask.Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
#cross_origin()
#app.route('/', methods=["GET"])
def return_news():
API_KEY = request.args['api_key']
if API_KEY == "xyz":
googlenews.get_news('TECHNOLOGY')
return jsonify(googlenews.result(True)[0:4])
else:
return Response(response="Unauthorized", status=401)
Thankyou
instead, try flask.Response object.
from flask import Flask, Response
app = Flask(__name__)
#app.route("/abort")
def abort():
return Response(response="Unauthorized", status=401)
app.run()
without the actual code it is hard to tell, but I think it is not using the flask abort() but the python internal abort() function.
Check the code below:
import flask
app = flask.Flask("aborter")
#app.route("/abort")
def abort():
return flask.abort(401)
if __name__ == '__main__':
app.run()
Happy Coding

Dictionary returned in Flask displays empty curly braces

I'm trying to make a flask pipeline which receives data from a python file and sends the data to react which display them.
I currently am stuck trying to receive the data in flask after sending them via post to the URL: localhost:5000/weather-data
The data is being posted with this Code:
dummy_data = {'data': str(msg.payload.decode('iso-8859-1')),
'timestamp': datetime.datetime.now().isoformat()}
response = requests.post(url, data=dummy_data)
print(response.text)
The print result is:
{"data": "{\"region\": \"Jokkmokk\", \"temp_now\": 8.91, \"weather_now\": \"bewölkt\", \"humidity\": 50, \"wind\": 24}",
"timestamp": "2021-02-24T17:23:15.347058"}
Which is all right but then i try to receive the data and return it on the flask side with this code:
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def test():
return 'HelloWorld'
#app.route('/weather-data', methods=['POST', 'GET'])
def weather_data():
try:
data = request.form.to_dict()
print(data)
return data
except Exception as e:
print(e)
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True, port=5000)
This runs normally through and my print(data) gives the exact same dictionary back but if i take a look at localhost:5000/weather-data i only see empty curly braces {}
As a Test i tried to return the data without receivng them first with this code:
#app.route('/weather-data', methods=['POST', 'GET'])
def weather_data():
return {"data": "{\"region\": \"Fishermans City\", \"temp_now\": 6.87, \"weather_now\": \"st\\u00fcrmisch\", "humidity\": 52, \"wind\": 58}",
"timestamp": "2021-02-23T18:32:49.120861"}
Like this it perfectly worked and showed the Data on the website.
Edit:
I think this is a stupid question for some of you but because i am kinda new to this i wanted to ask if it is possible that the Data is on the Page but when i reload the Page it overwrites the data with empty curly braces?
If yes is there a way that i can keep them on the Page until i make another Post with new data?
You need to use jsonify
from flask import Flask, request
from flask import jsonify
app = Flask(__name__)
data = dict()
#app.route('/')
def test():
return 'HelloWorld'
#app.route('/weather-data', methods=['POST', 'GET'])
def weather_data():
if request.method == 'POST':
global data
data = request.form.to_dict()
return jsonify(data), 200
else:
return jsonify(data), 200
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True, port=5000)
Have you tried using json?
response = requests.post(url, json=dummy_data)
and
data = request.json

I am having error invalid syntax in my python code

I am trying to add multiple inner function in my code. But I am not able to add it properly and also it is giving me a syntax error. Here I am trying to run my python script when I click a button and it will take input from a textfield and then run my script which has multiple functions. Is this the right way to add inner functions or is there another way to do this?
ERROR
File "server.py", line 17``
pass = request.form['typed']here
^
SyntaxError: invalid syntax
[1]: https://i.stack.imgur.com/H6Mg2.png
from flask import Flask, render_template, url_for, request, redirect
app= Flask(__name__)
#app.route('/')`enter code here`
def my_home():
return render_template('index.html')
#app.route('/<string:page_name>')
def html_page(page_name):
return render_template(page_name)
import hashlib
import sys
import requests
#app.route('/send',methods =['POST'])
def send():
if request.method == 'POST':
pass = request.form['typed']
def request_api_data(query_char)
res = requests.get(url)
if res.status_code != 200:
raise RuntimeError(f'Error fetching: {res.status_code}, check the api and try again')
return res
pass is a statement and cannot be used as a variable name.
https://docs.python.org/3/tutorial/controlflow.html#pass-statements
from flask import Flask, render_template, url_for, request, redirect
app= Flask(__name__)
#app.route('/')`enter code here`
def my_home():
return render_template('index.html')
#app.route('/<string:page_name>')
def html_page(page_name):
return render_template(page_name)
import hashlib
import sys
import requests
#app.route('/send',methods =['POST'])
def send():
if request.method == 'POST':
# pass = request.form['typed']
my_pass = request.form['typed'] # <- this should work.
def request_api_data(query_char)
res = requests.get(url)
if res.status_code != 200:
raise RuntimeError(f'Error fetching: {res.status_code}, check the api and try again')
return res

Unable to decode "devanagari text" passed as URL param

My Python Flask App is unable to decode the devanagari text eg:"सिंगापूर" that I pass as urlparam from my postman. If I sen english text it handles it well.
My PostMan query :
GET http://localhost:5000/getSimilarWord/सिंगापूर
from flask import Flask
from flask_restful import Resource, Api
class DevnagriText(Resource):
def get(self, textInput):
print("parsed String is :",textInput)
return {'text': textInput}
api.add_resource(DevnagriText, '/getWord/<string:textInput>')
if __name__ == '__main__':
app.run(debug=True)
The output I get on console is
{
"text": "\u00818"
}
Instead of
{
"text": "सिंगापूर"
}
You need to prevent the response from forcing ASCII: app.config['JSON_AS_ASCII'] = False
So in your example:
from flask import jsonify, Flask
from flask_restful import Resource, Api
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
api = Api(app)
class DevnagriText(Resource):
def get(self, textInput):
print("parsed String is :",textInput)
return jsonify(text=textInput)
api.add_resource(DevnagriText, '/getWord/<string:textInput>')
if __name__ == '__main__':
app.run(debug=True)
But, this doesn't really matter, it will all get interpreted the same way if it gets read into Python or JavaScript.

Pass filepath as parameter to a URL in FLASK(Python)

I want to build an api which accepts a parameter from the user which is a filepath and then process the file given in that path. The file to be processed is already in the server where the api will be running.
As of now, I have written an api where I have hardcoded the filepath in my code which runs the api. Now, I want to configure my api in such a way that accepts a filepath from the user. My api should accept the path as a parameter and process the file that has been given in the path.
The api code is as follows:
The convert function returns the category of the file.
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
#convert(r'D:\files\67cecf40-71cf-4fc4-82e1-696ca41a9fba.pdf')
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
categories=convert(r'D:\files\6628cb99-a400-4821-8b13-aa4744bd1286.pdf')
#app.route('/')
def returnResult():
return categories
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
So, I want to make changes to this code to accept a parameter from the user which will be a filepath and the convert function will process that filepath. I want to know how to make my api accept a filepath parameter from the user.
Trial with requests.args.get:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
#convert(r'D:\files\67cecf40-71cf-4fc4-82e1-696ca41a9fba.pdf')
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
#app.route('/')
def returnResult():
categories=convert(r'D:\files\'.format(request.args.get('categories')))
return categories
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
results in error :
"RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem."
PRESENT SCENARIO:
I am able to post a filepath to the url. My question is now how do I use this posted url with filepath in my code to trigger my function that takes in the filepath and processes the file. Code to post the filepath:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
categories=convert('/home/brian/ajay/files/5ca21af9-5b67-45f8-969c-ae571431c665.pdf')
#app.route('/')
def returnResult():
return categories
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def get_dir(path):
return path
##app.route('/get_dir/<path>')
#def get_dir(path):
# return path
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)

Resources