Firestore Emulator in Python - python

I'm trying to connect using python 3.8 to the firestore emulator 8.12. I'm having difficulty finding a way to connect. I've downloaded my key from Firestore in the cloud. But I'm trying to connect locally. What does local.json file look like to connect to the emulator locally?
import os
import firebase_admin
from firebase_admin import firestore
from firebase_admin import credentials
cred = credentials.ApplicationDefault()
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "local.json"
firebase_app = firebase_admin.initialize_app(cred)
db=firestore.client()
data = {
u'name': u'Los Angeles',
u'state': u'CA',
u'country': u'USA'
}
# Add a new doc in collection 'cities' with ID 'LA'
db.collection(u'cities').document(u'LA').set(data)

From this issue on the repo, it seems the Python Admin SDK also needs to the FIRESTORE_EMULATOR_HOST environment variable to be set.
os.environ["FIRESTORE_EMULATOR_HOST"] = "127.0.0.1:8080"
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "emulator_config.json"
docs = db.collection(u'insights/venues/queue').stream()

You can use anonymous credentials. From google-auth docs:
These are useful in the case of services that support anonymous access
or local service emulators that do not use credentials.
If you don't provide credentials, then it will use default credentials like you do and describet here
from google.auth import credentials
from google.cloud import firestore
client = firestore.Client(credentials=credentials.AnonymousCredentials())
FIRESTORE_EMULATOR_HOST needs to be set

Related

How to access firebase database without having 'Realtime Database'?

Im trying to connect my python script to a Firebase database.
Here is the code:
import firebase_admin
from firebase_admin import credentials, db
cred = credentials.Certificate("irebase-adminsdk-ofcmd-bwd7fbcz2c.json")
firebase_admin.initialize_app(cred, {'databaseURL':'https://company.firebaseio.com/'})
ref = db.reference('/users').get()
The ERROR Im facing looks like this:
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://company.firebaseio.com/users.json
I did a lot of research and everyone says that I have to find the right URL in the 'Realtime Database' Section. I wonder if there is any way to access the Firebase db without having realtime one enabled.
if you are looking to access the Firebase Database without having the realtime one enabled, you can try the Cloud Firestore which is a different database service provided by Firebase which doesn't require realtime database to be enabled but you may need to change the way you are accessing the data
import firebase_admin
from firebase_admin import credentials, firestore
# Initialize the Firebase Admin SDK with your service account credentials
cred = credentials.Certificate("firebase-adminsdk-that-cred-file.json")
firebase_admin.initialize_app(cred)
# Create a reference to the Firestore database
db = firestore.client()
# Read data from a specific document in the 'users' collection
doc_ref = db.collection('users').document('user1')
doc = doc_ref.get()
# Print the data from the document
print(doc.to_dict())

Cannot connect to firestore firebase in Python

I created a firebaseconfig.json file with my apikey, authodomain, databaseurl, projected, storagebucket, messagingsenderid, appid and measurementid. this comes standard in the SDK setup and configuration section of the yourapps section in project setting. but when I try running my python code.
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
import os
print(os.getcwd())
if not firebase_admin._apps:
cred = credentials.Certificate('src/firebaseconfig.json')
default_app = firebase_admin.initialize_app(cred)
db = firestore.client()
users_ref = db.collection(u'users')
docs = users_ref.stream()
for doc in docs:
print(f'{doc.id} => {doc.to_dict()}')
I get the Error: ValueError: Invalid service account certificate. Certificate must contain a "type" field set to "service_account".
The Firebase Admin SDK requires a service account for authentication, as opposed to a configuration file with the project keys (which is primarily used for web/iOS/Android clients).
If you have not used a service account, you need to generate a key file to use within your application through the Firebase console (Settings -> Service Accounts -> Generate New Private Key).
Afterwards, you can initialize the firestore client within your code as follows (relevant doc):
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
# Use the json key generated from the Firebase console
cred = credentials.Certificate('path/to/serviceAccount.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
Let me know if this information was useful.

How to make cloud firestore rules work on python program?

I written rules for my firestore documents and using admin sdk credentials, that bypasses rules.
How to make rules work on python?
Python code
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
cred = credentials.Certificate('key.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
try:
doc_ref = db.collection('users').document('test')
doc_ref.set({'password':'testPass','shadow':'testShadow'})
print('success')
except:
print('failed')
Firestore rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
}
}
The Firebase Admin SDKs run with administrative privileges and bypass the security rules for Firestore. There is no way to change that.
If you want your code to follow the security rules, you'll have to use one of the client-side SDKs, but none exists for Python at the moment.

Connecting aws backend to firebase database

I'm currently running python code in my aws server and trying to connect to my friend's firebase database. I read the documentation provided by firebase to connect to aws server.
https://firebase.google.com/docs/admin/setup
I have followed every step but I'm getting an error when I try to connect to my server. I have added google-service.json for credential.
Error that I get :
ValueError: Invalid service account certificate. Certificate must
contain a "type" field set to "service_account".
Do I need to modify the google-services.json ?
My code:
import firebase_admin
from firebase_admin import credentials
cred = credentials.Certificate('/home/ec2-user/google-services.json')
#default_app = firebase_admin.initialize_app(cred)
other_app = firebase_admin.initialize_app(cred, name='other')
ault_app = firebase_admin.initialize_app()
google-services.json is typically the name of an Android app configuration file. That's not the same as a service account. To get a hold of the credentials for a service account for your project, you'll need to generate one from the Firebase console from Project Settings -> Service Accounts. The documentation is here. Once you have this file, you can initialize the Admin SDK with it to begin accessing the data in your project.
Better way would be to store credentials on s3 (encrypted) with a IAM role attached to lambda function.
import os
import firebase_admin
from firebase_admin import credentials
import boto3
from settings.local_settings import AWS_REGION, ENVIRONMENT
import json
firebase_config_file = 'app-admin-config-{}.json'.format(ENVIRONMENT)
firebase_admin_creds_file = 'app-admin-sdk-{}.json'.format(ENVIRONMENT)
current_dir = os.path.abspath(os.path.dirname(__file__))
files = [f for f in os.listdir(current_dir) if os.path.isfile(f)]
if firebase_config_file not in files and firebase_admin_creds_file not in files:
s3 = boto3.resource('s3', region_name=AWS_REGION)
bucket = s3.Bucket('app-s3-secrets')
firebase_config = json.loads(
bucket.Object('app-admin-config-{}.json'.format(ENVIRONMENT)).get()['Body'].read())
firebase_admin_creds = json.loads(
bucket.Object('app-admin-sdk-{}.json'.format(ENVIRONMENT)).get()['Body'].read().decode())
class Firebase:
#staticmethod
def get_connection():
cred = credentials.Certificate(firebase_admin_creds)
return firebase_admin.initialize_app(cred, firebase_config)
app = Firebase.get_connection()

Python Azure sdk: How to retrieve secrets from keyvault?

I need to retrieve secrets from keyvault. This is my code so far:
from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.common.credentials import ServicePrincipalCredentials
subscription_id = 'x'
# See above for details on creating different types of AAD credentials
credentials = ServicePrincipalCredentials(
client_id = 'x',
secret = 'x',
tenant = 'x'
)
kv_client = KeyVaultManagementClient(credentials, subscription_id)
for vault in kv_client.vaults.list():
print(vault)
But I am getting this error:
msrestazure.azure_exceptions.CloudError: Azure Error:
AuthorizationFailed Message: The client 'x' with object id 'x' does
not have authorization to perform action
'Microsoft.Resources/subscriptions/resources/read' over scope
'/subscriptions/x'.
Now I am able to access the same keyvault with same credentials using C# code/ POwershell so there is definitely nothing wrong with authorization. Not sure why it isnt working using SDK. Please help.
If you are looking to access via a ServicePrincipalCredentials instance, you can just use:
from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
from azure.common.credentials import ServicePrincipalCredentials
credentials = None
def auth_callback(server, resource, scope):
credentials = ServicePrincipalCredentials(
client_id = '',
secret = '',
tenant = '',
resource = "https://vault.azure.net"
)
token = credentials.token
return token['token_type'], token['access_token']
client = KeyVaultClient(KeyVaultAuthentication(auth_callback))
secret_bundle = client.get_secret("https://vault_url", "secret_id", "")
print(secret_bundle.value)
This assumes that you don't want to pass a version. If you do, you can substitute the last parameter for it.
I run your code sample above and it is able to list the key vaults without any issue, hence it is not a code issue.
I have assigned the Contributor role to my AD application on the subscription where the key vault is provisioned and set the Access Policies to allow GET & LIST permissions for Key and Secret to the AD application.
The versions of my Azure Python packages used running under Python 3.6.2 runtime environment:
azure.common (1.1.8)
azure.mgmt.keyvault (0.40.0)
msrestazure(0.4.13)
I'll recommend you to try on the Python runtime version and Azure Python packages versions which is verified working.
Addendum:
If the above Python runtime environment version as well as Azure Python packages also does not work for you, you should probably consider creating a new issue in the Azure SDK for Python GitHub as it is working with the same credential with Azure .NET SDK as well as PowerShell.
You can also get secret by the name of the secret instead of ID:
secret_bundle = client.get_secret(<VAULT URL>, "<NAME>", "")
There are some good answers already, but the Azure SDK has since released new packages for working with Key Vault in Python that replace azure-keyvault:
azure-keyvault-certificates (Migration guide)
azure-keyvault-keys (Migration guide)
azure-keyvault-secrets (Migration guide)
azure-identity is also the package that should be used with these for authentication.
Documentation for working with the secrets library can be found on the azure-sdk-for-python GitHub repository, and here's a sample for retrieving secrets as you were doing:
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
credential = DefaultAzureCredential()
secret_client = SecretClient(
vault_url="https://my-key-vault.vault.azure.net/",
credential=credential
)
secret = secret_client.get_secret("secret-name")
You can provide the same credentials that you used for ServicePrincipalCredentials by setting environment variables corresponding to the client_id, secret, and tenant:
export AZURE_CLIENT_ID="client_id"
export AZURE_CLIENT_SECRET="secret"
export AZURE_TENANT_ID="tenant"
(I work on the Azure SDK in Python)
One can use the below class from azure.identity i.e ClientSecretCredential, find the below code ex: snippet
from azure.identity import ClientSecretCredential
from azure.keyvault.secrets import SecretClient
TENANT= <TenantId-in-string>
CLIENT_ID = <ClientId-in-string>
CLIENT_SECRET= <ClientSecret-in-string>
credential = ClientSecretCredential(TENANT,CLIENT_ID,CLIENT_SECRET)
VAULT_URL= <AzureVault-url-in-string>
client = SecretClient(vault_url=VAULT_URL, credential=credential)
print(client)
example_secret = client.get_secret(<secret_name_in_string>)
print(example_secret.value)

Categories