Im receiving a type error when I try to stream my firebase real time database. Here is the MRE of my code. Ive been using other features of the module perfectly but for some reason this error keep appearing when I try to stream my data.
from firebase import Firebase
import python_jwt as jwt
from gcloud import storage
from sseclient import SSEClient
from Crypto.PublicKey import RSA
from requests_toolbelt.adapters import appengine
config = {
"apiKey": "*******************************",
"authDomain": "*********************************",
"databaseURL": "*********************************",
"storageBucket": "********************************"
}
pythonfirebase = Firebase(config)
db = pythonfirebase.database()
def stream_handler(message):
print(message["event"]) # put
print(message["path"]) # /-K7yGTTEp7O549EzTYtI
print(message["data"]) # {'title': 'Pyrebase', "body": "etc..."}
my_stream = db.child("placements").stream(stream_handler)
Here is the full traceback
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/Users/temitayoadefemi/PycharmProjects/test7/venv/lib/python3.7/site-packages/firebase/__init__.py", line 593, in start_stream
self.sse = ClosableSSEClient(self.url, session=self.make_session(), build_headers=self.build_headers)
File "/Users/temitayoadefemi/PycharmProjects/test7/venv/lib/python3.7/site-packages/firebase/__init__.py", line 554, in __init__
super(ClosableSSEClient, self).__init__(*args, **kwargs)
File "/Users/temitayoadefemi/PycharmProjects/test7/venv/lib/python3.7/site-packages/sseclient.py", line 48, in __init__
self._connect()
File "/Users/temitayoadefemi/PycharmProjects/test7/venv/lib/python3.7/site-packages/firebase/__init__.py", line 558, in _connect
super(ClosableSSEClient, self)._connect()
File "/Users/temitayoadefemi/PycharmProjects/test7/venv/lib/python3.7/site-packages/sseclient.py", line 56, in _connect
self.resp = requester.get(self.url, stream=True, **self.requests_kwargs)
File "/Users/temitayoadefemi/PycharmProjects/test7/venv/lib/python3.7/site-packages/requests/sessions.py", line 546, in get
return self.request('GET', url, **kwargs)
TypeError: request() got an unexpected keyword argument 'build_headers'
Would appreciate any help
Try it with Firebase admin sdk instead
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
# Fetch the service account key JSON file contents
cred = credentials.Certificate(SERVICE_ACCOUNT_FILE)
# Initialize the app with a service account, granting admin privileges
firebase_admin.initialize_app(cred, {
'databaseURL': DATABASE_URL
})
# Get a database reference to our posts
ref = db.reference('messages')
def listener(event):
print(event.event_type) # can be 'put' or 'patch'
print(event.path) # relative to the reference, it seems
print(event.data) # new data at /reference/event.path. None if deleted
node = str(event.path).split('/')[-2] #you can slice the path according to your requirement
property = str(event.path).split('/')[-1]
value = event.data
if (node=='sala'):
#do something
""""""
elif (node=='ventilacion'):
#do something
""""""
else:
""""""
#do something else
# Read the data at the posts reference (this is a blocking operation)
# print(ref.get())
db.reference('/').listen(listener)
Related
I need to write a python script which checks for incoming e-mail in a shared mailbox hosted on office 365.
I have used python exchangelib 4.7.3:
Code
#!/usr/bin/env python3
import logging
from exchangelib import Credentials, Account, Configuration, DELEGATE
def list_mails():
credentials = Credentials('user#company.com', 'SecretPassword')
config = Configuration(server='outlook.office365.com', credentials=credentials)
account = Account(primary_smtp_address='sharedmailbox#company.com', config=config, autodiscover=False, access_type=DELEGATE)
for item in account.inbox.all().order_by('-datetime_received')[:100]:
print(item.subject, item.sender, item.datetime_received)
def main():
list_mails()
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
main()
Issue
Regardless of the different tries, the following error is showing up:
DEBUG:exchangelib.protocol:No retry: no fail-fast policy
DEBUG:exchangelib.protocol:Server outlook.office365.com: Retiring session 87355
DEBUG:exchangelib.protocol:Server outlook.office365.com: Created session 82489
DEBUG:exchangelib.protocol:Server outlook.office365.com: Releasing session 82489
Traceback (most recent call last):
File "/Users/test/Code/./orderalert.py", line 24, in <module>
main()
File "/Users/test/Code/./orderalert.py", line 20, in main
list_mails()
File "/Userstest/Code/./orderalert.py", line 11, in list_mails
account = Account(primary_smtp_address='sharedmailbox#company.com', config=config, autodiscover=False, access_type=DELEGATE)
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/account.py", line 204, in __init__
self.version = self.protocol.version.copy()
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/protocol.py", line 483, in version
self.config.version = Version.guess(self, api_version_hint=self._api_version_hint)
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/version.py", line 233, in guess
list(ResolveNames(protocol=protocol).call(unresolved_entries=[name]))
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/services/common.py", line 187, in _elems_to_objs
for elem in elems:
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/services/common.py", line 245, in _chunked_get_elements
yield from self._get_elements(payload=payload_func(chunk, **kwargs))
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/services/common.py", line 265, in _get_elements
yield from self._response_generator(payload=payload)
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/services/common.py", line 227, in _response_generator
response = self._get_response_xml(payload=payload)
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/services/common.py", line 343, in _get_response_xml
r = self._get_response(payload=payload, api_version=api_version)
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/services/common.py", line 297, in _get_response
r, session = post_ratelimited(
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/util.py", line 917, in post_ratelimited
protocol.retry_policy.raise_response_errors(r) # Always raises an exception
File "/opt/homebrew/lib/python3.9/site-packages/exchangelib/protocol.py", line 688, in raise_response_errors
raise UnauthorizedError(f"Invalid credentials for {response.url}")
exchangelib.errors.UnauthorizedError: Invalid credentials for https://outlook.office365.com/EWS/Exchange.asmx
DEBUG:exchangelib.protocol:Server outlook.office365.com: Closing sessions
Tried solutions (no luck with them)
The user#company.com credentials are valid, I can log myself in the web interface (no MFA or other enforced)
I have tried the auto discovery:
account = Account('sharedmailbox#company.com', credentials=credentials, autodiscover=True, access_type=DELEGATE)
Disable TLS Validation when connecting
As suggested added a "on" subdomain on on.company.com for the emails addresses.
Tested the overall setup for autodiscovery on testconnectivity.microsoft.com
On the Office 365 Azure AD admin web interface, I can see a successful login performed by the script.
I'd like to ask Azure for the details of the currently signed in user programmatically within a Python program. The program might run from the command line or within Azure batch.
Is there way to do the same thing as the azure cli does with az ad signed-in-user show, but through the Azure SDK for Python?
UPDATE:
Based on Gaurav's help and pointer to the Microsoft Graph Python Client Library, I tried the following:
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
from msgraphcore import GraphSession
credential = DefaultAzureCredential(
exclude_shared_token_cache_credential=True,
)
account_name = "mydatalake"
container_name = "test"
service = BlobServiceClient(
account_url=f"https://{account_name}.blob.core.windows.net/",
credential=credential
)
container_client = service.get_container_client(container_name)
blob_list = container_client.list_blobs()
for i, blob in enumerate(blob_list):
print("\t" + blob.name)
if i >= 9: break
scopes = ['user.read']
graph_session = GraphSession(credential, scopes)
result = graph_session.get('/me')
print(result.json())
I successfully get back blob names from a storage account. But it fails when it gets to the GraphAPI part with this stack trace:
Traceback (most recent call last):
File "py/src/azure_whoami.py", line 58, in <module>
result = graph_session.get('/me')
File "[...snip...]/site-packages/msgraphcore/middleware/options/middleware_control.py", line 24, in wrapper
return func(*args, **kwargs)
File "[...snip...]/site-packages/msgraphcore/graph_session.py", line 41, in get
return super().get(self._graph_url(url))
File "[...snip...]/site-packages/requests/sessions.py", line 555, in get
return self.request('GET', url, **kwargs)
File "[...snip...]/site-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "[...snip...]/site-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "[...snip...]/site-packages/msgraphcore/middleware/middleware.py", line 26,
in send
return self._middleware.send(request, **kwargs)
File "[...snip...]/site-packages/msgraphcore/middleware/authorization.py", line 16, in send
request.headers.update({'Authorization': 'Bearer {}'.format(self._get_access_token())})
File "[...snip...]/site-packages/msgraphcore/middleware/authorization.py", line 33, in _get_access_token
return self.credential.get_token(*self.scopes)[0]
File "[...snip...]/site-packages/azure/identity/_credentials/default.py", line 138, in get_token
token = self._successful_credential.get_token(*scopes, **kwargs)
File "[...snip...]/site-packages/azure/identity/_internal/decorators.py", line 27, in wrapper
token = fn(*args, **kwargs)
File "[...snip...]/site-packages/azure/identity/_credentials/azure_cli.py", line
58, in get_token
raise error
azure.identity._exceptions.CredentialUnavailableError: Please run 'az login' to set up an account
Based on the instructions provided here, you would first need to install the appropriate SDKs (msgraphcore and azure-identity).
After that your code would be something like (again taking from the same link)
# import modules
from azure.identity import UsernamePasswordCredential, DeviceCodeCredential
from msgraphcore import GraphSession
# Configuring credentials
# Added UsernamePassword for demo purposes only, please don't use this in production.
# ugly_credential = UsernamePasswordCredential('set-clientId', 'set-username', 'set-password')
device_credential = DeviceCodeCredential(
'set-clientId')
# There are many other options for getting an access token. See the following for more information.
# https://pypi.org/project/azure-identity/
# get data
scopes = ['user.read']
graph_session = GraphSession(device_credential, scopes)
result = graph_session.get('/me')
print(result.json())
I'm trying to interface Firebase with the official Admin SDK for Python (https://firebase.google.com/docs/database/admin/start).
However, I'm doing something wrong, as I'm not authorized somehow
This is my code:
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
# Fetch the service account key JSON file contents
cred = credentials.Certificate('./ServiceAccountKey.json')
# Initialize the app with a None auth variable, limiting the server's access
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://*[database name]*.firebaseio.com',
'databaseAuthVariableOverride': None
})
# The app only has access to public data as defined in the Security Rules
ref = db.reference('/public_resource')
print(ref.get())
This is the error I get:
python3 firebase_test.py
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/firebase_admin/db.py", line 943, in request
return super(_Client, self).request(method, url, **kwargs)
File "/usr/local/lib/python3.6/site-packages/firebase_admin/_http_client.py", line 117, in request
resp.raise_for_status()
File "/usr/local/lib/python3.6/site-packages/requests/models.py", line 941, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://*[database name]*.firebaseio.com/public_resource.json?auth_variable_override=null
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "firebase_test.py", line 16, in <module>
print(ref.get())
File "/usr/local/lib/python3.6/site-packages/firebase_admin/db.py", line 222, in get
return self._client.body('get', self._add_suffix(), params=params)
File "/usr/local/lib/python3.6/site-packages/firebase_admin/_http_client.py", line 129, in body
resp = self.request(method, url, **kwargs)
File "/usr/local/lib/python3.6/site-packages/firebase_admin/db.py", line 945, in request
raise _Client.handle_rtdb_error(error)
firebase_admin.exceptions.UnauthenticatedError: Unauthorized request.
I'm using a Raspberry Pi 4 B with installed Python 3.6.
Can somebody point me into the right direction of why this happens and how to fix it?
Found it out!
Under database, go to rules and change it to:
{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": true,
".write": true
}
}
It was automatically set to false after I've waited for a too long period since my last access.
I would like to use python kubernetes-client to connect to my AKS cluster api.
To do that I try to use the example give by kubernetes:
config.load_kube_config()
v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:
print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))
It is supposed to load my local kubeconfig and get a pods list but I get the following error:
Traceback (most recent call last): File "test.py", line 4, in
config.load_kube_config() File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 661, in load_kube_config
loader.load_and_set(config) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 469, in load_and_set
self._load_authentication() File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 203, in _load_authentication
if self._load_auth_provider_token(): File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 221, in _load_auth_provider_token
return self._load_azure_token(provider) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 233, in _load_azure_token
self._refresh_azure_token(provider['config']) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/kubernetes/config/kube_config.py",
line 253, in _refresh_azure_token
refresh_token, client_id, '00000002-0000-0000-c000-000000000000') File
"/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/authentication_context.py",
line 236, in acquire_token_with_refresh_token
return self._acquire_token(token_func) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/authentication_context.py",
line 128, in _acquire_token
return token_func(self) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/authentication_context.py",
line 234, in token_func
return token_request.get_token_with_refresh_token(refresh_token, client_secret) File
"/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/token_request.py",
line 343, in get_token_with_refresh_token
return self._get_token_with_refresh_token(refresh_token, None, client_secret) File
"/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/token_request.py",
line 340, in _get_token_with_refresh_token
return self._oauth_get_token(oauth_parameters) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/token_request.py",
line 112, in _oauth_get_token
return client.get_token(oauth_parameters) File "/Users//works/test-kube-api-python/env/lib/python2.7/site-packages/adal/oauth2_client.py",
line 291, in get_token
raise AdalError(return_error_string, error_response) adal.adal_error.AdalError: Get Token request returned http error: 400
and server response:
{"error":"invalid_grant","error_description":"AADSTS65001: The user or
administrator has not consented to use the application with ID
'' named 'Kubernetes AD Client
'. Send an interactive authorization request for this user and
resource.\r\nTrace ID:
\r\nCorrelation ID:
\r\nTimestamp: 2019-10-14
12:32:35Z","error_codes":[65001],"timestamp":"2019-10-14
12:32:35Z","trace_id":"","correlation_id":"","suberror":"consent_required"}
I really don't understand why it doesn't work.
When I use kubectl, all work fine.
I read some docs but I'm not sure to understand the adal error.
Thanks for your help
Login as a tenant admin to https://portal.azure.com
Open the registration for your app in the
Go to Settings then Required Permissions
Press the Grant Permissions button
If you are not a tenant admin, you cannot give admin consent
From https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp-dotnet-webapi/issues/19
This is good post where you can find snippet to authenticate to AKS:
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.containerservice import ContainerServiceClient
from azure.mgmt.containerservice.models import (ManagedClusterAgentPoolProfile,
ManagedCluster)
credential = AzureCliCredential()
subscription_id = "XXXXX"
resource_group= 'MY-RG'
resouce_client=ResourceManagementClient(credential,subscription_id)
container_client=ContainerServiceClient(credential,subscription_id)
resouce_list=resouce_client.resources.list_by_resource_group(resource_group)
Note: You need to install respective Az Python SKD libraries.
Moving on from AuthSub to OAuth, I think I'm slowly beginning to understand the process.
This one threw me an error though:
#!/usr/bin/env python
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from gdata.calendar import service
import gdata
from gdata.alt.appengine import run_on_appengine
from google.appengine.api import users
from google.appengine.ext import db
from gdata.auth import OAuthSignatureMethod, OAuthToken, OAuthInputParams
import urllib
import simplejson
import gdata.gauth
from google.appengine.runtime.apiproxy_errors import CapabilityDisabledError
SCOPES = 'https://www.google.com/calendar/feeds/' # in this case just one, but for future reference, just concatenate different scopes with a space in between
CONSUMER_KEY = 'jmm-timeline.appspot.com'
CONSUMER_SECRET = 'consumer secret key, here'
SIG_METHOD = gdata.auth.OAuthSignatureMethod.RSA_SHA1
f = open('remotekey.pem')
RSA_KEY = f.read()
f.close()
# Incomplete bibliography
# http://www.youtube.com/watch?v=bfgO-LXGpTM
# http://code.google.com/appengine/articles/python/retrieving_gdata_feeds.html
class BasePage(webapp.RequestHandler):
title = "Joshua's Construction Zone"
def write_page_header(self):
self.response.out.write(template.render('templates/header.html', {'title': self.title}))
def write_page_footer(self):
self.response.out.write(template.render('templates/footer.html', {}))
class MainHandler(BasePage):
def get(self):
self.write_page_header()
try:
client = gdata.calendar.service.CalendarService(source='jmm-timeline-v1')
run_on_appengine(client)
client.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.RSA_SHA1, consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, rsa_key=RSA_KEY)
req_token = client.FetchOAuthRequestToken(SCOPES)
oauth_callback_url = 'http://jmm-timeline.appspot.com/handle_authorized_request_token'
oauth_authorization_url = client.GenerateOAuthAuthorizationURL(callback_url=oauth_callback_url)
self.response.out.write(template.render('templates/authorization_prompt.html', { 'authorization_url': oauth_authorization_url }))
except CapabilityDisabledError, e:
self.response.out.write(template.render('templates/content/maintenance.html'))
self.write_page_footer()
class HandleAuthorizedRequestToken(BasePage):
def get(self):
self.write_page_header()
client = gdata.calendar.service.CalendarService('jmm-timeline-2');
run_on_appengine(client)
self.write_page_footer()
def main():
application = webapp.WSGIApplication([('/', MainHandler), ('/handle_authorized_request_token', HandleAuthorizedRequestToken)], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
It appears as if gdata is trying to read my RSA_KEY string, and I get a stacktrace:
Traceback (most recent call last):
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 515, in __call__
handler.get(*groups)
File "C:\Users\Joshua\appengineapps\jmm-timeline\main.py", line 52, in get
req_token = client.FetchOAuthRequestToken(SCOPES)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\service.py", line 415, in FetchOAuthRequestToken
extra_parameters=extra_parameters)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\auth.py", line 217, in GenerateOAuthRequestTokenUrl
oauth_input_params.GetConsumer(), None)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\oauth\__init__.py", line 171, in sign_request
self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token))
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\oauth\__init__.py", line 175, in build_signature
return signature_method.build_signature(self, consumer, token)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\oauth\rsa.py", line 55, in build_signature
privatekey = keyfactory.parsePrivateKey(cert)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\keyfactory.py", line 203, in parsePrivateKey
return parseXMLKey(s, private=True)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\keyfactory.py", line 79, in parseXMLKey
key = Python_RSAKey.parseXML(s)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\Python_RSAKey.py", line 137, in parseXML
element = xmltools.parseAndStripWhitespace(s)
File "C:\Users\Joshua\appengineapps\jmm-timeline\gdata\tlslite\utils\xmltools.py", line 30, in parseAndStripWhitespace
raise SyntaxError(str(e))
SyntaxError: syntax error: line 1, column 0
tlslite has two keyformats: PEM and XML. It first tries PEM (see parsePrivateKey), and then falls back to XML. Apparently, there is an error in your PEM file, so PEM parsing fails (but should have succeeded). Parsing XML then clearly must fail.
My guess is that you messed up line endings somehow, but perhaps there is something even more fundamentally wrong with the PEM file.