Flask access request data when uploading file with angular - python

I'm uploading a file using angular and try to access the uploaded file in flask.
This is no problem and works fine. However, when I add more request parameters I cannot seem to find them in the flask request object.
For example, uploading a file using ngFileUpload (https://github.com/danialfarid/ng-file-upload) I can specify more meta-information like this:
$scope.upload = function (file) {
Upload.upload({
url: '/api/upload',
data: {file: file, 'username': $scope.username}
})
};
where username is extra meta-information.
Here's the flask code (using Flask-Restful):
from flask import Flask, request, Response
from flask.ext.restful import Api, Resource
ALLOWED_EXTENSIONS = {'csv'}
def allowed_file(fn):
return '.' in fn and fn.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
app = Flask(__name__)
api = Api(app)
class Upload(Resource):
def post():
file = request.files['file']
fn = file.filename
if file and allowed_file(fn):
try:
# code for saving file
return Response(status=200)
except:
return Response(status=500)
return Response(status=500)
api.add_resource(Upload, '/api/upload')
In flask I can access the file through request.files['file'], but the username information/variable is nowhere to be found.
Is this not possible in flask, am I missing something, or what's going on here?

I actually think #ciacicode was right to ask you about your python code.
You are probably running into a CORS violation with Angular calling Python.
Add an import
See Flask-CORS: http://flask-cors.corydolphin.com/en/latest/index.html
from flask.ext.cors import CORS
Add CORS to your app
Simple addition to your code:
app = Flask(__name__)
cors = CORS(app)
api = Api(app)
Adding CORS made your code sample run for me.

If the CORS is not doing anything for you, then use request.values['username']

Related

Issue with simple python API in flask. Trying to create a post method to add json data to a list

I am trying to build a simple flask api to post json data to a list (eventually with be redshift but this is just a simple test program).
I have attached the api code first followed by the code to send data.
I am getting internal server error issues when running the second script.
The code seems very simple though and I cannot figure out what is wrong.
from flask_restful import Api, Resource
from flask import request
app = Flask(__name__)
api = Api(app)
audit_log = []
class audit(Resource):
#def get (self):
#return {"data":"HelloWorld"}
def put (self):
new_item = request.get_json()
audit_log.append(new_item)
return new_item
api.add_resource(audit,"/")
app.run()
import requests
BASE = "HTTP://127.0.0.1:5000/"
response = requests.put(BASE, params = {'auditid' : 'xyz', 'jobname' : 'abc'})
print (response.json())
It seems that you haven't imported the Flask properly
instead of this
from flask import request
use this
from flask import Flask, request
This should work fine...

How to configure basepath in flask restful api application?

I want to set a basepath for my flask application. I have mentioned one example below.
basepath = 'http://localhost:3000/api'
i have two api call one is GET and other one is POST .
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.add_resource(CreateUser, "/v1/user/create/")
api.add_resource(CreateUser, "/v1/user/details")
class CreateUser(Resource):
def post(self):
# Code for creating a user
def get(self):
# Code for get the details of user.
So here, if i want to create the user then my url will be http://localhost:3000/api/v1/user/create/
so same for GET also . So how do i achieve this ?
Initialize your Api with the path prefix:
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app, "/api")
...
You can't change the host and port this way, you'll have to run flask with parameters:
flask run --host=127.0.0.1 --port=3000
Or you could do
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app, "/api")
...
if __name__ == "__main__":
app.run(host="127.0.0.1", port="3000")
Please keep in mind this is not intended for production environments, only for local testing. Please see https://flask.palletsprojects.com/en/1.1.x/tutorial/deploy/ for using in a production environment.
If you want to get those values from basepath, one option would be purl:
url = purl.URL('http://localhost:3000/api')
url.host() # --> "localhost"
url.port() # --> 3000
url.path() # --> "/api"

How to configure flask uploads properly to upload files

I'm trying to build a flask app where I can upload a JSON file. I followed the official flask tutorials; this is my code:
import os
from flask import Flask, flash, request, render_template, url_for
from flask_restful import Resource, Api
from flask_uploads import UploadSet, configure_uploads, DATA
app = Flask(__name__)
app.config['UPLOADED_FILES_DEST'] = os.getcwd()
file = UploadSet('SecretKey', DATA)
configure_uploads(app, file)
#app.route('/')
def my_form():
return render_template('upload.html')
#app.route('/checkUpload', methods=['POST'])
def my_form_post():
if request.method == 'POST' and 'file' in request.files:
keyFile = file.save( request.files['keyfile'] )
# ...
My directory structure looks like this:
folder - >
app.py
templates - > uploads.html
When I run the application , I get this error:
RuntimeError: no destination for set SecretKey
I understand that I need to set a destination to the file that's being uploaded,
but I can't figure out how to properly do that; I can't understand why the way I'm currently setting the destination directory is wrong. Ideally, I don't want to store this file anywhere, I just want to take this file, check some credentials from it and then start a session if the credentials are valid. Any help is much appreciated. Thank you for your time in advance.
P.S: Please ignore the spacing of the code , and I've also looked into some other SO questions related to these:
1) Flask Upload Issue
2) Flask Upload Issue
but they didn't exactly had the same issue as I did, so I'm creating a new thread.
You didn't set destination to UploadSet. flask_uploads doesn't know where to store a files. Just set destination:
file = UploadSet('SecretKey', DATA, default_dest=lambda x: 'SecretKey')
Hope this helps.

Flask_dance with Google API; Missing required parameter: refresh_token

I trid to make authorization system with flask_dance and Google.
I was successful in authorize first but after a while, the program caused this error even though I didn't change it at all.
My whole code is here (It's almost the same as the tutorial one though
from flask import Flask, redirect, url_for
from flask_dance.contrib.google import make_google_blueprint, google
app = Flask(__name__)
app.secret_key = "supersekrit"
blueprint = make_google_blueprint(
client_id="",
client_secret="",
scope=["profile", "email"]
)
app.register_blueprint(blueprint, url_prefix="/login")
#app.route("/")
def index():
if not google.authorized:
return redirect(url_for("google.login"))
resp = google.get("/oauth2/v2/userinfo")
assert resp.ok, resp.text
return "You are {email} on Google".format(email=resp.json()["email"])
if __name__ == "__main__":
app.run()
How can I fix this error?
This problem seems to be the one referenced in this Github issue. The suggested solution is to request offline access:
google_blueprint = make_google_blueprint(
client_id='',
client_secret='',
scope=['profile', 'email'],
offline=True
)

Python flask Dockerized Web application api not return response ERROR:BrokenFilesystemWarning

I am using python 2.7 and flask that returns a complete response to my local setup. Now the application is dockerized the and deployed in Google kubernetes container. This is a sample API of POST method which takes inputs as application/json, currently the internal function able to fetch the data in JSON format but its not return to the client end.
Python part:
from flask import Flask, render_template, request, jsonify
from flask_cors import CORS, cross_origin
import sys
from runmodel import run
reload(sys) # Reload is a hack
sys.setdefaultencoding('UTF8')
app = Flask(__name__, static_url_path='/static')
CORS(app)
#app.route("/modelrun", methods=['POST'])
def modelrun():
"""TO run the model and get data to populate"""
req_data = request.json
res = run(req_data) #another function return the data it will return json format
return jsonify(res)
My current problem is I am not getting the complete response, its return the ValueError: View function did not return a response// Werkzeug Debugger in the web browser.
Here are the logs and Traceback:
labels{
container.googleapis.com/stream: "stderr"
}
BrokenFilesystemWarning)
severity: "ERROR"
textPayload: " BrokenFilesystemWarning)

Categories