Flask Python Firebase storage - python

I'm trying to upload an image to Firebase.
storage = firebase.storage()
storage.child("images/example.jpg").put("cat.jpg")
I can't seem to allow user to browse an image file from their PC and upload it to Firebase.
How should I go about doing this? Please kindly guide me in the right direction ,thank you!

Use <input type="file".. to trigger the select window and may be listen the onChange="handleUpload()" event to handle your firebase upload.
function handleUpload(event) {
// Use this event to get the input element
const files = event.target.files;
if (!files.length) {
return alert('Please choose a file to upload first.');
}
// Always multiple files get the first file if no `multiple` in input
var file = files[0];
var fileName = file.name;
}

Related

How do I get url with token of uploaded file to firebase storage?

I am trying to get the URL of a file I'm uploading to Firebase Storage. I want the URL that includes the token at the end, the one that looks like this:
https://firebasestorage.googleapis.com/v0/b/myapp.appspot.com/o/folder%myfile?alt=media&token=mytoken
So far this is my code:
from firebase_admin import credentials, initialize_app
cred = credentials.Certificate("serviceAccountKey.json")
initialize_app(cred, {'storageBucket': 'myapp.appspot.com'})
bucket = storage.bucket()
path = "path/to/myfile"
blob = self.bucket.blob(path)
blob.upload_from_filename("temp.mp3")
# I only know how to get this URL but it's not the one that I want
blob.make_public()
url = blob.public_url
I also don't want the signed URL that expires.
I've seen people mention the function getDownloadURL but I don't know how I can use it with firebase-admin in Python.
I've checked https://googleapis.dev/python/storage/latest/blobs.html but all I could find about URLs was either signedURL or publicURL
Change the security rule to that specific folder
Make sure you upload publically visible images to that specific folder
It doesn't require any access token to access such images
Capturing media token can only be done by the Client SDK and not available in the Admin SDK for firebase-admin python
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Explicitly define rules for the 'path/to/myfile/' pattern
match /path/to/myfile/{allPaths}{
allow write: if request.auth != null; // Only Auth person can read
allow read: if request.auth == null; // Anyone can read
}
// This will be defined for everything else
match /{allPaths=**} {
allow write: if request.auth != null; // Only auth person can write
allow read: if request.auth != null; // Only auth person can read
}
}
}
Sample python code
storageBucket='myapp.appspot.com'
bucket_path="path/to/myfile/temp.mp3"
firebase_storageURL = 'https://firebasestorage.googleapis.com/v0/b/{}/o/{}?alt=media'.format(storageBucket, bucket_path)

Uploading an excel file to FastAPI from a React app

Ok, I was really hoping that one of the various other questions on this topic would help me but I simply can't make this work! I'm relatively new to React and using API requests. I'm looking to upload an excel file from my React app and then process it in python using FastAPI as the interface.
I've followed the various tutorials / documentation approaches and I just get a 422 Unprocessable Entity Error!
In React, my event handlers look like this:
When file is selected, set the file in state:
onFileChange = (event) => {
this.setState({
uploadFile: event.target.files[0],
isFileSelected: true
});
};
When the "Upload" button is pressed, append to a FormData object and send via an axios request (Database is the axios object):
onUploadClick = async (event) => {
event.preventDefault()
var formData = new FormData();
formData.append(
"UploadFile",
this.state.uploadFile,
this.state.uploadFile.name
);
this.setState({isFileUploaded: true})
console.log(this.state.uploadFile)
const headers={'Content-Type': this.state.uploadFile.type}
await Database.post("/FileUpload",formData,headers);
};
And my FastAPI handler looks like this:
#app.post("/FileUpload")
async def FileUpload(file: UploadFile = File(...)):
# do some things...
Can someone please put me out my misery?
Your problem is due to the same reason as
How to send file to fastapi endpoint using postman
The name of the file variable in your fastapi endpoint has to match the name of the key to the file of your formdata. That is, your javascript should be like
formData.append(
"file",
this.state.uploadFile,
this.state.uploadFile.name
);
in order for your endpoint to be able to access the file parameter. Otherwise change the parameter's name (UploadFile in your case).

angularjs+python(Flask) file upload to server

I am developing a web app using angular, python and Flask.
In my app there is a form where the user need to enter some data and to upload his photo.
I want to implement the file upload to the server using angular.
I saw that I need to use the FormData() and to bind the data from the HTML to angular using "watch".
The javascript part is clear.
I don't understand how can I get the data from the Python side.
This is my HTML -
<form enctype="multipart/form-data" ng-submit="submitGuideDetailsForm()">
<div class="form-group">
<label for="usr">Add your photo:</label>
<input type='file' class="form-control" name='file' onchange="angular.element(this).scope().uploadFile(this.files)">
</div>
</form>
This is my angular -
$scope.uploadFile = function(files) {
$scope.file = new FormData();
$scope.file.append("file", files[0]);
};
$scope.submitGuideDetailsForm= function() {
$http.post('/uploadFile', $scope.file, {
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(function(results)
{
$log.log('success load file')
}).error(function(error)
{
$log.log('error load file!!!!!')
$log.log(error);
});
};
I want to get the file on the server side, using python and flask -
#app.route('/uploadFile', methods=['POST'])
def uploadFile():
json_data = request.json
print(json_data)
status = 'success'
return jsonify({'result': status})
I don't know how to get the data from the 'request' object.
request.json does not work.
Please advice me what am I doing wrong.
How can I get the data from the 'request' object?
Do I need to encode the data to a file?
How do I send the data back to client? Do I need to encode it back?
I did not find a full example using angular and python/flask uploading a file to server, saving it and than downloading it to the client.
Thanks a lot,
Dina
the file can be get byfile = request.files['file']
after that,
you can get the filename by file.filename.encode("utf8")
The command 'request.files' work
The gets me the following object -
ImmutableMultiDict([('file', <FileStorage:
u'12132638_10153196350425732_1151540092606190338_o.jpg'
('image/jpeg')>)])
I don't understand how can I save it on the server.
How do I get only the file name out of this object
And how do I send it back to the client side?
Thanks a lot, Dina
Use request.files and .filename atrribute
file = request.files['file']
fileName = file.filename
#to store it on server use getvalue() and write it to the file object
filedata = file.getvalue()
with open('abc.png') as f:
f.write(filedata)

Upload an image from iphone to GAE blobstore

I spent all this morning looking for a clear example on how to upload a picture taken with an iPhone to the blobstore, but without succeed.
Currently I have my iPhone app developed, which can send pics to the server in PHP, with this code in the server:
// Function to upload a photo in a file and save data in the DB
function upload($photoData, $descr, $phone) {
// Folder to upload data
$path = $_SERVER['DOCUMENT_ROOT']."/program/data/";
// Check if there was no error during the file upload
if ($photoData['error'] == 0) {
$result = query("INSERT INTO pics(descr, phone) VALUES('%s','%s')", $descr, $phone);
if (!$result['error']) {
// Inserted in the database, go on with file storage
// Obtain database link (in lib.php)
global $link;
// Get the last automatically generated ID
$idPhoto = mysqli_insert_id($link);
// Move the temporarily stored file to a convenient location
if (move_uploaded_file($photoData['tmp_name'], $path.$idPhoto.".jpg")) {
// File moved, all good, generate thumbnail
thumb($path.$idPhoto.".jpg", 180);
print json_encode(array('successful' => 1));
} else {
errorJson('Upload on server problem');
}
} else {
errorJson('Save database problem: '.$result['error']);
}
} else {
errorJson('Upload malfunction.');
}
}
The part in Objective-C that makes this works is (I'm using AFNetworking and the object API sharedInstance is an AFJSONRequestOperation class):
// Upload the image and the description to the web service
[[API sharedInstance] commandWithParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"upload", #"command",
UIImageJPEGRepresentation(originalPhoto, 70), #"file",
description, #"descr",
phoneNumber, #"phone",
nil]
onCompletion:^(NSDictionary *json) {
// Finished and response from server
if (![json objectForKey:#"error"]) {
// Success
[[[UIAlertView alloc]initWithTitle:#"Info"
message:#"Thanks"
delegate:nil
cancelButtonTitle:#"Dismiss"
otherButtonTitles: nil] show];
// Send a notification so the main view can reload the data
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateStream" object:nil];
} else {
// Error
NSString* errorMsg = [json objectForKey:#"error"];
[UIAlertView error:errorMsg];
}
}];
This works fine and the images are saved on the server. But I want to make the same with datastore, which you can't save files. So I made a webpage to practice on save images, and I can upload images without any problem in the blobstore from an standard web form. This is the code I'm using to save it in GAE (forget about my own helper classes or functions like PicturePageHandler or render_page):
# Get and post for the create page
class Create(PicturePageHandler, blobstore_handlers.BlobstoreUploadHandler):
def get(self):
if self.user_logged_in():
# The session for upload a file must be new every reload page
uploadUrl = blobstore.create_upload_url('/addPic')
self.render_page("addPicture.htm", form_action=uploadUrl)
def post(self):
if self.user_logged_in():
# Create a dictionary with the values, we will need in case of error
templateValues = self.template_from_request()
# Test if all data form is valid
testErrors = check_fields(self)
if testErrors[0]:
# No errors, save the object
try:
# Get the file and upload it
uploadFiles = self.get_uploads('picture')
# Get the key returned from blobstore, for the first element
blobInfo = uploadFiles[0]
# Add the key and the permanent url to the template
templateValues['blobKey'] = blobInfo.key()
templateValues['servingUrl'] = images.get_serving_url(blobInfo.key(), size=None)
# Save all
pic = Picture.save(self.user.key, **templateValues)
if pic is None:
logging.error('Picture save error.')
self.redirect("/myPics")
except:
self.render_page("customMessage.htm", custom_msg=_("Problems while uploading the picture."))
else:
# Errors, render the page again, with the values, and showing the errors
templateValues = custom.prepare_errors(templateValues, testErrors[1])
# The session for upload a file must be new every reload page
templateValues['form_action'] = blobstore.create_upload_url('/addPic')
self.render_page("addPicture.htm", **templateValues)
My questions are:
Can I still using my Objective-C JSON call to upload a picture to the server or must I completely change the way to upload the picture?
How can I change the Python server code to get the picture from the JSON, if it is possible?
It's not exactly what you're after, but this might help:
http://brunofuster.wordpress.com/2011/03/11/uploading-an-image-from-iphone-to-appengine-blobstore-using-vraptor/

Send an image file using sockets , Android to Python

Im trying to send an image from an android client to a python server , I have achieved it before with a python test client and the server. Basically my client app takes a form consisting of users details and an image. Once the user selects the image I get the uri in the onActivityResult method and parse it to a string Like so
selectedImagePath = selectedImageUri.toString();
when the user hits submit button on the form the sending activity is invoked with the form data as extras in an array in a bundle like so.
Bundle b=new Bundle();
b.putStringArray("regValues", new String[]{name,email,selectedImagePath});
in the sending activity I establish a connection with the server and attempt to send the image like so .
`
//establish link with the server
try{
//refer to the host computer's loopback interface
host = InetAddress.getByName("10.0.2.2");
link = new Socket(host,port);
in = new BufferedReader(new InputStreamReader(link.getInputStream()));
//access the strings that were passed to this activity
Bundle b = this.getIntent().getExtras();
String[] regFormValues = b.getStringArray("regValues");
//display connection confirmation
String message = in.readLine();
status.setText(message);
File myFile = new File (regFormValues[2]);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = link.getOutputStream();
os.write(mybytearray,0,mybytearray.length);
os.flush();
link.close();
}
catch(IOException e ){
e.printStackTrace();
}
`
It connects to the server no problem , the
server creates a file for output to write the data to as usual but it just appears empty so no data is being recieved. I think it may be a problem with the file path on the client side. Any Ideas ?
EDIT: Basically I would like to know if I am accessing the image file in the right way or if you have any better suggestions for accessing and sending it.
Consider using methods such as File.exists() and File.isFile() to validate if the path is OK and whether the image is really there
Also check if the image even hits the wire - using tcpdump ro wireshark
I have solved it , as I use selectedImageUri = Uri.fromFile(photo); to get the uri if its taken by the camera and selectedImageUri = data.getData(); if its been selected by the file browser. I used selectedImagePath = selectedImagePath.substring(7); to strip the file:// form the camera's image path, resulting in a /sdcard/etc or wherever it stored it. To get the file path for the image chosen by the file browser i used this
// convert the image URI to the direct file system path of the image file
public String getRealPathFromURI(Uri contentUri) {
// can post image
String [] proj={MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery( contentUri,
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
Now it works as expected.

Categories

Resources