0
# Authentication & Sessions
1
2
Built-in authentication support for various methods including Basic Auth, OAuth2, and custom authentication schemes. RestNavigator provides flexible session management through integration with the requests library.
3
4
## Capabilities
5
6
### Authentication Methods
7
8
Set authentication credentials for all subsequent API requests.
9
10
```python { .api }
11
class HALNavigator:
12
def authenticate(self, auth) -> None:
13
"""
14
Set authentication for API requests.
15
16
Parameters:
17
- auth: Authentication object compatible with requests library
18
(tuple for basic auth, custom auth objects, etc.)
19
"""
20
```
21
22
### Session Management
23
24
Access and configure the underlying requests session for advanced authentication and request customization.
25
26
```python { .api }
27
class HALNavigator:
28
@property
29
def session(self) -> 'Session':
30
"""
31
Requests session object used for all HTTP operations.
32
33
Returns:
34
Session object with authentication and configuration
35
"""
36
37
@property
38
def headers(self) -> dict:
39
"""
40
Session headers dictionary for request customization.
41
42
Returns:
43
Mutable dictionary of session headers
44
"""
45
```
46
47
### Basic Authentication
48
49
```python
50
from restnavigator import Navigator
51
52
# Basic authentication with username/password
53
api = Navigator.hal('https://api.example.com/')
54
api.authenticate(('username', 'password'))
55
56
# Or set during creation
57
api = Navigator.hal(
58
'https://api.example.com/',
59
auth=('username', 'password')
60
)
61
62
# Access authenticated resources
63
user_data = api['me']()
64
```
65
66
### OAuth2 Authentication
67
68
```python
69
from restnavigator import Navigator
70
from requests_oauthlib import OAuth2Session
71
72
# Create OAuth2 session
73
oauth = OAuth2Session('client_id', token={
74
'access_token': 'your_access_token',
75
'token_type': 'Bearer'
76
})
77
78
# Use OAuth2 session with navigator
79
api = Navigator.hal('https://api.example.com/', session=oauth)
80
81
# All requests will include OAuth2 authorization
82
user_profile = api['profile']()
83
```
84
85
### Custom Authentication
86
87
```python
88
import requests
89
from requests.auth import AuthBase
90
91
class CustomAuth(AuthBase):
92
def __init__(self, api_key):
93
self.api_key = api_key
94
95
def __call__(self, r):
96
r.headers['Authorization'] = f'ApiKey {self.api_key}'
97
return r
98
99
# Use custom authentication
100
api = Navigator.hal('https://api.example.com/')
101
api.authenticate(CustomAuth('your-api-key'))
102
103
# Or with session
104
session = requests.Session()
105
session.auth = CustomAuth('your-api-key')
106
api = Navigator.hal('https://api.example.com/', session=session)
107
```
108
109
### Session Headers
110
111
```python
112
# Set default headers for all requests
113
api = Navigator.hal(
114
'https://api.example.com/',
115
headers={
116
'User-Agent': 'MyApp/1.0',
117
'Accept': 'application/hal+json'
118
}
119
)
120
121
# Modify session headers after creation
122
api.headers['X-Custom-Header'] = 'custom-value'
123
124
# Headers are inherited by all navigators from the same API
125
user = api['users', 0]
126
print(user.headers) # Includes all session headers
127
```
128
129
### Advanced Session Configuration
130
131
```python
132
import requests
133
134
# Create custom session with advanced configuration
135
session = requests.Session()
136
137
# Configure retries
138
from requests.adapters import HTTPAdapter
139
from urllib3.util.retry import Retry
140
141
retry_strategy = Retry(
142
total=3,
143
status_forcelist=[429, 500, 502, 503, 504],
144
method_whitelist=["HEAD", "GET", "OPTIONS"]
145
)
146
adapter = HTTPAdapter(max_retries=retry_strategy)
147
session.mount("http://", adapter)
148
session.mount("https://", adapter)
149
150
# Configure timeout
151
session.timeout = 30
152
153
# Use configured session
154
api = Navigator.hal('https://api.example.com/', session=session)
155
```
156
157
### Token Refresh and Management
158
159
```python
160
from requests_oauthlib import OAuth2Session
161
162
# OAuth2 with automatic token refresh
163
def token_updater(token):
164
# Save updated token to secure storage
165
save_token_to_storage(token)
166
167
oauth = OAuth2Session(
168
'client_id',
169
token=current_token,
170
auto_refresh_url='https://api.example.com/oauth/token',
171
auto_refresh_kwargs={
172
'client_id': 'client_id',
173
'client_secret': 'client_secret'
174
},
175
token_updater=token_updater
176
)
177
178
api = Navigator.hal('https://api.example.com/', session=oauth)
179
180
# Tokens will be automatically refreshed when they expire
181
data = api['protected-resource']()
182
```
183
184
### Authentication State Management
185
186
```python
187
# Check if navigator is authenticated
188
def is_authenticated(navigator):
189
return navigator.session.auth is not None
190
191
# Get current authentication type
192
def get_auth_type(navigator):
193
auth = navigator.session.auth
194
if isinstance(auth, tuple) and len(auth) == 2:
195
return 'basic'
196
elif hasattr(auth, '__class__'):
197
return auth.__class__.__name__
198
return 'none'
199
200
# Clear authentication
201
def clear_auth(navigator):
202
navigator.session.auth = None
203
204
# Usage
205
print("Authenticated:", is_authenticated(api))
206
print("Auth type:", get_auth_type(api))
207
```
208
209
### Per-Request Authentication Override
210
211
```python
212
# Override authentication for specific requests
213
result = api['sensitive-endpoint'].create(
214
data,
215
headers={'Authorization': 'Bearer special-token'}
216
)
217
218
# Use different auth for specific operations
219
admin_auth = ('admin', 'admin-password')
220
admin_result = api['admin']['users'].create(
221
user_data,
222
headers={'Authorization': f'Basic {base64.b64encode(b"admin:admin-password").decode()}'}
223
)
224
```
225
226
### Session Sharing and Identity
227
228
```python
229
# All navigators from the same API root share the same session
230
api = Navigator.hal('https://api.example.com/')
231
api.authenticate(('user', 'pass'))
232
233
# These navigators share authentication
234
users = api['users']
235
posts = api['posts']
236
237
# They all use the same session
238
assert users.session is api.session
239
assert posts.session is api.session
240
241
# Authentication applies to all related navigators
242
user_data = users[0]() # Uses authenticated session
243
post_data = posts[0]() # Uses authenticated session
244
```
245
246
### Error Handling with Authentication
247
248
```python
249
from restnavigator.exc import HALNavigatorError
250
251
try:
252
protected_data = api['protected']()
253
except HALNavigatorError as e:
254
if e.status == 401:
255
print("Authentication required or invalid")
256
# Re-authenticate or refresh token
257
api.authenticate(new_credentials)
258
protected_data = api['protected']()
259
elif e.status == 403:
260
print("Insufficient permissions")
261
else:
262
raise
263
```