Skip to content
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

Function case #317

Merged
merged 16 commits into from
Jul 23, 2024
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
12 changes: 6 additions & 6 deletions .github/workflows/sdk-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ jobs:
run: pydocstyle --match-dir='^(?!build$).*' --match='^(?!(__init__\.py|setup\.py$)).*\.py$' src
- name: Lint with pydoclint
run: pydoclint --exclude='.*/build/.*' src
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 ./src --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 ./src --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Lint with pylint
run: |
# check for Python errors
pylint src --errors-only --disable=E0401,E0611 --ignore=build
# check for lint
pylint ./src --disable=all --enable=C0103,C0301 --ignore=build --max-line-length=127
- name: Test with pytest
run: |
coverage run -m pytest ./tests/unit
Expand Down
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
"./src/zos_jobs",
"./src/zosmf"
],
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ All notable changes to the Zowe Client Python SDK will be documented in this fil

- Add type annotations for all methods [#280] (https://github.com/zowe/zowe-client-python-sdk/issues/280)

- *Breaking*: Revised function names in `Logger` class and `files` class into snake_case. Enabled pylint rule to enforce function case. [#315] (https://github.com/zowe/zowe-client-python-sdk/issues/315)

### Bug Fixes

## `1.0.0-dev18`
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ Code standards

This project follows the [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide.

This project also uses `flake8` for code linting. Make sure to run `flake8` on your code before submitting a pull request.
This project also uses `pydocstyle`, `pydoclint`, and `pylint` for code linting. Make sure to run them on your code before submitting a pull request.

We recommend using `black` and `isort` as code formatters. Please format your code using these tools before creating a pull request.
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
black
certifi==2024.7.4
chardet==4.0.0
colorama==0.4.4
colorama==0.4.5
commentjson==0.9.0
coverage==5.4
deepmerge==1.1.0
flake8==5.0.0
idna==3.7
importlib-metadata==3.6.0;python_version<"3.8"
isort
Expand All @@ -18,8 +17,8 @@ pycodestyle==2.9.0
pydocstyle==5.1.1
pydoclint==0.5.3
pyfakefs
pyflakes==2.5.0
pylama==7.7.1
pylint==3.2.5
pytest==7.1.2
python-decouple==3.4
PyYAML==6.0.1
Expand Down
2 changes: 1 addition & 1 deletion src/core/zowe/core_for_zowe_sdk/config_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ConfigFile:
jsonc: Optional[dict] = None
_missing_secure_props: list = field(default_factory=list)

__logger = Log.registerLogger(__name__)
__logger = Log.register_logger(__name__)

@property
def filename(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion src/core/zowe/core_for_zowe_sdk/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ApiConnection:
"""

def __init__(self, host_url: str, user: str, password: str, ssl_verification: bool = True):
__logger = Log.registerLogger(__name__)
__logger = Log.register_logger(__name__)
if not host_url or not user or not password:
__logger.error("Missing connection argument")
raise MissingConnectionArgs()
Expand Down
2 changes: 1 addition & 1 deletion src/core/zowe/core_for_zowe_sdk/credential_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class CredentialManager:
"""A class including static functions for managing credentials."""

secure_props = {}
__logger = Log.registerLogger(__name__)
__logger = Log.register_logger(__name__)

@staticmethod
def load_secure_props() -> None:
Expand Down
8 changes: 4 additions & 4 deletions src/core/zowe/core_for_zowe_sdk/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Log:
loggers: set = set()

@staticmethod
def registerLogger(name: str) -> logging.Logger:
def register_logger(name: str) -> logging.Logger:
"""
Create and register a logger.

Expand All @@ -68,7 +68,7 @@ def registerLogger(name: str) -> logging.Logger:
return logger

@staticmethod
def setAllLoggerLevel(level: int):
def set_all_logger_level(level: int):
"""
Set display level for all loggers.

Expand Down Expand Up @@ -107,13 +107,13 @@ def open(logger: logging.Logger):
logger.disabled = False

@staticmethod
def closeAll():
def close_all():
"""Disable all loggers."""
for logger in Log.loggers:
logger.disabled = True

@staticmethod
def openAll():
def open_all():
"""Enable all loggers."""
for logger in Log.loggers:
logger.disabled = False
Expand Down
48 changes: 27 additions & 21 deletions src/core/zowe/core_for_zowe_sdk/profile_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@
from copy import deepcopy
from typing import Optional

import jsonschema
from deepmerge import always_merger
from jsonschema.exceptions import (
FormatError,
SchemaError,
UndefinedTypeCheck,
UnknownType,
ValidationError,
)

from .config_file import ConfigFile, Profile
from .credential_manager import CredentialManager
Expand Down Expand Up @@ -67,7 +73,7 @@
self.__project_config = ConfigFile(type=TEAM_CONFIG, name=appname)
self.__project_user_config = ConfigFile(type=USER_CONFIG, name=appname)

self.__logger = Log.registerLogger(__name__)
self.__logger = Log.register_logger(__name__)

self.__global_config = ConfigFile(type=TEAM_CONFIG, name=GLOBAL_CONFIG_NAME)
try:
Expand Down Expand Up @@ -261,32 +267,32 @@
FormatError
If validating a format in the configuration fails.
"""
logger = Log.registerLogger(__name__)
logger = Log.register_logger(__name__)

cfg_profile = Profile()
try:
cfg_profile = cfg.get_profile(
profile_name=profile_name, profile_type=profile_type, validate_schema=validate_schema
)
except jsonschema.exceptions.ValidationError as exc:
except ValidationError as exc:

Check warning on line 277 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L277

Added line #L277 was not covered by tests
logger.error(f"Instance was invalid under the provided $schema property, {exc}")
raise jsonschema.exceptions.ValidationError(
f"Instance was invalid under the provided $schema property, {exc}"
)
except jsonschema.exceptions.SchemaError as exc:
raise ValidationError(f"Instance was invalid under the provided $schema property, {exc}")
except SchemaError as exc:

Check warning on line 280 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L279-L280

Added lines #L279 - L280 were not covered by tests
logger.error(f"The provided schema is invalid, {exc}")
raise jsonschema.exceptions.SchemaError(f"The provided schema is invalid, {exc}")
except jsonschema.exceptions.UndefinedTypeCheck as exc:
raise SchemaError(f"The provided schema is invalid, {exc}")
except UndefinedTypeCheck as exc:

Check warning on line 283 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L282-L283

Added lines #L282 - L283 were not covered by tests
logger.error(f"A type checker was asked to check a type it did not have registered, {exc}")
raise jsonschema.exceptions.UndefinedTypeCheck(
f"A type checker was asked to check a type it did not have registered, {exc}"
)
except jsonschema.exceptions.UnknownType as exc:
raise UndefinedTypeCheck(f"A type checker was asked to check a type it did not have registered, {exc}")
except UnknownType as exc:

Check warning on line 286 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L285-L286

Added lines #L285 - L286 were not covered by tests
logger.error(f"Unknown type is found in schema_json, {exc}")
raise jsonschema.exceptions.UnknownType(f"Unknown type is found in schema_json, {exc}")
except jsonschema.exceptions.FormatError as exc:
raise UnknownType(

Check warning on line 288 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L288

Added line #L288 was not covered by tests
f"Unknown type is found in schema_json, {exc}",
instance=profile_name,
schema=validate_schema,
)
except FormatError as exc:

Check warning on line 293 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L293

Added line #L293 was not covered by tests
logger.error(f"Validating a format config_json failed for schema_json, {exc}")
raise jsonschema.exceptions.FormatError(f"Validating a format config_json failed for schema_json, {exc}")
raise FormatError(f"Validating a format config_json failed for schema_json, {exc}")

Check warning on line 295 in src/core/zowe/core_for_zowe_sdk/profile_manager.py

View check run for this annotation

Codecov / codecov/patch

src/core/zowe/core_for_zowe_sdk/profile_manager.py#L295

Added line #L295 was not covered by tests
except ProfileNotFound:
if profile_name:
logger.warning(f"Profile '{profile_name}' not found in file '{cfg.filename}'")
Expand Down Expand Up @@ -405,13 +411,13 @@
cfg_schema = cfg_layer.schema_property
cfg_schema_dir = cfg_layer._location

usrProject = self.__project_user_config.profiles or {}
usr_project = self.__project_user_config.profiles or {}
project = self.__project_config.profiles or {}
project_temp = always_merger.merge(deepcopy(project), usrProject)
project_temp = always_merger.merge(deepcopy(project), usr_project)

usrGlobal = self.__global_user_config.profiles or {}
usr_global = self.__global_user_config.profiles or {}
global_ = self.__global_config.profiles or {}
global_temp = always_merger.merge(deepcopy(global_), usrGlobal)
global_temp = always_merger.merge(deepcopy(global_), usr_global)

profiles_merged = project_temp
for name, value in global_temp.items():
Expand Down
12 changes: 7 additions & 5 deletions src/core/zowe/core_for_zowe_sdk/request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, session_arguments: dict, logger_name: str = __name__):
self.session_arguments = session_arguments
self.__valid_methods = ["GET", "POST", "PUT", "DELETE"]
self.__handle_ssl_warnings()
self.__logger = Log.registerLogger(logger_name)
self.__logger = Log.register_logger(logger_name)

def __handle_ssl_warnings(self):
"""Turn off warnings if the SSL verification argument if off."""
Expand Down Expand Up @@ -121,7 +121,9 @@ def __validate_response(self):
if self.__response.ok:
if self.__response.status_code not in self.__expected_code:
self.__logger.error(
f"The status code from z/OSMF was: {self.__expected_code}\nExpected: {self.__response.status_code}\nRequest output:{self.__response.text}"
f"The status code from z/OSMF was: {self.__expected_code}\n"
f"Expected: {self.__response.status_code}\n"
f"Request output: {self.__response.text}"
)
raise UnexpectedStatus(self.__expected_code, self.__response.status_code, self.__response.text)
else:
Expand All @@ -146,10 +148,10 @@ def __normalize_response(self) -> Union[str, bytes, dict]:
- `str` when the response is plain text
- `dict` when the response is json
"""
contentType = self.__response.headers.get("Content-Type")
if contentType == "application/octet-stream":
content_type = self.__response.headers.get("Content-Type")
if content_type == "application/octet-stream":
return self.__response.content
elif contentType and contentType.startswith("application/json"):
elif content_type and content_type.startswith("application/json"):
return "" if self.__response.text == "" else self.__response.json()
else:
return self.__response.text
8 changes: 4 additions & 4 deletions src/core/zowe/core_for_zowe_sdk/sdk_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, profile: dict, default_url: str, logger_name: str = __name__)
session = Session(profile)
self.session: ISession = session.load()

self.logger = Log.registerLogger(logger_name)
self.logger = Log.register_logger(logger_name)

self._default_service_url = default_url
self._default_headers = {
Expand All @@ -52,17 +52,17 @@ def __init__(self, profile: dict, default_url: str, logger_name: str = __name__)
"headers": self._default_headers,
}
self.__session_arguments = {
"verify": self.session.rejectUnauthorized,
"verify": self.session.reject_unauthorized,
"timeout": 30,
}
self.request_handler = RequestHandler(self.__session_arguments, logger_name=logger_name)

if self.session.type == session_constants.AUTH_TYPE_BASIC:
self._request_arguments["auth"] = (self.session.user, self.session.password)
elif self.session.type == session_constants.AUTH_TYPE_BEARER:
self._default_headers["Authorization"] = f"Bearer {self.session.tokenValue}"
self._default_headers["Authorization"] = f"Bearer {self.session.token_value}"
elif self.session.type == session_constants.AUTH_TYPE_TOKEN:
self._default_headers["Cookie"] = f"{self.session.tokenType}={self.session.tokenValue}"
self._default_headers["Cookie"] = f"{self.session.token_type}={self.session.token_value}"
elif self.session.type == session_constants.AUTH_TYPE_CERT_PEM:
self.__session_arguments["cert"] = self.session.cert

Expand Down
28 changes: 14 additions & 14 deletions src/core/zowe/core_for_zowe_sdk/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ class ISession:

host: str
port: int = session_constants.DEFAULT_HTTPS_PORT
rejectUnauthorized: bool = True
reject_unauthorized: bool = True
user: Optional[str] = None
password: Optional[str] = None
protocol: str = session_constants.HTTPS_PROTOCOL
basePath: Optional[str] = None
base_path: Optional[str] = None
type: Optional[str] = None
tokenType: Optional[str] = None
tokenValue: Optional[str] = None
token_type: Optional[str] = None
token_value: Optional[str] = None
cert: Optional[str] = None


Expand All @@ -51,7 +51,7 @@ class Session:

def __init__(self, props: dict) -> None:
# set host and port
self.__logger = Log.registerLogger(__name__)
self.__logger = Log.register_logger(__name__)

if props.get("host") is not None:
self.session: ISession = ISession(host=props.get("host"))
Expand All @@ -63,33 +63,33 @@ def __init__(self, props: dict) -> None:
if props.get("user") is not None and props.get("password") is not None:
self.session.user = props.get("user")
self.session.password = props.get("password")
self.session.rejectUnauthorized = props.get("rejectUnauthorized")
self.session.reject_unauthorized = props.get("rejectUnauthorized")
self.session.type = session_constants.AUTH_TYPE_BASIC
elif props.get("tokenType") is not None and props.get("tokenValue") is not None:
self.session.tokenType = props.get("tokenType")
self.session.tokenValue = props.get("tokenValue")
self.session.token_type = props.get("tokenType")
self.session.token_value = props.get("tokenValue")
self.session.type = session_constants.AUTH_TYPE_TOKEN
elif props.get("tokenValue") is not None:
self.session.tokenValue = props.get("tokenValue")
self.session.token_value = props.get("tokenValue")
self.session.type = session_constants.AUTH_TYPE_BEARER
elif props.get("certFile") is not None:
if props.get("certKeyFile"):
self.session.cert = (props.get("certFile"), props.get("certKeyFile"))
else:
self.__logger.error("A certificate key file must be provided when certFile is specified")
raise Exception("A certificate key file must be provided when certFile is specified")
self.session.rejectUnauthorized = props.get("rejectUnauthorized")
self.session.reject_unauthorized = props.get("rejectUnauthorized")
self.session.type = session_constants.AUTH_TYPE_CERT_PEM
else:
self.session.type = session_constants.AUTH_TYPE_NONE
self.__logger.info("Authentication method not supplied")
# raise Exception("An authentication method must be supplied")

# set additional parameters
self.session.basePath = props.get("basePath")
self.session.base_path = props.get("basePath")
self.session.port = props.get("port", self.session.port)
self.session.protocol = props.get("protocol", self.session.protocol)
self.session.rejectUnauthorized = False if props.get("rejectUnauthorized") == False else True
self.session.reject_unauthorized = False if props.get("rejectUnauthorized") == False else True

def load(self) -> ISession:
"""
Expand All @@ -112,5 +112,5 @@ def host_url(self) -> str:
str
the formatted host URL
"""
basePath = self.session.basePath or ""
return f"{self.session.protocol}://{self.session.host}:{self.session.port}{basePath}"
base_path = self.session.base_path or ""
return f"{self.session.protocol}://{self.session.host}:{self.session.port}{base_path}"
2 changes: 1 addition & 1 deletion src/core/zowe/core_for_zowe_sdk/zosmf_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class ZosmfProfile:

def __init__(self, profile_name: str):
self.__profile_name = profile_name
self.__logger = Log.registerLogger(__name__)
self.__logger = Log.register_logger(__name__)

@property
def profiles_dir(self) -> str:
Expand Down
6 changes: 0 additions & 6 deletions src/zos_files/zowe/zos_files_for_zowe_sdk/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
_ZOWE_FILES_DEFAULT_ENCODING = zos_file_constants["ZoweFilesDefaultEncoding"]


@dataclass
class DatasetOption:
"""A dataclass that represents options for creating a dataset.

Expand Down Expand Up @@ -286,11 +285,6 @@ def like(self) -> Optional[str]:
"""Get the dataset name to copy attributes from."""
return self.__like

@like.setter
def like(self, like: Optional[str]):
"""Set the dataset name to copy attributes from."""
self.__like = like

def to_dict(self) -> dict:
"""Return the DatasetOption as a dict."""
return {key.replace("_DatasetOption__", ""): value for key, value in self.__dict__.items() if value is not None}
Expand Down
Loading
Loading