Skip to content

Commit feb32b8

Browse files
committed
refactor: make session auth to use base service's http client
1 parent 90c163e commit feb32b8

4 files changed

Lines changed: 33 additions & 33 deletions

File tree

‎ibmcloudant/cloudant_base_service.py‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
from ibm_cloud_sdk_core import BaseService
2828
from ibm_cloud_sdk_core.authenticators import Authenticator
2929
from requests import Response, Session
30-
from requests.cookies import RequestsCookieJar
3130

3231
from .common import get_sdk_headers
3332
from .couchdb_session_authenticator import CouchDbSessionAuthenticator
@@ -96,9 +95,8 @@ def __init__(
9695
self.set_http_config(new_http_config)
9796
# Custom actions for CouchDbSessionAuthenticator
9897
if isinstance(authenticator, CouchDbSessionAuthenticator):
99-
# Replacing BaseService's http.cookiejar.CookieJar as RequestsCookieJar supports update(CookieJar)
100-
self.jar = RequestsCookieJar(self.jar)
101-
self.authenticator.set_jar(self.jar) # Authenticators don't have access to cookie jars by default
98+
# Make token manager of CouchDbSessionAuthenticator to use the same http client as main service
99+
self.authenticator.set_http_client(self.get_http_client(), self.jar)
102100
add_hooks(self)
103101

104102
def set_service_url(self, service_url: str):

‎ibmcloudant/couchdb_session_authenticator.py‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22

3-
# © Copyright IBM Corporation 2020, 2022.
3+
# © Copyright IBM Corporation 2020, 2025.
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
66
# you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
1616
"""
1717
Module for handling session authentication
1818
"""
19-
from requests import Request
19+
from requests import Request, Session
20+
from requests.cookies import RequestsCookieJar
21+
2022

2123
from ibm_cloud_sdk_core.authenticators import Authenticator
2224
from .couchdb_session_token_manager import CouchDbSessionTokenManager
@@ -46,20 +48,22 @@ def __init__(self,
4648
if not isinstance(disable_ssl_verification, bool):
4749
raise TypeError('disable_ssl_verification must be a bool')
4850

49-
self.jar = None
50-
5151
self.token_manager = CouchDbSessionTokenManager(
5252
username,
5353
password,
5454
disable_ssl_verification=disable_ssl_verification
5555
)
5656
self.validate()
5757

58-
def set_jar(self, jar):
59-
"""Sets the cookie jar for the authenticator.
58+
def set_http_client(self, http_client: Session, jar: RequestsCookieJar) -> None:
59+
"""Sets base serivice's http client for the authenticator.
6060
This is an internal method called by BaseService. Not to be called directly.
6161
"""
62-
self.jar = jar
62+
if isinstance(http_client, Session):
63+
self.token_manager.http_client = http_client
64+
self.token_manager.jar = jar
65+
else:
66+
raise TypeError("http_client parameter must be a requests.sessions.Session")
6367

6468
def validate(self):
6569
"""Validates the username, and password for session token requests.
@@ -82,11 +86,7 @@ def authenticate(self, req: Request):
8286
Args:
8387
req: Ignored. BaseService uses the cookie jar for every request
8488
"""
85-
jar = self.token_manager.get_token()
86-
# Requests seem to save cookies only for Sessions. BaseService is
87-
# hard-coded to work with "regular" requests requests so updating
88-
# the jar manually is necessary
89-
self.jar.update(jar)
89+
self.token_manager.get_token()
9090

9191
def authentication_type(self) -> str:
9292
"""Returns this authenticator's type ('COUCHDB_SESSION')."""

‎ibmcloudant/couchdb_session_token_manager.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22

3-
# © Copyright IBM Corporation 2020, 2022.
3+
# © Copyright IBM Corporation 2020, 2025.
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
66
# you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616
"""
1717
Module for managing session authentication token
1818
"""
19+
from requests import Session
20+
1921
from ibm_cloud_sdk_core.token_managers.token_manager import TokenManager
2022

2123

@@ -52,7 +54,9 @@ def __init__(self, username: str, password: str,
5254

5355
self.token = None
5456

57+
self.http_client = Session()
5558
self.http_config = {}
59+
self.jar = None
5660
self.headers = None
5761

5862
def request_token(self):
@@ -63,14 +67,16 @@ def request_token(self):
6367
A CookieJar of Cookies the server sent back.
6468
"""
6569

66-
response = self._request(
70+
response = self.http_client.request(
6771
method='POST',
6872
url=self.url + "/_session",
6973
headers=self.headers,
7074
json={
7175
'username': self.username,
7276
'password': self.password,
73-
}
77+
},
78+
cookies=self.jar,
79+
**self.http_config
7480
)
7581

7682
return response

‎test/integration/test_timeout.py‎

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22

3-
# © Copyright IBM Corporation 2021.
3+
# © Copyright IBM Corporation 2021, 2025.
44
# #
55
# Licensed under the Apache License, Version 2.0 (the "License");
66
# you may not use this file except in compliance with the License.
@@ -86,8 +86,9 @@ def get_authenticate_arguments(req):
8686
return req.mock_calls[0]
8787

8888
@staticmethod
89-
def get_request_arguments(tci, srv, idx):
90-
tci.assertEqual(srv.http_client.request.call_count, idx + 1)
89+
def get_request_arguments(tci, srv, idx, call_count=None):
90+
call_count = idx + 1 if call_count is None else call_count
91+
tci.assertEqual(srv.http_client.request.call_count, call_count)
9192
return srv.http_client.request.mock_calls[idx]
9293

9394
# Every method tests an authenticator.
@@ -142,10 +143,6 @@ def test_timeout_cloudantv1_sessionauth(self):
142143
)
143144
my_service.set_service_url("http://cloudant.example")
144145

145-
# Mock out authentication
146-
orig_request = requests.request
147-
requests.request = Mock(return_value=Helpers.get_mocked_response())
148-
149146
# Mock out request response
150147
Helpers.mock_out_cloudant_request(my_service)
151148

@@ -157,17 +154,16 @@ def test_timeout_cloudantv1_sessionauth(self):
157154
# Call the server
158155
my_service.get_server_information()
159156

160-
# Assert timeout is set to the authenticator
161-
auth_args = Helpers.get_authenticate_arguments(requests.request)
162-
Helpers.assert_default_timeout_setting(self, auth_args)
157+
# first call is to a _session end-point, so we have an additional call on our mock request
158+
if tc_num == 0:
159+
# Assert timeout is set to the authenticator
160+
auth_args = Helpers.get_request_arguments(self, my_service.authenticator.token_manager, tc_num, tc_num+2)
161+
Helpers.assert_default_timeout_setting(self, auth_args)
163162

164163
# Assert timeout is set in the server request
165-
req_args = Helpers.get_request_arguments(self, my_service, tc_num)
164+
req_args = Helpers.get_request_arguments(self, my_service, tc_num+1, tc_num+2)
166165
tc['assert_func'](self, req_args)
167166

168-
# Set back requests.request
169-
requests.request = orig_request
170-
171167
def test_timeout_cloudantv1_iamauth(self):
172168
authenticator = IAMAuthenticator('apikey')
173169
my_service = CloudantV1(

0 commit comments

Comments
 (0)