Download all images from Firebase Storage to UICollectionView Swift - python

I am trying to download all images uploaded in my Firebase Storage to UICollection View in Swift and displaying it to the user. The backend code to upload images to Firebase Storage is in Python. Currently, there is no way Firebase Storage supports multiple downloads unless the metadata(image Url's) are stored in a Real-time database. Most of the solutions implement it using a complete web-based/Android/iOS approach where the image upload and download logic are on the same platform.
The architecture for these solutions is a Cloud Storage linked with Firebase Database that stores the image URLs.
How do I generate the image URLs for the uploaded images in Python and then access them using Swift?
The Python code that uploads the image to Storage is as follows:
# Import gcloud
from firebase import firebase
import firebase_admin
import google.cloud
from google.cloud import storage
from firebase import firebase
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="/home/pi/Desktop/<sample.json>"
firebase = firebase.FirebaseApplication('<firebaseurl>')
client = storage.Client()
bucket = client.get_bucket('<bucketurl>')
imagePath = '/home/pi/Desktop/birdIMG.jpeg'
imageBlob = bucket.blob("/")
imageBlob.upload_from_filename(imagePath)

Related

google storage error: Bucket is requester pays bucket but no user project provided

I want to download files using "file.json" which includes all URLs. Here I tried to use those code in Python, however I am getting this error:
"code":400,"message":"Bucket is requester pays bucket but no user project provided"
I already set up my billing details when I created the GCP account. I really don't know how to solve it. I am not the owner of the bucket. I do have permission to get data from the bucket.
Python code:
import os
from google.cloud.bigquery.client import Client
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'path/to/key.json'
bq_client = Client()
import json
from google.cloud import storage
client = storage.Client(project='my_projectID')
bucket = client.get_bucket('the_bucket')
file_json = bucket.get_blob('file.json')
data = json.loads(file_json.download_as_string())
You need to provide the user_project in the request, which is a gcp project for which you have billing rights. The requests will then be charged to that project.
You can find a python code sample here: https://cloud.google.com/storage/docs/using-requester-pays#using
bucket = storage_client.bucket(bucket_name, user_project=project_id)
See here for which permissions you need in the user_project: https://cloud.google.com/storage/docs/requester-pays#requirements
serviceusage.services.use

How to delete a image file from Google firebase Storage using python

I am currently in the process of creating a Web App (Flask) where users can log in and upload photos to Google Firebase. At one point in the code I was initially saving user uploaded photos to a local folder, but when deployed this doesn't work correctly so I decided to temporarily store it in Google Storage, analyze the faces in it, then delete it. However, I am unable to delete it from Google Storage for some reason.
Firebase Initilizations:
import pyrebase
from pyrebase.pyrebase import storage
import firebase_admin
from firebase_admin import storage, credentials
firebase = pyrebase.initialize_app(json.load(open('firebase/firebaseConfig.json')))
auth = firebase.auth()
db = firebase.database()
storage = firebase.storage()
I have not needed to delete the photos in storage before, but I am able to store Images as well as retrieve their URLs for download as seen below. I am certain the image is stored in my Google Storage and the try fails when I attempt the storage.delete()
try:
storage.child("images/temp/" + filename).put(image, userIdToken)
current_app.logger.info("[UPLOAD-IMAGE] Photo saved, grabbing url")
imageURL = storage.child("images/temp/" + filename).get_url(None)
anazlyzeInfo = recognize.facialRecognition(imageURL)
delete_temp_image_path = "images/temp/" + filename
#storage.delete(imageURL) # same error happens when URL is passed
storage.delete(delete_temp_image_path)
The error described in the exception is: 'Storage' object has no attribute 'bucket'
I looked into this for a while and tried other solutions like StorageRef
and was met with the error 'Storage' has no attribute 'ref'.
I also tried A Service Account following the Google Admin SDK setup but am not sure what to do now that I have:
cred = credentials.Certificate(json.load(open('firebase/fiddl-dev-firebase-adminsdk-stuffdnsnfsnfk.json')))
admin = firebase_admin.initialize_app(cred)
I tried working with this for a while but I could not figure out what was callable with admin.
Was I on the correct path with either of the two fixes I attempted? My use of Firebase was pretty low level before and I would think that deleting would be the same. Thanks!
I’m the OP and I figured out my issue! This GitHub post helped me learn that you need to "add a service account to the config" when getting the 'storage' has not 'bucket' error.
To do this I followed the Firebase Admin Documentation which was pretty straight forward.
However there were 2 main fixes I needed. I fixed this using this Stackoverflow post as a guide.
The first was adding my storageBucket for my app which I was missing above.
admin = firebase_admin.initialize_app(cred, {
'storageBucket': 'fiddl-dev.appspot.com'})
The second issues was when I was trying the bucket = storage.bucket() seen in the same [Stackoverflow] post I was getting the error that storage didn’t have an attribute bucket. This I couldn’t find anything on and was why I made the post.
At the top of my file.py I import:
import pyrebase
from pyrebase.pyrebase import storage
import firebase_admin
from firebase_admin import storage as admin_storage, credentials, firestore
The key being that I added import storage as admin_storage rather than what I had import storage. Essentially I was importing a module named storage twice and it was getting confused.
With that last change I was now able to test the following code that deleted the image from the filepath in Google Firebase Storage specified.
bucket = admin_storage.bucket()
blob = bucket.blob('images/temp/pumpkin.jpg')
print(blob)
blob.delete()

Unable to upload image to firebase storage from python server

I am creating an android app which sends an image to python server and from my python server I want to upload that received image to firebase storage. My problem is that when I try to upload the received image from python server only the filename is stored in the specified collection but my image doesn't upload. My firebase storage looks like this
Firebase storage screenshot
In the attached screenshot the first image starting with Actual is the one that I upload from android and the second starting with processed is the one that I am trying to upload from python but unable to do that. The file type is also different that the one uploaded from android. Below is my code that I am using to upload the image from my server:
Function where I receive image from android:
def handle_request():
print(flask.request.files)
print(flask.request.form)
imagefile = flask.request.files['image']
userID = flask.request.form['user_ID']
upload_to_firebase(imagefile, filename, userID)
Function which stores the image to firebase storage.
def upload_to_firebase(file, filename, userID):
firebase = Firebase(config)
firebase = pyrebase.initialize_app(config)
storage = firebase.storage()
storage.child(userID + "/" + filename + "/Processed_" + filename+"").put(file)
downloadURL = storage.child(userID + "/" + filename + "/Processed_" + filename+"").get_url(None)
Is there any way I can pass the content type image/jpeg while sending the image or any other way I can fix this. I have searched a lot this solution but none have worked so far.
Notice that as explained on the Firebase documentation:
You can use the bucket references returned by the Admin SDK in conjunction with the official Google Cloud Storage client libraries to upload, download, and modify content in the buckets associated with your Firebase projects
Therefore you'll need to modify your upload_to_firebase function to something similar as explained here on the relevant section of the Google Cloud Storage client library for Python:
from google.cloud import storage
def upload_blob(bucket_name, source_file_name, destination_blob_name):
"""Uploads a file to the bucket."""
# bucket_name = "your-bucket-name"
# source_file_name = "local/path/to/file"
# destination_blob_name = "storage-object-name"
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
print(
"File {} uploaded to {}.".format(
source_file_name, destination_blob_name
)
)
where you could obtain the bucket_name variable from the name propertyof the bucket object you define with the Firebase Admin SDK (e.g. if you are using the default bucket of your project):
import firebase_admin
from firebase_admin import credentials
from firebase_admin import storage
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred, {
'storageBucket': '<BUCKET_NAME>.appspot.com'
})
bucket = storage.bucket()
and the source_file_name will correspond to the full path of the uploaded image within the server serving your Flask application.
Notice that you could end up with disk space issues if not properly deleting or managing the files uploaded to the Python server, so be careful on that regards.

How to retrieve image from Firebase Storage using Python?

I have already store my image to Firebase Storage, and I need to take it out by using Python code. Can I retrieve the image by using any URL? Or is there any way to retrieve it out?
Here are the image of how I store it in Firebase Storage:
This is what I use. Hope it helps.
import firebase_admin
from firebase_admin import credentials
from firebase_admin import storage
# Fetch the service account key JSON file contents
cred = credentials.Certificate("credentials.json")
# Initialize the app with a service account, granting admin privileges
app = firebase_admin.initialize_app(cred, {
'storageBucket': '<BUCKET_NAME>.appspot.com',
}, name='storage')
bucket = storage.bucket(app=app)
blob = bucket.blob("<your_blob_path>")
print(blob.generate_signed_url(datetime.timedelta(seconds=300), method='GET'))
It generates a public URL (for 300 secs) for you to download your files.
For example, in my case, I use that URL to display stored pictures in my django website with <img> tag.
Here is the doc for more usefull functions.

Is it possible to download file to Google Cloud Storage via API call (with Python) using Google App Engine (without Google Compute Engine)

I wrote a python program which connected various platforms' API for file downloading purposes here. The program is currently running on my local machine (laptop) without a problem (all downloaded files saved to my local drive of course).
Here is my real question, without Google Compute Engine, is it possible to deploy the very same python program using Google App Engine? If yes, how could I save my files (via API calls) to Google Cloud Storage here?
Thanks.
Is this a Web App? If so you deploy it using GOOGLE APP ENGINE standard or flexible.
In order to send files to Cloud Storage, try the example in the python-docs-samples repo (folder appengine/flexible/storage/):
# [START upload]
#app.route('/upload', methods=['POST'])
def upload():
"""Process the uploaded file and upload it to Google Cloud Storage."""
uploaded_file = request.files.get('file')
if not uploaded_file:
return 'No file uploaded.', 400
# Create a Cloud Storage client.
gcs = storage.Client()
# Get the bucket that the file will be uploaded to.
bucket = gcs.get_bucket(CLOUD_STORAGE_BUCKET)
# Create a new blob and upload the file's content.
blob = bucket.blob(uploaded_file.filename)
blob.upload_from_string(
uploaded_file.read(),
content_type=uploaded_file.content_type
)
# The public URL can be used to directly access the uploaded file via HTTP.
return blob.public_url
# [END upload]

Categories

Resources