Skip to content

Commit

Permalink
Merge pull request #322 from zowe/Response-Type-for-REST-APT
Browse files Browse the repository at this point in the history
Update REST API response type
  • Loading branch information
t1m0thyj authored Aug 13, 2024
2 parents 9c42f3b + f87c516 commit 66b711f
Show file tree
Hide file tree
Showing 37 changed files with 943 additions and 146 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/sdk-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Lint with pydocstyle
run: pydocstyle --match-dir='^(?!build$).*' --match='^(?!(__init__\.py|setup\.py$)).*\.py$' src
run: pydocstyle --match-dir='^(?!(build|response)$).*' --match='^(?!(__init__\.py|setup\.py$)).*\.py$' src
- name: Lint with pydoclint
run: pydoclint --exclude='.*/build/.*' src
run: pydoclint --exclude='.*/(build|response)/.*' src
- 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
pylint ./src --disable=all --enable=C0103,C0301 --ignore=build,response --max-line-length=127
- name: Check license headers
run: python scripts/license_header.py src
- name: Test with pytest
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"./src/zos_console",
"./src/zos_files",
"./src/zos_jobs",
"./src/zosmf"
"./src/zosmf",
"./src/zos_tso"
],
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to the Zowe Client Python SDK will be documented in this file.

## Recent Changes

### Enhancements

- *Breaking*: Update method return types to use custom classes for REST API responses [#89] (https://github.com/zowe/zowe-client-python-sdk/issues/89)

### Bug Fixes


## `1.0.0-dev19`

### Enhancements
Expand Down
2 changes: 1 addition & 1 deletion scripts/license_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def main():
if "build" in root.split(os.path.sep):
continue
for file in files:
if file.endswith(".py"):
if file.endswith(".py") and file is not "_version.py":
file_path = os.path.join(root, file)
if not check_and_add_license_header(file_path, write_header):
print(f"License header missing in: {file_path}")
Expand Down
11 changes: 11 additions & 0 deletions src/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
"""Zowe Python Client SDK.
This program and the accompanying materials are made available under the terms of the
Eclipse Public License v2.0 which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright Contributors to the Zowe Project.
"""
__version__ = "1.0.0-dev19"
14 changes: 7 additions & 7 deletions src/core/zowe/core_for_zowe_sdk/request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def __handle_ssl_warnings(self):
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def perform_request(
self, method: str, request_arguments: dict, expected_code: dict = [200], stream: bool = False
) -> dict:
self, method: str, request_arguments: dict, expected_code: list = [200], stream: bool = False
) -> Union[str, bytes, dict, None]:
"""Execute an HTTP/HTTPS requests from given arguments and return validated response (JSON).
Parameters
Expand All @@ -54,14 +54,14 @@ def perform_request(
The request method that should be used
request_arguments: dict
The dictionary containing the required arguments for the execution of the request
expected_code: dict
expected_code: list
The list containing the acceptable response codes (default is [200])
stream: bool
The boolean value whether the request is stream
Returns
-------
dict
Union[str, bytes, dict, None]
normalized request response in json (dictionary)
"""
self.__method = method
Expand Down Expand Up @@ -136,13 +136,13 @@ def __validate_response(self):
)
raise RequestFailed(self.__response.status_code, output_str)

def __normalize_response(self) -> Union[str, bytes, dict]:
def __normalize_response(self) -> Union[str, bytes, dict, None]:
"""
Normalize the response object to a JSON format.
Returns
-------
Union[str, bytes, dict]
Union[str, bytes, dict, None]
Response object at the format based on Content-Type header:
- `bytes` when the response is binary data
- `str` when the response is plain text
Expand All @@ -152,6 +152,6 @@ def __normalize_response(self) -> Union[str, bytes, dict]:
if content_type == "application/octet-stream":
return self.__response.content
elif content_type and content_type.startswith("application/json"):
return "" if self.__response.text == "" else self.__response.json()
return None if self.__response.text == "" else self.__response.json()
else:
return self.__response.text
14 changes: 8 additions & 6 deletions src/zos_console/zowe/zos_console_for_zowe_sdk/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

from zowe.core_for_zowe_sdk import SdkApi

from .response import ConsoleResponse, IssueCommandResponse


class Console(SdkApi):
"""
Expand All @@ -28,7 +30,7 @@ class Console(SdkApi):
def __init__(self, connection: dict):
super().__init__(connection, "/zosmf/restconsoles/consoles/defcn", logger_name=__name__)

def issue_command(self, command: str, console: Optional[str] = None) -> dict:
def issue_command(self, command: str, console: Optional[str] = None) -> IssueCommandResponse:
"""Issues a command on z/OS Console.
Parameters
Expand All @@ -40,17 +42,17 @@ def issue_command(self, command: str, console: Optional[str] = None) -> dict:
Returns
-------
dict
IssueCommandResponse
A JSON containing the response from the console command
"""
custom_args = self._create_custom_request_arguments()
custom_args["url"] = self._request_endpoint.replace("defcn", console or "defcn")
request_body = {"cmd": command}
custom_args["json"] = request_body
response_json = self.request_handler.perform_request("PUT", custom_args)
return response_json
return IssueCommandResponse(response_json)

def get_response(self, response_key: str, console: Optional[str] = None) -> dict:
def get_response(self, response_key: str, console: Optional[str] = None) -> ConsoleResponse:
"""
Collect outstanding synchronous z/OS Console response messages.
Expand All @@ -63,11 +65,11 @@ def get_response(self, response_key: str, console: Optional[str] = None) -> dict
Returns
-------
dict
ConsoleResponse
A JSON containing the response to the command
"""
custom_args = self._create_custom_request_arguments()
request_url = "{}/solmsgs/{}".format(console or "defcn", response_key)
custom_args["url"] = self._request_endpoint.replace("defcn", request_url)
response_json = self.request_handler.perform_request("GET", custom_args)
return response_json
return ConsoleResponse(response_json)
13 changes: 13 additions & 0 deletions src/zos_console/zowe/zos_console_for_zowe_sdk/response/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Zowe Python Client SDK.
This program and the accompanying materials are made available under the terms of the
Eclipse Public License v2.0 which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright Contributors to the Zowe Project.
"""

from .console import ConsoleResponse, IssueCommandResponse
50 changes: 50 additions & 0 deletions src/zos_console/zowe/zos_console_for_zowe_sdk/response/console.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Zowe Python Client SDK.
This program and the accompanying materials are made available under the terms of the
Eclipse Public License v2.0 which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright Contributors to the Zowe Project.
"""

from dataclasses import dataclass
from typing import Any, Optional


@dataclass
class IssueCommandResponse:
cmd_response_key: Optional[str] = None
cmd_response_url: Optional[str] = None
cmd_response_uri: Optional[str] = None
cmd_response: Optional[str] = None

def __init__(self, response: dict) -> None:
for k, value in response.items():
key = k.replace("-", "_")
super().__setattr__(key, value)

def __getitem__(self, key: str) -> str:
return self.__dict__[key.replace("-", "_")]

def __setitem__(self, key: str, value: str) -> None:
self.__dict__[key.replace("-", "_")] = value


@dataclass
class ConsoleResponse:
cmd_response: Optional[str] = None
sol_key_detected: Optional[bool] = None

def __init__(self, response: dict) -> None:
for k, value in response.items():
key = k.replace("-", "_")
super().__setattr__(key, value)

def __getitem__(self, key: str) -> Any:
return self.__dict__[key.replace("-", "_")]

def __setitem__(self, key: str, value: Any) -> None:
self.__dict__[key.replace("-", "_")] = value
13 changes: 7 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 @@ -17,6 +17,7 @@
from zowe.core_for_zowe_sdk import SdkApi
from zowe.core_for_zowe_sdk.exceptions import FileNotFound
from zowe.zos_files_for_zowe_sdk.constants import FileType, zos_file_constants
from zowe.zos_files_for_zowe_sdk.response import DatasetListResponse, MemberListResponse

_ZOWE_FILES_DEFAULT_ENCODING = zos_file_constants["ZoweFilesDefaultEncoding"]

Expand Down Expand Up @@ -306,7 +307,7 @@ def __init__(self, connection: dict):
super().__init__(connection, "/zosmf/restfiles/", logger_name=__name__)
self._default_headers["Accept-Encoding"] = "gzip"

def list(self, name_pattern: str, return_attributes: bool = False) -> List[Dict]:
def list(self, name_pattern: str, return_attributes: bool = False) -> DatasetListResponse:
"""
Retrieve a list of datasets based on a given pattern.
Expand All @@ -319,7 +320,7 @@ def list(self, name_pattern: str, return_attributes: bool = False) -> List[Dict]
Returns
-------
List[Dict]
DatasetListResponse
A JSON with a list of dataset names (and attributes if specified) matching the given pattern.
"""
custom_args = self._create_custom_request_arguments()
Expand All @@ -330,7 +331,7 @@ def list(self, name_pattern: str, return_attributes: bool = False) -> List[Dict]
custom_args["headers"]["X-IBM-Attributes"] = "base"

response_json = self.request_handler.perform_request("GET", custom_args)
return response_json
return DatasetListResponse(response_json, return_attributes)

def list_members(
self,
Expand All @@ -339,7 +340,7 @@ def list_members(
member_start: Optional[str] = None,
limit: int = 1000,
attributes: str = "member",
) -> dict:
) -> MemberListResponse:
"""
Retrieve the list of members on a given PDS/PDSE.
Expand All @@ -358,7 +359,7 @@ def list_members(
Returns
-------
dict
MemberListResponse
A JSON with a list of members from a given PDS/PDSE
"""
custom_args = self._create_custom_request_arguments()
Expand All @@ -372,7 +373,7 @@ def list_members(
custom_args["headers"]["X-IBM-Max-Items"] = "{}".format(limit)
custom_args["headers"]["X-IBM-Attributes"] = attributes
response_json = self.request_handler.perform_request("GET", custom_args)
return response_json["items"] # type: ignore
return MemberListResponse(response_json, (attributes == "base"))

def copy_data_set_or_member(
self,
Expand Down
10 changes: 7 additions & 3 deletions src/zos_files/zowe/zos_files_for_zowe_sdk/file_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from zowe.core_for_zowe_sdk import SdkApi
from zowe.zos_files_for_zowe_sdk import constants, exceptions

from .response import FileSystemListResponse

_ZOWE_FILES_DEFAULT_ENCODING = constants.zos_file_constants["ZoweFilesDefaultEncoding"]


Expand Down Expand Up @@ -150,7 +152,9 @@ def unmount(self, file_system_name: str, options: dict = {}, encoding: str = _ZO
response_json = self.request_handler.perform_request("PUT", custom_args, expected_code=[204])
return response_json

def list(self, file_path_name: Optional[str] = None, file_system_name: Optional[str] = None) -> dict:
def list(
self, file_path_name: Optional[str] = None, file_system_name: Optional[str] = None
) -> FileSystemListResponse:
"""
List all mounted filesystems.
Expand All @@ -166,12 +170,12 @@ def list(self, file_path_name: Optional[str] = None, file_system_name: Optional[
Returns
-------
dict
FileSystemListResponse
A JSON containing the result of the operation
"""
custom_args = self._create_custom_request_arguments()

custom_args["params"] = {"path": file_path_name, "fsname": file_system_name}
custom_args["url"] = "{}mfs".format(self._request_endpoint)
response_json = self.request_handler.perform_request("GET", custom_args, expected_code=[200])
return response_json
return FileSystemListResponse(response_json)
14 changes: 14 additions & 0 deletions src/zos_files/zowe/zos_files_for_zowe_sdk/response/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Zowe Python Client SDK.
This program and the accompanying materials are made available under the terms of the
Eclipse Public License v2.0 which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html
SPDX-License-Identifier: EPL-2.0
Copyright Contributors to the Zowe Project.
"""
from .datasets import DatasetListResponse, MemberListResponse
from .file_system import FileSystemListResponse
from .uss import USSListResponse
Loading

0 comments on commit 66b711f

Please sign in to comment.