Skip to content

Merge Python3 breaking changes from V2 to master #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
This project contains core functionality required by Python code generated by the IBM Cloud OpenAPI SDK Generator
(openapi-sdkgen).

# Notice
Support for Python versions 2.x and versions <= 3.4 is deprecated and will be officially dropped in the next major release,
which is expected to be end of December, 2019.
# Python Version
The current minimum Python version supported is 3.5.3.

## Installation

Expand Down
11 changes: 7 additions & 4 deletions ibm_cloud_sdk_core/api_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Optional
from http import HTTPStatus
from requests import Response


Expand All @@ -32,9 +33,9 @@ class ApiException(Exception):
global_transaction_id (str, optional): Globally unique id the service endpoint has given a transaction.
"""

def __init__(self, code: int, message: Optional[str] = None, http_response: Optional[Response] = None):
def __init__(self, code: int, *, message: Optional[str] = None, http_response: Optional[Response] = None) -> None:
# Call the base class constructor with the parameters it needs
super(ApiException, self).__init__(message)
super().__init__(message)
self.message = message
self.code = code
self.http_response = http_response
Expand All @@ -43,14 +44,14 @@ def __init__(self, code: int, message: Optional[str] = None, http_response: Opti
self.global_transaction_id = http_response.headers.get('X-Global-Transaction-ID')
self.message = self.message if self.message else self._get_error_message(http_response)

def __str__(self):
def __str__(self) -> str:
msg = 'Error: ' + str(self.message) + ', Code: ' + str(self.code)
if self.global_transaction_id is not None:
msg += ' , X-global-transaction-id: ' + str(self.global_transaction_id)
return msg

@staticmethod
def _get_error_message(response: Response):
def _get_error_message(response: Response) -> str:
error_message = 'Unknown error'
try:
error_json = response.json()
Expand All @@ -66,6 +67,8 @@ def _get_error_message(response: Response):
error_message = error_json['errorMessage']
elif response.status_code == 401:
error_message = 'Unauthorized: Access is denied due to invalid credentials'
else:
error_message = HTTPStatus(response.status_code).phrase
return error_message
except:
return response.text or error_message
10 changes: 8 additions & 2 deletions ibm_cloud_sdk_core/authenticators/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,23 @@
class Authenticator(ABC):
"""This interface defines the common methods and constants associated with an Authenticator implementation."""
@abstractmethod
def authenticate(self, req: dict):
def authenticate(self, req: dict) -> None:
"""Perform the necessary authentication steps for the specified request.

Attributes:
req (dict): Will be modified to contain the appropriate authentication information.

To be implemented by subclasses.
"""
pass

@abstractmethod
def validate(self):
def validate(self) -> None:
"""Validates the current set of configuration information in the Authenticator.

Raises:
ValueError: The configuration information is not valid for service operations.

To be implemented by subclasses.
"""
pass
8 changes: 4 additions & 4 deletions ibm_cloud_sdk_core/authenticators/basic_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ class BasicAuthenticator(Authenticator):
"""
authentication_type = 'basic'

def __init__(self, username: str, password: str):
def __init__(self, username: str, password: str) -> None:
self.username = username
self.password = password
self.validate()
self.authorization_header = self.__construct_basic_auth_header()


def validate(self):
def validate(self) -> None:
"""Validate username and password.

Ensure the username and password are valid for service operations.
Expand All @@ -62,13 +62,13 @@ def validate(self):
'Please remove any surrounding {, }, or \" characters.')


def __construct_basic_auth_header(self):
def __construct_basic_auth_header(self) -> str:
authstring = "{0}:{1}".format(self.username, self.password)
base64_authorization = base64.b64encode(authstring.encode('utf-8')).decode('utf-8')
return 'Basic {0}'.format(base64_authorization)


def authenticate(self, req: Request):
def authenticate(self, req: Request) -> None:
"""Add basic authentication information to a request.

Basic Authorization will be added to the request's headers in the form:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ class BearerTokenAuthenticator(Authenticator):
"""
authentication_type = 'bearerToken'

def __init__(self, bearer_token: str):
def __init__(self, bearer_token: str) -> None:
self.bearer_token = bearer_token
self.validate()

def validate(self):
def validate(self) -> None:
"""Validate the bearer token.

Ensures the bearer token is valid for service operations.
Expand All @@ -49,7 +49,7 @@ def validate(self):
if self.bearer_token is None:
raise ValueError('The bearer token shouldn\'t be None.')

def authenticate(self, req: Request):
def authenticate(self, req: Request) -> None:
"""Adds bearer authentication information to the request.

The bearer token will be added to the request's headers in the form:
Expand All @@ -63,7 +63,7 @@ def authenticate(self, req: Request):
headers = req.get('headers')
headers['Authorization'] = 'Bearer {0}'.format(self.bearer_token)

def set_bearer_token(self, bearer_token: str):
def set_bearer_token(self, bearer_token: str) -> None:
"""Set a new bearer token to be sent in subsequent service operations.

Args:
Expand Down
16 changes: 9 additions & 7 deletions ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ def __init__(self,
username: str,
password: str,
url: str,
*,
disable_ssl_verification: bool = False,
headers: Optional[Dict[str, str]] = None,
proxies: Optional[Dict[str, str]] = None):
proxies: Optional[Dict[str, str]] = None) -> None:
self.token_manager = CP4DTokenManager(
username, password, url, disable_ssl_verification, headers, proxies)
username, password, url, disable_ssl_verification=disable_ssl_verification,
headers=headers, proxies=proxies)
self.validate()

def validate(self):
def validate(self) -> None:
"""Validate username, password, and url for token requests.

Ensures the username, password, and url are not None. Additionally, ensures they do not contain invalid
Expand All @@ -89,7 +91,7 @@ def validate(self):
'The url shouldn\'t start or end with curly brackets or quotes. '
'Please remove any surrounding {, }, or \" characters.')

def authenticate(self, req: Request):
def authenticate(self, req: Request) -> None:
"""Adds CP4D authentication information to the request.

The CP4D bearer token will be added to the request's headers in the form:
Expand All @@ -104,7 +106,7 @@ def authenticate(self, req: Request):
bearer_token = self.token_manager.get_token()
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)

def set_disable_ssl_verification(self, status: bool = False):
def set_disable_ssl_verification(self, status: bool = False) -> None:
"""Set the flag that indicates whether verification of the server's SSL certificate should be
disabled or not. Defaults to False.

Expand All @@ -113,15 +115,15 @@ def set_disable_ssl_verification(self, status: bool = False):
"""
self.token_manager.set_disable_ssl_verification(status)

def set_headers(self, headers: Dict[str, str]):
def set_headers(self, headers: Dict[str, str]) -> None:
"""Default headers to be sent with every CP4D token request.

Args:
headers: The headers to be sent with every CP4D token request.
"""
self.token_manager.set_headers(headers)

def set_proxies(self, proxies: Dict[str, str]):
def set_proxies(self, proxies: Dict[str, str]) -> None:
"""Sets the proxies the token manager will use to communicate with CP4D on behalf of the host.

Args:
Expand Down
22 changes: 12 additions & 10 deletions ibm_cloud_sdk_core/authenticators/iam_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,20 @@ class IAMAuthenticator(Authenticator):

def __init__(self,
apikey: str,
*,
url: Optional[str] = None,
client_id: Optional[str] = None,
client_secret: Optional[str] = None,
disable_ssl_verification: Optional[bool] = False,
disable_ssl_verification: bool = False,
headers: Optional[Dict[str, str]] = None,
proxies: Optional[Dict[str, str]] = None):
proxies: Optional[Dict[str, str]] = None) -> None:
self.token_manager = IAMTokenManager(
apikey, url, client_id, client_secret, disable_ssl_verification,
headers, proxies)
apikey, url=url, client_id=client_id, client_secret=client_secret,
disable_ssl_verification=disable_ssl_verification,
headers=headers, proxies=proxies)
self.validate()

def validate(self):
def validate(self) -> None:
"""Validates the apikey, client_id, and client_secret for IAM token requests.

Ensure the apikey is not none, and has no bad characters. Additionally, ensure the
Expand All @@ -91,7 +93,7 @@ def validate(self):
raise ValueError(
'Both client_id and client_secret should be initialized.')

def authenticate(self, req: Request):
def authenticate(self, req: Request) -> None:
"""Adds IAM authentication information to the request.

The IAM bearer token will be added to the request's headers in the form:
Expand All @@ -106,7 +108,7 @@ def authenticate(self, req: Request):
bearer_token = self.token_manager.get_token()
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)

def set_client_id_and_secret(self, client_id: str, client_secret: str):
def set_client_id_and_secret(self, client_id: str, client_secret: str) -> None:
"""Set the client_id and client_secret pair the token manager will use for IAM token requests.

Args:
Expand All @@ -119,7 +121,7 @@ def set_client_id_and_secret(self, client_id: str, client_secret: str):
self.token_manager.set_client_id_and_secret(client_id, client_secret)
self.validate()

def set_disable_ssl_verification(self, status: bool = False):
def set_disable_ssl_verification(self, status: bool = False) -> None:
"""Set the flag that indicates whether verification of the server's SSL certificate should be
disabled or not. Defaults to False.

Expand All @@ -128,15 +130,15 @@ def set_disable_ssl_verification(self, status: bool = False):
"""
self.token_manager.set_disable_ssl_verification(status)

def set_headers(self, headers: Dict[str, str]):
def set_headers(self, headers: Dict[str, str]) -> None:
"""Headers to be sent with every IAM token request.

Args:
headers: Headers to be sent with every IAM token request.
"""
self.token_manager.set_headers(headers)

def set_proxies(self, proxies: Dict[str, str]):
def set_proxies(self, proxies: Dict[str, str]) -> None:
"""Sets the proxies the token manager will use to communicate with IAM on behalf of the host.

Args:
Expand Down
4 changes: 2 additions & 2 deletions ibm_cloud_sdk_core/authenticators/no_auth_authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class NoAuthAuthenticator(Authenticator):
"""Performs no authentication."""
authentication_type = 'noAuth'

def validate(self):
def validate(self) -> None:
pass

def authenticate(self, req):
def authenticate(self, req) -> None:
pass
Loading