Skip to content

Commit 062abf0

Browse files
authored
Merge pull request #340 from olucurious/develop
Develop
2 parents c519b15 + 19ea6c6 commit 062abf0

File tree

5 files changed

+30
-11
lines changed

5 files changed

+30
-11
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ from pyfcm import FCMNotification
5858

5959
fcm = FCMNotification(service_account_file="<service-account-json-path>", project_id="<project-id>")
6060

61+
# Google oauth2 credentials(such as ADC, impersonate credentials) can be used instead of service account file.
62+
63+
fcm = FCMNotification(
64+
service_account_file=None, credentials=your_credentials, project_id="<project-id>"
65+
)
66+
6167
# OR initialize with proxies
6268

6369
proxy_dict = {

pyfcm/__meta__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
__summary__ = "Python client for FCM - Firebase Cloud Messaging (Android, iOS and Web)"
33
__url__ = "https://github.com/olucurious/pyfcm"
44

5-
__version__ = "2.0.3"
5+
__version__ = "2.0.4"
66

77
__author__ = "Emmanuel Adegbite"
88
__email__ = "[email protected]"

pyfcm/baseapi.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import json
24
import os
35
import time
@@ -26,8 +28,9 @@ class BaseAPI(object):
2628

2729
def __init__(
2830
self,
29-
service_account_file: str,
31+
service_account_file: str | None,
3032
project_id: str,
33+
credentials=None,
3134
proxy_dict=None,
3235
env=None,
3336
json_encoder=None,
@@ -38,6 +41,7 @@ def __init__(
3841
Attributes:
3942
service_account_file (str): path to service account JSON file
4043
project_id (str): project ID of Google account
44+
credentials (Credentials): Google oauth2 credentials instance, such as ADC
4145
proxy_dict (dict): proxy settings dictionary, use proxy (keys: `http`, `https`)
4246
env (dict): environment settings dictionary, for example "app_engine"
4347
json_encoder (BaseJSONEncoder): JSON encoder
@@ -49,10 +53,11 @@ def __init__(
4953
self.FCM_REQ_PROXIES = None
5054
self.custom_adapter = adapter
5155
self.thread_local = threading.local()
56+
self.credentials = credentials
5257

53-
if not service_account_file:
58+
if not service_account_file and not credentials:
5459
raise AuthenticationError(
55-
"Please provide a service account file path in the constructor"
60+
"Please provide a service account file path or credentials in the constructor"
5661
)
5762

5863
if (
@@ -85,7 +90,12 @@ def requests_session(self):
8590
self.thread_local.requests_session = requests.Session()
8691
self.thread_local.requests_session.mount("http://", adapter)
8792
self.thread_local.requests_session.mount("https://", adapter)
93+
self.thread_local.token_expiry = 0
94+
95+
current_timestamp = time.time()
96+
if self.thread_local.token_expiry < current_timestamp:
8897
self.thread_local.requests_session.headers.update(self.request_headers())
98+
self.thread_local.token_expiry = current_timestamp + 1800
8999
return self.thread_local.requests_session
90100

91101
def send_request(self, payload=None, timeout=None):
@@ -120,17 +130,20 @@ def send_async_request(self, params_list, timeout):
120130

121131
def _get_access_token(self):
122132
"""
123-
Generates access from refresh token that contains in the service_account_file.
133+
Generates access token from credentials.
124134
If token expires then new access token is generated.
125135
Returns:
126136
str: Access token
127137
"""
128138
# get OAuth 2.0 access token
129139
try:
130-
credentials = service_account.Credentials.from_service_account_file(
131-
self.service_account_file,
132-
scopes=["https://www.googleapis.com/auth/firebase.messaging"],
133-
)
140+
if self.service_account_file:
141+
credentials = service_account.Credentials.from_service_account_file(
142+
self.service_account_file,
143+
scopes=["https://www.googleapis.com/auth/firebase.messaging"],
144+
)
145+
else:
146+
credentials = self.credentials
134147
request = google.auth.transport.requests.Request()
135148
credentials.refresh(request)
136149
return credentials.token

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
aiohttp>=3.6.2
22
cachetools==5.3.3
3-
google-auth==2.29.0
3+
google-auth==2.22.0
44
pyasn1==0.6.0
55
pyasn1-modules==0.4.0
66
rsa==4.9

tests/test_fcm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
def test_push_service_without_credentials():
66
try:
7-
FCMNotification(service_account_file="", project_id="")
7+
FCMNotification(service_account_file="", project_id="", credentials=None)
88
assert False, "Should raise AuthenticationError without credentials"
99
except errors.AuthenticationError:
1010
pass

0 commit comments

Comments
 (0)