Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.

Commit 9eb6974

Browse files
authored
Merge pull request #5 from iMicknl/refresh_acces_tokens
Refresh acces tokens automatically
2 parents 5b3cd0d + f34f8f1 commit 9eb6974

4 files changed

Lines changed: 41 additions & 15 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## 0.3 - 2018-02-04
8+
### Fixed
9+
- Better exception handling & less code duplication
10+
711
## 0.2 - 2018-01-24
812
### Added
913
- Basic test function

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# python-postnl-api
2-
32
(Unofficial) Python wrapper for the PostNL API (Dutch Postal Services), which can be used to track packages and letter deliveries. You can use your [jouw.postnl.nl](http://jouw.postnl.nl) credentials to use the API.
43

54
## Quick test
@@ -25,9 +24,11 @@ letters = postnl.get_letters()
2524
print (letters)
2625
```
2726

27+
## Miscellaneous
28+
[This blogpost](https://imick.nl/reverse-engineering-the-postnl-consumer-api/) describes the process of figuring out the API endpoints and shows how this can be done for other API's.
29+
2830
## Changelog
29-
See the [CHANGELOG](./CHANGELOG.MD) file.
31+
See the [CHANGELOG](./CHANGELOG.md) file.
3032

3133
## License
3234
MIT
33-

postnl_api/postnl_api.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,18 @@ def __init__(self, user, password):
4747
self._access_token = data['access_token']
4848
self._refresh_token = data['refresh_token']
4949
self._token_expires_in = data['expires_in']
50-
self._token_expires_at = datetime.now() + timedelta(0, data['expires_in'])
50+
self._token_expires_at = datetime.now(
51+
) + timedelta(0, data['expires_in'])
5152

52-
def refresh_token(self):
53+
def _is_token_expired(self):
54+
""" Check if access token is expired """
55+
if (datetime.now() > self._token_expires_at):
56+
self._refresh_access_token()
57+
return True
58+
59+
return False
60+
61+
def _refresh_access_token(self):
5362
""" Refresh access_token """
5463

5564
payload = {
@@ -61,13 +70,15 @@ def refresh_token(self):
6170
response = requests.request(
6271
'POST', AUTHENTICATE_URL, data=payload, headers=DEFAULT_HEADER)
6372

64-
data = response.json()
73+
data = response.json() # TODO Add error handling
6574

6675
self._access_token = data['access_token']
6776

6877
def get_shipments(self):
6978
""" Retrieve shipments """
7079

80+
self._is_token_expired()
81+
7182
headers = {
7283
'authorization': 'Bearer ' + self._access_token
7384
}
@@ -76,7 +87,7 @@ def get_shipments(self):
7687
'GET', SHIPMENTS_URL, headers={**headers, **DEFAULT_HEADER})
7788

7889
if response.status_code == 401:
79-
self.refresh_token()
90+
self._refresh_access_token()
8091
shipments = self.get_shipments()
8192
else:
8293
shipments = response.json()
@@ -86,6 +97,8 @@ def get_shipments(self):
8697
def get_shipment(self, shipment_id):
8798
""" Retrieve single shipment by id """
8899

100+
self._is_token_expired()
101+
89102
headers = {
90103
'authorization': 'Bearer ' + self._access_token
91104
}
@@ -94,7 +107,7 @@ def get_shipment(self, shipment_id):
94107
'GET', SHIPMENTS_URL + '/' + shipment_id, headers={**headers, **DEFAULT_HEADER})
95108

96109
if response.status_code == 401:
97-
self.refresh_token()
110+
self._refresh_access_token()
98111
shipments = self.get_shipment(shipment_id)
99112
else:
100113
shipments = response.json()
@@ -104,6 +117,8 @@ def get_shipment(self, shipment_id):
104117
def get_profile(self):
105118
""" Retrieve profile """
106119

120+
self._is_token_expired()
121+
107122
headers = {
108123
'authorization': 'Bearer ' + self._access_token
109124
}
@@ -112,7 +127,7 @@ def get_profile(self):
112127
'GET', PROFILE_URL, headers={**headers, **DEFAULT_HEADER})
113128

114129
if response.status_code == 401:
115-
self.refresh_token()
130+
self._refresh_access_token()
116131
profile = self.get_profile()
117132
else:
118133
profile = response.json()
@@ -122,6 +137,8 @@ def get_profile(self):
122137
def validate_letters(self):
123138
""" Retrieve letter validation status """
124139

140+
self._is_token_expired()
141+
125142
headers = {
126143
'authorization': 'Bearer ' + self._access_token
127144
}
@@ -130,7 +147,7 @@ def validate_letters(self):
130147
'GET', VALIDATE_LETTERS_URL, headers={**headers, **DEFAULT_HEADER})
131148

132149
if response.status_code == 401:
133-
self.refresh_token()
150+
self._refresh_access_token()
134151
validation = self.validate_letters()
135152
else:
136153
validation = response.json()
@@ -139,16 +156,18 @@ def validate_letters(self):
139156

140157
def get_letters(self):
141158
""" Retrieve letters """
159+
160+
self._is_token_expired()
142161

143162
headers = {
144163
'authorization': 'Bearer ' + self._access_token
145164
}
146165

147166
response = requests.request(
148167
'GET', LETTERS_URL, headers={**headers, **DEFAULT_HEADER})
149-
168+
150169
if response.status_code == 401:
151-
self.refresh_token()
170+
self._refresh_access_token()
152171
letters = self.get_letters()
153172
else:
154173
letters = response.json()
@@ -163,6 +182,8 @@ def get_letters(self):
163182
def get_letter(self, letter_id):
164183
""" Retrieve single letter by id """
165184

185+
self._is_token_expired()
186+
166187
headers = {
167188
'authorization': 'Bearer ' + self._access_token
168189
}
@@ -173,9 +194,9 @@ def get_letter(self, letter_id):
173194
if response.status_code == 200:
174195
letter = response.json()
175196
elif response.status_code == 401:
176-
self.refresh_token()
197+
self._refresh_access_token()
177198
letter = self.get_letter(letter_id)
178-
else:
199+
else:
179200
raise Exception('Unknown Error')
180201

181202
return letter

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from setuptools import setup, find_packages
22

33
setup(name='postnl_api',
4-
version='0.2',
4+
version='0.3',
55
description='Python wrapper for the PostNL API, a way to track packages using their online portal',
66
url='https://github.com/imicknl/python-postnl-api',
77
author='Mick Vleeshouwer',

0 commit comments

Comments
 (0)