@@ -260,6 +260,13 @@ class Session(requests.Session):
260
260
to true. Ignored for HTTP connections.
261
261
token : str, optional
262
262
OAuth token to use for authorization.
263
+ client_id : str, optional
264
+ Client ID requesting access. Use if connection to Viya should be
265
+ made using `client_credentials` method.
266
+ client_secret : str, optional
267
+ Client secret for client requesting access. Required if `client_id`
268
+ is provided.
269
+
263
270
264
271
Attributes
265
272
----------
@@ -285,6 +292,8 @@ def __init__(
285
292
port = None ,
286
293
verify_ssl = None ,
287
294
token = None ,
295
+ client_id = None ,
296
+ client_secret = None
288
297
):
289
298
super (Session , self ).__init__ ()
290
299
@@ -373,7 +382,7 @@ def is_ipaddress(hst):
373
382
"password" : password ,
374
383
}
375
384
376
- if self ._settings ["password" ] is None :
385
+ if self ._settings ["password" ] is None and client_secret is None :
377
386
# Try to get credentials from .authinfo or .netrc files.
378
387
# If no file path was specified, the default locations will
379
388
# be checked.
@@ -408,7 +417,8 @@ def is_ipaddress(hst):
408
417
409
418
# Find a suitable authentication mechanism and build an auth header
410
419
self .auth = self .get_auth (
411
- self ._settings ["username" ], self ._settings ["password" ], token
420
+ self ._settings ["username" ], self ._settings ["password" ], token ,
421
+ client_id = client_id , client_secret = client_secret
412
422
)
413
423
414
424
# Used for context manager
@@ -686,20 +696,39 @@ def head(self, url, **kwargs):
686
696
def delete (self , url , ** kwargs ):
687
697
return self .request ("DELETE" , url , ** kwargs )
688
698
689
- def get_auth (self , username = None , password = None , token = None ):
699
+ def get_auth (
700
+ self ,
701
+ username = None ,
702
+ password = None ,
703
+ token = None ,
704
+ client_id = None ,
705
+ client_secret = None
706
+ ):
690
707
"""Attempt to authenticate with the Viya environment.
691
708
692
- If `username` and `password` or `token` are provided, they will be used exclusively. If neither of these
693
- is specified, Kerberos authorization will be attempted. If this fails, authorization using an
694
- OAuth2 authorization code will be attempted. Be aware that this requires prompting the user for input and
709
+ If `username` and `password` or `token` are provided, they will be used
710
+ exclusively. Alternatively `client_id` and `client_secret` can be
711
+ provided without `username` and `password` which will result in
712
+ authentication using `client_credentials` flow. If neither of these is
713
+ specified, Kerberos authorization will be attempted. If this fails,
714
+ authorization using an OAuth2 authorization code will be attempted.
715
+ Be aware that this requires prompting the user for input and
695
716
should NOT be used in a non-interactive session.
696
717
697
718
Parameters
698
719
----------
699
720
username : str, optional
700
721
Username to use for authentication.
701
722
password : str, optional
702
- Password to use for authentication. Required if `username` is provided.
723
+ Password to use for authentication. Required if `username` is
724
+ provided.
725
+ client_id : str, optional
726
+ Client ID requesting access. Use if connection to Viya should be
727
+ made using a `client_credentials` method.
728
+ client_secret : str, optional
729
+ Client secret for client requesting access. Required if `client_id`
730
+ is provided.
731
+
703
732
token : str, optional
704
733
An existing OAuth2 access token to use.
705
734
@@ -711,8 +740,15 @@ def get_auth(self, username=None, password=None, token=None):
711
740
"""
712
741
713
742
# If explicit username & password were provided, use them.
714
- if username is not None and password is not None :
715
- return self .get_oauth_token (username , password )
743
+ if username and password :
744
+ return self .get_oauth_token (
745
+ username , password
746
+ )
747
+ if client_id is not None and client_secret is not None :
748
+ return self .get_oauth_token (
749
+ client_id = client_id ,
750
+ client_secret = client_secret
751
+ )
716
752
717
753
# If an existing access token was provided, use it
718
754
if token is not None :
@@ -745,22 +781,27 @@ def get_oauth_token(
745
781
client_id = None ,
746
782
client_secret = None ,
747
783
):
748
- """Request an OAuth2 access token using either a username & password or an auth token.
784
+ """Request an OAuth2 access token using either a username & password,
785
+ client_id and client_secret, or an auth token.
749
786
750
787
Parameters
751
788
----------
752
789
username : str, optional
753
790
Username to use for authentication.
754
791
password : str, optional
755
- Password to use for authentication. Required if `username` is provided.
792
+ Password to use for authentication. Required if `username` is
793
+ provided.
756
794
auth_code : str, optional
757
795
Authorization code to use.
758
796
refresh_token : str, optinoal
759
797
Valid refresh token to use.
760
798
client_id : str, optional
761
- Client ID requesting access. Use if connection to Viya should be made using a non-default client id.
799
+ Client ID requesting access. Use if connection to Viya should be
800
+ made using a non-default client id or using `client_credentials`
801
+ method.
762
802
client_secret : str, optional
763
- Client secret for client requesting access. Required if `client_id` is provided
803
+ Client secret for client requesting access. Required if `client_id`
804
+ is provided.
764
805
765
806
Returns
766
807
-------
@@ -778,6 +819,8 @@ def get_oauth_token(
778
819
"username" : username ,
779
820
"password" : password ,
780
821
}
822
+ elif username is None and client_secret is not None :
823
+ data = {"grant_type" : "client_credentials" }
781
824
elif auth_code is not None :
782
825
data = {"grant_type" : "authorization_code" , "code" : auth_code }
783
826
elif refresh_token is not None :
@@ -830,7 +873,7 @@ def get_oauth_token(
830
873
831
874
# No reason to cache token if username & password were provided - they'd just be re-provided on future
832
875
# connections. Cache for auth code & refresh token to prevent frequent interruptions for the user.
833
- if username is None :
876
+ if username is None and client_secret is None :
834
877
self .cache_token (token , self .PROFILE_PATH )
835
878
836
879
return token
0 commit comments