Python - Push Notification through FCM / APNs to IOS or Android Devices - python

I am working on my python project, i need to create my own push notification server for apns and fcm / gcm, which sends push notification to both ios and android at same time, I have looked through the Firebase documentation however, the there was no code examples on the site. Can any one give me an idea of how to complete this in Python code?

I struggled with this for a little while so I thought I will post the code that worked for me eventually. All you need to do is to do a pip install of oauth2client from Google (https://github.com/google/oauth2client):
pip install oauth2client
Now, you will need to import the service account which will generate for you a short lived token that you can use in your API so that your app server can communicate with the FCM Google server.
Do as instructed by the following website:
https://firebase.google.com/docs/cloud-messaging/auth-server
from oauth2client.service_account import ServiceAccountCredentials
def _get_access_token():
"""Retrieve a valid access token that can be used to authorize requests.
:return: Access token.
"""
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'service-account.json', FCM_SCOPE)
access_token_info = credentials.get_access_token()
return access_token_info.access_token
Now, once you have the short_lived token, you can use it in your API calls to send messages to your android / IOS devices:
import requests, json
values = {"message":{"token":"<insert android firebase token id here>","notification":{"body":"This is a Firebase Cloud Messaging Topic Message for testing!","title":"FCM Message!!"}}}
header ={ 'Content-Length': '33333', 'Content-Type': 'application/json; UTF-8', 'Authorization': 'Bearer ' + _get_access_token(), 'User-Agent': 'Mozilla/5.0'}
url = 'https://fcm.googleapis.com/v1/projects/<insert project name here>/messages:send'
print(header)
r = requests.post(url, data=json.dumps(values), headers=header)
print(r.text)
If the call is successful, you will receive a print on the screen of the reference of your FCM message that you have just sent:
{
"name": "projects/<your project name>/messages/0:1519633952417262%0958967209589672"
}

Related

How to create a work item in python using either TFSAPI or requests, ..etc

AM currently writing a rest api python script to interact with azure devops and I wanted to create a work item but am getting 401 or 404 errors. I followed the url query to do a post but I seem not to find the solution.
You can refer this official Azure DevOps Python API doc.
It contains Python APIs for interacting with and managing Azure
DevOps. These APIs power the Azure DevOps Extension for Azure CLI. To
learn more about the Azure DevOps Extension for Azure CLI, visit the
Microsoft/azure-devops-cli-extension repo.
Here is some example code for creating work item in python.
Besides, it is supported to use requests to call Azure DevOps REST API. In this way, you need to create a personal access token (PAT) first. (Make sure you select the correct scope, in your scenario at least have the create work item permission).
Then you can use the PAT to create the basic auth header, and make the request:
import requests
import base64
pat = 'tcd******************************tnq'
authorization = str(base64.b64encode(bytes(':'+pat, 'ascii')), 'ascii')
headers = {
'Accept': 'application/json-patch+json',
'Authorization': 'Basic '+authorization
}
url = "https://dev.azure.com/fabrikam/{project}/_apis/wit/workitems/${type}?api-version=6.0"
payload = "[\n {\n \"op\": \"add\",\n \"path\": \"\/fields\/System.Title\",\n \"from\": null,\n \"value\": \"Sample task\"\n }\n]"
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

Scrape Alertmanager API

I have an Openshift 3.11 cluster with the default installation of Prometheus and Alertmanager.
I want to write a python script to scrape the Alertmanager API endpoint so that I can parse the data and pass that on to s third party monitoring tool for our ops team.
My problem is that to get to the API I need to authenticate against oauth. How can I do this within python?
I don't know if this is any different for alert manager compared with the Reddit API, but when I set up a bot for that, I had to first register it on their OAuth page, then I needed to use the codes that it gave me there, to request an access token with the rest of my user data (Login and password as well as what the application was called) Then I could use that authentication to contact the API endpoint.
Here is the function I made to request the access token from Reddit:
def AuthRequest():
import requests
import requests.auth
import json
client_auth = requests.auth.HTTPBasicAuth('Application ID code', 'OAuth secret code')
post_data = {"grant_type": "password", "username": "Your_Username", "password": "Your_Password"}
headers = {"User-Agent": "Name_Of_Application"}
response = requests.post("https://www.reddit.com/api/v1/access_token", auth=client_auth, data=post_data, headers=headers)
return response.json()
And here is the code that contacts the endpoint and takes the data from it:
import requests
import requests.auth
import json
currentComments = []
headers = {"Authorization": auth['token_type'] + " " + auth['access_token'], "User-Agent": "Your_Application_Name"}
mentions = requests.get("https://oauth.reddit.com/message/unread.json", headers=headers).json()
Note here that 'auth' is simply the 'response' from the authentication token. I hope that helps, I don't really know how this differs with alertmanager as I've never really had to use it.
I found the fix for me.
I needed to create a service account
oc create serviceaccount <serviceaccount name> -n <your-namespace>
Then create a cluster role binding for it
oc create clusterrolebinding <name for your role> \
--clusterrole=cluster-monitoring-view \
--serviceaccount=<your-namespace>:<serviceaccount name>
Get a token from the SA and then use that in the curl
oc sa get-token <serviceaccount name> -n <your-namespace>

Firebase DB HTTP API Auth: When and how to refresh JWT token?

I'm trying to make a Python webapp write to Firebase DB using HTTP API (I'm using the new version of Firebase presented at Google I/O 2016).
My understanding so far is that the specific type of write I'd like to accomplish is made with a POST request to a URL of this type:
https://my-project-id.firebaseio.com/{path-to-resource}.json
What I'm missing is the auth part: if I got it correctly a JWT should be passed in the HTTP Authorization header as Authorization : Bearer {token}.
So I created a service account, downloaded its private key and used it to generate the JWT, added it to the request headers and the request successfully wrote to Firebase DB.
Now the JWT has expired and any similar request to the firebase DB are failing.
Of course I should generate a new token but the question is: I wasn't expecting to handle token generation and refresh myself, most HTTP APIs I'm used to require just a static api key to be passed in the request so my webapps could be kept relatively simple by just adding the stati api key string to the request.
If I have to take care of token generation and expiration the webapp logic needs to become more complex (because I'd have to store the token, check if it is still valid and generate a new one when not), or I could just generate a new token for every request (but does this really make sense?).
I'd like to know if there's a best practice to follow in this respect or if I'm missing something from the documentation regarding this topic.
Thanks,
Marco
ADDENDUM
This is the code I'm currently running:
import requests
import json
from oauth2client.service_account import ServiceAccountCredentials
_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
def _get_credentials():
credentials = ServiceAccountCredentials.from_json_keyfile_name('my_service_account_key.json', scopes=_SCOPES)
return credentials.get_access_token().access_token
def post_object():
url = _BASE_URL + '/path/to/write/to.json'
headers = {
'Authorization': 'Bearer '+ _get_credentials(),
'Content-Type': 'application/json'
}
payload = {
'title': title,
'message': alert
}
return requests.post(url,
data=json.dumps(payload),
headers=headers)
Currently for every request a new JWT is generated. It doesn't seem optimal to me. Is it possible to generate a token that doesn't expire?
Thanks for the code example. I got it working better by using the credentials.authorize function which creates an authenticated wrapper for http.
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
import json
_BASE_URL = 'https://my-app-id.firebaseio.com'
_SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/firebase.database'
]
# Get the credentials to make an authorized call to firebase
credentials = ServiceAccountCredentials.from_json_keyfile_name(
_KEY_FILE_PATH, scopes=_SCOPES)
# Wrap the http in the credentials. All subsequent calls are authenticated
http_auth = credentials.authorize(Http())
def post_object(path, objectToSave):
url = _BASE_URL + path
resp, content = http_auth.request(
uri=url,
method='POST',
headers={'Content-Type': 'application/json'},
body=json.dumps(objectToSave),
)
return content
objectToPost = {
'title': "title",
'message': "alert"
}
print post_object('/path/to/write/to.json', objectToPost)

Python Requests - Azure RM API returning 200 status code but 400 in content

I have some code where I am trying to authenticate against Azure's Resource Manager REST API.
import json
import requests
tenant_id = "TENANT_ID"
app_id = "CLIENT_ID"
password = "APP_SECRET"
token_endpoint = 'http://login.microsoftonline.com/%s/oauth2/token' % tenant_id
management_uri = 'https://management.core.windows.net/'
payload = { 'grant_type': 'client_credentials',
'client_id': app_id,
'client_secret': password
}
auth_response = requests.post(url=token_endpoint, data=payload)
print auth_response.status_code
print auth_response.reason
This returns:
200
OK
However, when I print auth_response.content or auth_reponse.text, I get back a 400 HTML error code and an error message.
HTTP Error Code: 400
Sorry, but we’re having trouble signing you in.
We received a bad request.
I am able to get back the correct information using PostMan, however, with the same URI and payload. I used the "Generate Code" option in Postman to export my request to a Python requests script and tried running that. But, I get the same errors.
Anybody have any idea why this is happening?
Only modify your token_endpoint to https Protocols. E.G:
token_endpoint = 'https://login.microsoftonline.com/%s/oauth2/token' % tenant_id.
You can refer to https://msdn.microsoft.com/en-us/library/azure/dn645543.aspx for more details.
Meanwhile, you can leverage Microsoft Azure Active Directory Authentication Library (ADAL) for Python for acquire the access token in a ease.
You should use HTTPS instead of HTTP for token_endpoint, and you should specify API version too. Here is what you should use.
token_endpoint = 'https://login.microsoftonline.com/%s/oauth2/token?api-version=1.0' % tenant_id

Python Requests - Azure Graph API Authentication

I am trying to access the Azure AD Graph API using the Python requests library. My steps are to first get the authorization code. Then, using the authorization code, I request an access token/refresh token and then finally query the API.
When I go through the browser, I am able to get my authorization code. I copy that over to get the access token. However, I've been unable to do the same with a Python script. I'm stuck at the part where I get the authorization code.
My script returns a response code of 200, but the response headers don't include that field. I would've expected the new URL with the code to be in the response headers. I would have also expected a response code of 301.
Does anyone know why my response headers don't have the auth code? Also, given the auth code, how would I pull it out to then get the access/refresh tokens using Python?
My code is below:
import requests
s = requests.Session()
s.auth = (USERNAME, PASSWORD)
# Authorize URL
authorize_url = 'https://login.microsoftonline.com/%s/oauth2/authorize' % TENANT_ID
# Token endpoint.
token_url = 'https://login.microsoftonline.com/%s/oauth2/token' % TENANT_ID
payload = { 'response_type': 'code',
'client_id': CLIENT_ID,
'redirect_uri': REDIRECT_URI
}
request = s.get(authorize_url, json=payload, allow_redirects=True)
print request.headers
It looks that you are implementing with Authorization Code Grant Flow via python requests. As the flow shows, the response of the request of authorize_url will redirect to a SSO page of your AD tenant. After your user login on, it will redirect to the location which set in redirect_uri with code as the URL parameters. E.G. http://localhost/?code=AAABAAAAiL...
And your code seems cannot simply display a html page with JavaScript allowed, so it will not redirect to the login on page.
So you can refer to # theadriangreen’s suggestion to implement with a python web server application.
Otherwise, you can refer to Microsoft Azure Active Directory Authentication Library (ADAL) for Python, which is a python package for acquiring access token from AD and can be easily integrated in your python application.

Categories

Resources