Py4HEAppE 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- __init__.py +1 -0
- py4heappe/__init__.py +1 -0
- py4heappe/cli/__init__.py +1 -0
- py4heappe/cli/auth.py +153 -0
- py4heappe/cli/command_template.py +370 -0
- py4heappe/cli/configuration.py +65 -0
- py4heappe/cli/information.py +163 -0
- py4heappe/cli/job_management.py +211 -0
- py4heappe/cli/report.py +173 -0
- py4heappe/core/__init__.py +167 -0
- py4heappe/core/api/__init__.py +12 -0
- py4heappe/core/api/cluster_information_api.py +308 -0
- py4heappe/core/api/data_transfer_api.py +405 -0
- py4heappe/core/api/file_transfer_api.py +498 -0
- py4heappe/core/api/job_management_api.py +866 -0
- py4heappe/core/api/job_reporting_api.py +692 -0
- py4heappe/core/api/management_api.py +2540 -0
- py4heappe/core/api/user_and_limitation_management_api.py +676 -0
- py4heappe/core/api_client.py +632 -0
- py4heappe/core/base/__init__.py +1 -0
- py4heappe/core/base/exceptions.py +41 -0
- py4heappe/core/base/logger.py +11 -0
- py4heappe/core/base/utils.py +43 -0
- py4heappe/core/configuration.py +247 -0
- py4heappe/core/models/__init__.py +155 -0
- py4heappe/core/models/adaptor_user.py +398 -0
- py4heappe/core/models/adaptor_user_group.py +268 -0
- py4heappe/core/models/adaptor_user_role.py +242 -0
- py4heappe/core/models/adaptor_user_role_ext.py +138 -0
- py4heappe/core/models/adaptor_user_role_type.py +95 -0
- py4heappe/core/models/adaptor_user_type.py +91 -0
- py4heappe/core/models/adaptor_user_user_group_role.py +320 -0
- py4heappe/core/models/allocated_nodes_ips_model.py +136 -0
- py4heappe/core/models/authenticate_lexis_token_model.py +110 -0
- py4heappe/core/models/authenticate_user_digital_signature_model.py +110 -0
- py4heappe/core/models/authenticate_user_open_id_model.py +110 -0
- py4heappe/core/models/authenticate_user_open_id_open_stack_model.py +136 -0
- py4heappe/core/models/authenticate_user_password_model.py +110 -0
- py4heappe/core/models/authentication_credentials.py +110 -0
- py4heappe/core/models/bad_request_result.py +110 -0
- py4heappe/core/models/cancel_job_model.py +136 -0
- py4heappe/core/models/cluster.py +478 -0
- py4heappe/core/models/cluster_authentication_credentials.py +375 -0
- py4heappe/core/models/cluster_authentication_credentials_auth_type.py +97 -0
- py4heappe/core/models/cluster_connection_protocol.py +91 -0
- py4heappe/core/models/cluster_detailed_report_ext.py +214 -0
- py4heappe/core/models/cluster_ext.py +188 -0
- py4heappe/core/models/cluster_init_report_ext.py +136 -0
- py4heappe/core/models/cluster_node_type.py +528 -0
- py4heappe/core/models/cluster_node_type_detailed_report_ext.py +240 -0
- py4heappe/core/models/cluster_node_type_ext.py +292 -0
- py4heappe/core/models/cluster_node_type_for_task_ext.py +188 -0
- py4heappe/core/models/cluster_node_type_report_ext.py +214 -0
- py4heappe/core/models/cluster_node_type_requested_group.py +136 -0
- py4heappe/core/models/cluster_node_type_resource_usage_ext.py +292 -0
- py4heappe/core/models/cluster_node_usage_ext.py +318 -0
- py4heappe/core/models/cluster_project.py +347 -0
- py4heappe/core/models/cluster_project_credential.py +294 -0
- py4heappe/core/models/cluster_proxy_connection.py +243 -0
- py4heappe/core/models/cluster_proxy_connection_ext.py +214 -0
- py4heappe/core/models/cluster_report_ext.py +215 -0
- py4heappe/core/models/command_template.py +557 -0
- py4heappe/core/models/command_template_ext.py +240 -0
- py4heappe/core/models/command_template_parameter.py +347 -0
- py4heappe/core/models/command_template_parameter_ext.py +136 -0
- py4heappe/core/models/command_template_parameter_value_ext.py +136 -0
- py4heappe/core/models/contact.py +269 -0
- py4heappe/core/models/copy_job_data_from_temp_model.py +162 -0
- py4heappe/core/models/copy_job_data_to_temp_model.py +162 -0
- py4heappe/core/models/create_command_inner_template_parameter_model.py +162 -0
- py4heappe/core/models/create_command_template_from_generic_model.py +292 -0
- py4heappe/core/models/create_command_template_model.py +318 -0
- py4heappe/core/models/create_command_template_parameter_model.py +214 -0
- py4heappe/core/models/create_job_by_project_model.py +136 -0
- py4heappe/core/models/create_project_assignment_to_cluster_model.py +188 -0
- py4heappe/core/models/create_project_model.py +318 -0
- py4heappe/core/models/create_secure_shell_key_model.py +162 -0
- py4heappe/core/models/create_secure_shell_key_model_obsolete.py +188 -0
- py4heappe/core/models/current_cluster_node_usage_model.py +136 -0
- py4heappe/core/models/current_info_for_job_model.py +136 -0
- py4heappe/core/models/data_transfer_method_ext.py +188 -0
- py4heappe/core/models/delete_job_model.py +136 -0
- py4heappe/core/models/deployment_type_ext.py +91 -0
- py4heappe/core/models/digital_signature_credentials_ext.py +162 -0
- py4heappe/core/models/download_file_from_cluster_model.py +162 -0
- py4heappe/core/models/download_parts_of_job_files_from_cluster_model.py +162 -0
- py4heappe/core/models/end_data_transfer_model.py +136 -0
- py4heappe/core/models/end_file_transfer_model.py +162 -0
- py4heappe/core/models/environment_variable_ext.py +136 -0
- py4heappe/core/models/extended_command_template_ext.py +370 -0
- py4heappe/core/models/extended_command_template_parameter_ext.py +188 -0
- py4heappe/core/models/extended_project_info_ext.py +318 -0
- py4heappe/core/models/file_information_ext.py +136 -0
- py4heappe/core/models/file_transfer_cipher_type.py +94 -0
- py4heappe/core/models/file_transfer_cipher_type_ext.py +93 -0
- py4heappe/core/models/file_transfer_key_credentials_ext.py +240 -0
- py4heappe/core/models/file_transfer_method.py +294 -0
- py4heappe/core/models/file_transfer_method_ext.py +240 -0
- py4heappe/core/models/file_transfer_protocol.py +91 -0
- py4heappe/core/models/file_transfer_protocol_ext.py +91 -0
- py4heappe/core/models/get_command_template_parameters_name_model.py +188 -0
- py4heappe/core/models/get_current_usage_and_limitations_for_current_user_model.py +110 -0
- py4heappe/core/models/get_data_transfer_method_model.py +188 -0
- py4heappe/core/models/get_file_transfer_method_model.py +136 -0
- py4heappe/core/models/http_get_to_job_node_model.py +241 -0
- py4heappe/core/models/http_header_ext.py +136 -0
- py4heappe/core/models/http_post_to_job_node_model.py +267 -0
- py4heappe/core/models/initialize_cluster_script_directory_model.py +162 -0
- py4heappe/core/models/instance_information_ext.py +344 -0
- py4heappe/core/models/job_detailed_report_ext.py +318 -0
- py4heappe/core/models/job_file_content_ext.py +214 -0
- py4heappe/core/models/job_report_ext.py +188 -0
- py4heappe/core/models/job_specification_by_project_ext.py +448 -0
- py4heappe/core/models/job_specification_ext.py +448 -0
- py4heappe/core/models/job_state_aggregation_report_ext.py +162 -0
- py4heappe/core/models/job_state_ext.py +96 -0
- py4heappe/core/models/lexis_credentials_ext.py +137 -0
- py4heappe/core/models/list_changed_files_for_job_model.py +136 -0
- py4heappe/core/models/list_jobs_for_current_user_model.py +110 -0
- py4heappe/core/models/modify_command_template_from_generic_model.py +292 -0
- py4heappe/core/models/modify_command_template_model.py +292 -0
- py4heappe/core/models/modify_command_template_parameter_model.py +214 -0
- py4heappe/core/models/modify_project_assignment_to_cluster_model.py +188 -0
- py4heappe/core/models/modify_project_model.py +292 -0
- py4heappe/core/models/node_used_cores_and_limitation_ext.py +110 -0
- py4heappe/core/models/open_id_credentials_ext.py +137 -0
- py4heappe/core/models/open_stack_application_credentials_ext.py +136 -0
- py4heappe/core/models/password_credentials_ext.py +136 -0
- py4heappe/core/models/problem_details.py +89 -0
- py4heappe/core/models/project.py +482 -0
- py4heappe/core/models/project_contact.py +215 -0
- py4heappe/core/models/project_detailed_report_ext.py +292 -0
- py4heappe/core/models/project_ext.py +266 -0
- py4heappe/core/models/project_for_task_ext.py +214 -0
- py4heappe/core/models/project_list_report_ext.py +214 -0
- py4heappe/core/models/project_reference_ext.py +137 -0
- py4heappe/core/models/project_report_ext.py +240 -0
- py4heappe/core/models/project_resource_usage_ext.py +266 -0
- py4heappe/core/models/proxy_type.py +91 -0
- py4heappe/core/models/proxy_type_ext.py +91 -0
- py4heappe/core/models/public_key_ext.py +188 -0
- py4heappe/core/models/recreate_secure_shell_key_model.py +214 -0
- py4heappe/core/models/regenerate_secure_shell_key_model.py +188 -0
- py4heappe/core/models/regenerate_secure_shell_key_model_obsolete.py +188 -0
- py4heappe/core/models/remove_command_template_model.py +136 -0
- py4heappe/core/models/remove_command_template_parameter_model.py +136 -0
- py4heappe/core/models/remove_project_assignment_to_cluster_model.py +162 -0
- py4heappe/core/models/remove_project_model.py +136 -0
- py4heappe/core/models/remove_secure_shell_key_model.py +162 -0
- py4heappe/core/models/remove_secure_shell_key_model_obsolete.py +162 -0
- py4heappe/core/models/resource_allocation_type_ext.py +91 -0
- py4heappe/core/models/resource_limitation_ext.py +136 -0
- py4heappe/core/models/resource_usage_ext.py +163 -0
- py4heappe/core/models/scheduler_type.py +92 -0
- py4heappe/core/models/ssh_key_user_credentials_model.py +136 -0
- py4heappe/core/models/submit_job_model.py +136 -0
- py4heappe/core/models/submitted_job_info_ext.py +318 -0
- py4heappe/core/models/submitted_task_info_ext.py +370 -0
- py4heappe/core/models/synchronizable_files_ext.py +92 -0
- py4heappe/core/models/task_detailed_report_ext.py +318 -0
- py4heappe/core/models/task_file_offset_ext.py +162 -0
- py4heappe/core/models/task_paralization_parameter_ext.py +162 -0
- py4heappe/core/models/task_priority_ext.py +97 -0
- py4heappe/core/models/task_report_ext.py +266 -0
- py4heappe/core/models/task_specification_ext.py +682 -0
- py4heappe/core/models/task_state_ext.py +95 -0
- py4heappe/core/models/test_cluster_access_for_account_model.py +162 -0
- py4heappe/core/models/test_cluster_access_for_account_model_obsolete.py +162 -0
- py4heappe/core/models/unauthorized_result.py +110 -0
- py4heappe/core/models/usage_type.py +90 -0
- py4heappe/core/models/usage_type_ext.py +90 -0
- py4heappe/core/models/user_group_detailed_report_ext.py +240 -0
- py4heappe/core/models/user_group_list_report_ext.py +240 -0
- py4heappe/core/models/user_group_report_ext.py +240 -0
- py4heappe/core/models/version_information_ext.py +162 -0
- py4heappe/core/rest.py +311 -0
- py4heappe-1.0.0.dist-info/METADATA +147 -0
- py4heappe-1.0.0.dist-info/RECORD +183 -0
- py4heappe-1.0.0.dist-info/WHEEL +5 -0
- py4heappe-1.0.0.dist-info/entry_points.txt +2 -0
- py4heappe-1.0.0.dist-info/licenses/LICENSE +20 -0
- py4heappe-1.0.0.dist-info/top_level.txt +3 -0
- py4heappe_cli.py +22 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
HEAppE Web API
|
|
5
|
+
|
|
6
|
+
HEAppE middleware API v4.2.1 # noqa: E501
|
|
7
|
+
|
|
8
|
+
OpenAPI spec version: v4.2.1
|
|
9
|
+
Contact: support.heappe@it4i.cz
|
|
10
|
+
Generated by: https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import pprint
|
|
14
|
+
import re # noqa: F401
|
|
15
|
+
|
|
16
|
+
import six
|
|
17
|
+
|
|
18
|
+
class VersionInformationExt(object):
|
|
19
|
+
"""NOTE: This class is auto generated by the swagger code generator program.
|
|
20
|
+
|
|
21
|
+
Do not edit the class manually.
|
|
22
|
+
"""
|
|
23
|
+
"""
|
|
24
|
+
Attributes:
|
|
25
|
+
swagger_types (dict): The key is attribute name
|
|
26
|
+
and the value is attribute type.
|
|
27
|
+
attribute_map (dict): The key is attribute name
|
|
28
|
+
and the value is json key in definition.
|
|
29
|
+
"""
|
|
30
|
+
swagger_types = {
|
|
31
|
+
'name': 'str',
|
|
32
|
+
'description': 'str',
|
|
33
|
+
'version': 'str'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
attribute_map = {
|
|
37
|
+
'name': 'Name',
|
|
38
|
+
'description': 'Description',
|
|
39
|
+
'version': 'Version'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def __init__(self, name=None, description=None, version=None): # noqa: E501
|
|
43
|
+
"""VersionInformationExt - a model defined in Swagger""" # noqa: E501
|
|
44
|
+
self._name = None
|
|
45
|
+
self._description = None
|
|
46
|
+
self._version = None
|
|
47
|
+
self.discriminator = None
|
|
48
|
+
if name is not None:
|
|
49
|
+
self.name = name
|
|
50
|
+
if description is not None:
|
|
51
|
+
self.description = description
|
|
52
|
+
if version is not None:
|
|
53
|
+
self.version = version
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def name(self):
|
|
57
|
+
"""Gets the name of this VersionInformationExt. # noqa: E501
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
:return: The name of this VersionInformationExt. # noqa: E501
|
|
61
|
+
:rtype: str
|
|
62
|
+
"""
|
|
63
|
+
return self._name
|
|
64
|
+
|
|
65
|
+
@name.setter
|
|
66
|
+
def name(self, name):
|
|
67
|
+
"""Sets the name of this VersionInformationExt.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
:param name: The name of this VersionInformationExt. # noqa: E501
|
|
71
|
+
:type: str
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
self._name = name
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def description(self):
|
|
78
|
+
"""Gets the description of this VersionInformationExt. # noqa: E501
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
:return: The description of this VersionInformationExt. # noqa: E501
|
|
82
|
+
:rtype: str
|
|
83
|
+
"""
|
|
84
|
+
return self._description
|
|
85
|
+
|
|
86
|
+
@description.setter
|
|
87
|
+
def description(self, description):
|
|
88
|
+
"""Sets the description of this VersionInformationExt.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
:param description: The description of this VersionInformationExt. # noqa: E501
|
|
92
|
+
:type: str
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
self._description = description
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def version(self):
|
|
99
|
+
"""Gets the version of this VersionInformationExt. # noqa: E501
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
:return: The version of this VersionInformationExt. # noqa: E501
|
|
103
|
+
:rtype: str
|
|
104
|
+
"""
|
|
105
|
+
return self._version
|
|
106
|
+
|
|
107
|
+
@version.setter
|
|
108
|
+
def version(self, version):
|
|
109
|
+
"""Sets the version of this VersionInformationExt.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
:param version: The version of this VersionInformationExt. # noqa: E501
|
|
113
|
+
:type: str
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
self._version = version
|
|
117
|
+
|
|
118
|
+
def to_dict(self):
|
|
119
|
+
"""Returns the model properties as a dict"""
|
|
120
|
+
result = {}
|
|
121
|
+
|
|
122
|
+
for attr, _ in six.iteritems(self.swagger_types):
|
|
123
|
+
value = getattr(self, attr)
|
|
124
|
+
if isinstance(value, list):
|
|
125
|
+
result[attr] = list(map(
|
|
126
|
+
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
|
127
|
+
value
|
|
128
|
+
))
|
|
129
|
+
elif hasattr(value, "to_dict"):
|
|
130
|
+
result[attr] = value.to_dict()
|
|
131
|
+
elif isinstance(value, dict):
|
|
132
|
+
result[attr] = dict(map(
|
|
133
|
+
lambda item: (item[0], item[1].to_dict())
|
|
134
|
+
if hasattr(item[1], "to_dict") else item,
|
|
135
|
+
value.items()
|
|
136
|
+
))
|
|
137
|
+
else:
|
|
138
|
+
result[attr] = value
|
|
139
|
+
if issubclass(VersionInformationExt, dict):
|
|
140
|
+
for key, value in self.items():
|
|
141
|
+
result[key] = value
|
|
142
|
+
|
|
143
|
+
return result
|
|
144
|
+
|
|
145
|
+
def to_str(self):
|
|
146
|
+
"""Returns the string representation of the model"""
|
|
147
|
+
return pprint.pformat(self.to_dict())
|
|
148
|
+
|
|
149
|
+
def __repr__(self):
|
|
150
|
+
"""For `print` and `pprint`"""
|
|
151
|
+
return self.to_str()
|
|
152
|
+
|
|
153
|
+
def __eq__(self, other):
|
|
154
|
+
"""Returns true if both objects are equal"""
|
|
155
|
+
if not isinstance(other, VersionInformationExt):
|
|
156
|
+
return False
|
|
157
|
+
|
|
158
|
+
return self.__dict__ == other.__dict__
|
|
159
|
+
|
|
160
|
+
def __ne__(self, other):
|
|
161
|
+
"""Returns true if both objects are not equal"""
|
|
162
|
+
return not self == other
|
py4heappe/core/rest.py
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
HEAppE Web API
|
|
5
|
+
|
|
6
|
+
HEAppE middleware API v4.2.1 # noqa: E501
|
|
7
|
+
|
|
8
|
+
OpenAPI spec version: v4.2.1
|
|
9
|
+
Contact: support.heappe@it4i.cz
|
|
10
|
+
Generated by: https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import absolute_import
|
|
14
|
+
|
|
15
|
+
import io
|
|
16
|
+
import json
|
|
17
|
+
import logging
|
|
18
|
+
import re
|
|
19
|
+
import ssl
|
|
20
|
+
|
|
21
|
+
import certifi
|
|
22
|
+
# python 2 and python 3 compatibility library
|
|
23
|
+
import six
|
|
24
|
+
from six.moves.urllib.parse import urlencode
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
import urllib3
|
|
28
|
+
except ImportError:
|
|
29
|
+
raise ImportError('Swagger python client requires urllib3.')
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class RESTResponse(io.IOBase):
|
|
36
|
+
|
|
37
|
+
def __init__(self, resp):
|
|
38
|
+
self.urllib3_response = resp
|
|
39
|
+
self.status = resp.status
|
|
40
|
+
self.reason = resp.reason
|
|
41
|
+
self.data = resp.data
|
|
42
|
+
|
|
43
|
+
def getheaders(self):
|
|
44
|
+
"""Returns a dictionary of the response headers."""
|
|
45
|
+
return self.urllib3_response.headers
|
|
46
|
+
|
|
47
|
+
def getheader(self, name, default=None):
|
|
48
|
+
"""Returns a given response header."""
|
|
49
|
+
return self.urllib3_response.headers.get(name, default)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class RESTClientObject(object):
|
|
53
|
+
|
|
54
|
+
def __init__(self, configuration, pools_size=4, maxsize=None):
|
|
55
|
+
# cert_reqs
|
|
56
|
+
if configuration.verify_ssl:
|
|
57
|
+
cert_reqs = ssl.CERT_REQUIRED
|
|
58
|
+
else:
|
|
59
|
+
cert_reqs = ssl.CERT_NONE
|
|
60
|
+
|
|
61
|
+
# ca_certs
|
|
62
|
+
if configuration.ssl_ca_cert:
|
|
63
|
+
ca_certs = configuration.ssl_ca_cert
|
|
64
|
+
else:
|
|
65
|
+
# if not set certificate file, use Mozilla's root certificates.
|
|
66
|
+
ca_certs = certifi.where()
|
|
67
|
+
|
|
68
|
+
addition_pool_args = {}
|
|
69
|
+
if configuration.assert_hostname is not None:
|
|
70
|
+
addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
|
|
71
|
+
|
|
72
|
+
if maxsize is None:
|
|
73
|
+
if configuration.connection_pool_maxsize is not None:
|
|
74
|
+
maxsize = configuration.connection_pool_maxsize
|
|
75
|
+
else:
|
|
76
|
+
maxsize = 4
|
|
77
|
+
|
|
78
|
+
# https pool manager
|
|
79
|
+
if configuration.proxy:
|
|
80
|
+
self.pool_manager = urllib3.ProxyManager(
|
|
81
|
+
num_pools=pools_size,
|
|
82
|
+
maxsize=maxsize,
|
|
83
|
+
cert_reqs=cert_reqs,
|
|
84
|
+
ca_certs=ca_certs,
|
|
85
|
+
cert_file=configuration.cert_file,
|
|
86
|
+
key_file=configuration.key_file,
|
|
87
|
+
proxy_url=configuration.proxy,
|
|
88
|
+
**addition_pool_args
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
self.pool_manager = urllib3.PoolManager(
|
|
92
|
+
num_pools=pools_size,
|
|
93
|
+
maxsize=maxsize,
|
|
94
|
+
cert_reqs=cert_reqs,
|
|
95
|
+
ca_certs=ca_certs,
|
|
96
|
+
cert_file=configuration.cert_file,
|
|
97
|
+
key_file=configuration.key_file,
|
|
98
|
+
**addition_pool_args
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def request(self, method, url, query_params=None, headers=None,
|
|
102
|
+
body=None, post_params=None, _preload_content=True,
|
|
103
|
+
_request_timeout=None):
|
|
104
|
+
"""Perform requests.
|
|
105
|
+
|
|
106
|
+
:param method: http request method
|
|
107
|
+
:param url: http request url
|
|
108
|
+
:param query_params: query parameters in the url
|
|
109
|
+
:param headers: http request headers
|
|
110
|
+
:param body: request json body, for `application/json`
|
|
111
|
+
:param post_params: request post parameters,
|
|
112
|
+
`application/x-www-form-urlencoded`
|
|
113
|
+
and `multipart/form-data`
|
|
114
|
+
:param _preload_content: if False, the urllib3.HTTPResponse object will
|
|
115
|
+
be returned without reading/decoding response
|
|
116
|
+
data. Default is True.
|
|
117
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
118
|
+
number provided, it will be total request
|
|
119
|
+
timeout. It can also be a pair (tuple) of
|
|
120
|
+
(connection, read) timeouts.
|
|
121
|
+
"""
|
|
122
|
+
method = method.upper()
|
|
123
|
+
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
|
|
124
|
+
'PATCH', 'OPTIONS']
|
|
125
|
+
|
|
126
|
+
if post_params and body:
|
|
127
|
+
raise ValueError(
|
|
128
|
+
"body parameter cannot be used with post_params parameter."
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
post_params = post_params or {}
|
|
132
|
+
headers = headers or {}
|
|
133
|
+
|
|
134
|
+
timeout = None
|
|
135
|
+
if _request_timeout:
|
|
136
|
+
if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821
|
|
137
|
+
timeout = urllib3.Timeout(total=_request_timeout)
|
|
138
|
+
elif (isinstance(_request_timeout, tuple) and
|
|
139
|
+
len(_request_timeout) == 2):
|
|
140
|
+
timeout = urllib3.Timeout(
|
|
141
|
+
connect=_request_timeout[0], read=_request_timeout[1])
|
|
142
|
+
|
|
143
|
+
if 'Content-Type' not in headers:
|
|
144
|
+
headers['Content-Type'] = 'application/json'
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
|
|
148
|
+
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
|
|
149
|
+
if query_params:
|
|
150
|
+
url += '?' + urlencode(query_params)
|
|
151
|
+
if re.search('json', headers['Content-Type'], re.IGNORECASE):
|
|
152
|
+
request_body = '{}'
|
|
153
|
+
if body is not None:
|
|
154
|
+
request_body = json.dumps(body)
|
|
155
|
+
r = self.pool_manager.request(
|
|
156
|
+
method, url,
|
|
157
|
+
body=request_body,
|
|
158
|
+
preload_content=_preload_content,
|
|
159
|
+
timeout=timeout,
|
|
160
|
+
headers=headers)
|
|
161
|
+
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
|
|
162
|
+
r = self.pool_manager.request(
|
|
163
|
+
method, url,
|
|
164
|
+
fields=post_params,
|
|
165
|
+
encode_multipart=False,
|
|
166
|
+
preload_content=_preload_content,
|
|
167
|
+
timeout=timeout,
|
|
168
|
+
headers=headers)
|
|
169
|
+
elif headers['Content-Type'] == 'multipart/form-data':
|
|
170
|
+
# must del headers['Content-Type'], or the correct
|
|
171
|
+
# Content-Type which generated by urllib3 will be
|
|
172
|
+
# overwritten.
|
|
173
|
+
del headers['Content-Type']
|
|
174
|
+
r = self.pool_manager.request(
|
|
175
|
+
method, url,
|
|
176
|
+
fields=post_params,
|
|
177
|
+
encode_multipart=True,
|
|
178
|
+
preload_content=_preload_content,
|
|
179
|
+
timeout=timeout,
|
|
180
|
+
headers=headers)
|
|
181
|
+
# Pass a `string` parameter directly in the body to support
|
|
182
|
+
# other content types than Json when `body` argument is
|
|
183
|
+
# provided in serialized form
|
|
184
|
+
elif isinstance(body, str):
|
|
185
|
+
request_body = body
|
|
186
|
+
r = self.pool_manager.request(
|
|
187
|
+
method, url,
|
|
188
|
+
body=request_body,
|
|
189
|
+
preload_content=_preload_content,
|
|
190
|
+
timeout=timeout,
|
|
191
|
+
headers=headers)
|
|
192
|
+
else:
|
|
193
|
+
# Cannot generate the request from given parameters
|
|
194
|
+
msg = """Cannot prepare a request message for provided
|
|
195
|
+
arguments. Please check that your arguments match
|
|
196
|
+
declared content type."""
|
|
197
|
+
raise ApiException(status=0, reason=msg)
|
|
198
|
+
# For `GET`, `HEAD`
|
|
199
|
+
else:
|
|
200
|
+
r = self.pool_manager.request(method, url,
|
|
201
|
+
fields=query_params,
|
|
202
|
+
preload_content=_preload_content,
|
|
203
|
+
timeout=timeout,
|
|
204
|
+
headers=headers)
|
|
205
|
+
except urllib3.exceptions.SSLError as e:
|
|
206
|
+
msg = "{0}\n{1}".format(type(e).__name__, str(e))
|
|
207
|
+
raise ApiException(status=0, reason=msg)
|
|
208
|
+
|
|
209
|
+
if _preload_content:
|
|
210
|
+
r = RESTResponse(r)
|
|
211
|
+
|
|
212
|
+
# log response body
|
|
213
|
+
logger.debug("response body: %s", r.data)
|
|
214
|
+
|
|
215
|
+
if not 200 <= r.status <= 299:
|
|
216
|
+
raise ApiException(http_resp=r)
|
|
217
|
+
|
|
218
|
+
return r
|
|
219
|
+
|
|
220
|
+
def GET(self, url, headers=None, query_params=None, _preload_content=True,
|
|
221
|
+
_request_timeout=None):
|
|
222
|
+
return self.request("GET", url,
|
|
223
|
+
headers=headers,
|
|
224
|
+
_preload_content=_preload_content,
|
|
225
|
+
_request_timeout=_request_timeout,
|
|
226
|
+
query_params=query_params)
|
|
227
|
+
|
|
228
|
+
def HEAD(self, url, headers=None, query_params=None, _preload_content=True,
|
|
229
|
+
_request_timeout=None):
|
|
230
|
+
return self.request("HEAD", url,
|
|
231
|
+
headers=headers,
|
|
232
|
+
_preload_content=_preload_content,
|
|
233
|
+
_request_timeout=_request_timeout,
|
|
234
|
+
query_params=query_params)
|
|
235
|
+
|
|
236
|
+
def OPTIONS(self, url, headers=None, query_params=None, post_params=None,
|
|
237
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
238
|
+
return self.request("OPTIONS", url,
|
|
239
|
+
headers=headers,
|
|
240
|
+
query_params=query_params,
|
|
241
|
+
post_params=post_params,
|
|
242
|
+
_preload_content=_preload_content,
|
|
243
|
+
_request_timeout=_request_timeout,
|
|
244
|
+
body=body)
|
|
245
|
+
|
|
246
|
+
def DELETE(self, url, headers=None, query_params=None, body=None,
|
|
247
|
+
_preload_content=True, _request_timeout=None):
|
|
248
|
+
return self.request("DELETE", url,
|
|
249
|
+
headers=headers,
|
|
250
|
+
query_params=query_params,
|
|
251
|
+
_preload_content=_preload_content,
|
|
252
|
+
_request_timeout=_request_timeout,
|
|
253
|
+
body=body)
|
|
254
|
+
|
|
255
|
+
def POST(self, url, headers=None, query_params=None, post_params=None,
|
|
256
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
257
|
+
return self.request("POST", url,
|
|
258
|
+
headers=headers,
|
|
259
|
+
query_params=query_params,
|
|
260
|
+
post_params=post_params,
|
|
261
|
+
_preload_content=_preload_content,
|
|
262
|
+
_request_timeout=_request_timeout,
|
|
263
|
+
body=body)
|
|
264
|
+
|
|
265
|
+
def PUT(self, url, headers=None, query_params=None, post_params=None,
|
|
266
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
267
|
+
return self.request("PUT", url,
|
|
268
|
+
headers=headers,
|
|
269
|
+
query_params=query_params,
|
|
270
|
+
post_params=post_params,
|
|
271
|
+
_preload_content=_preload_content,
|
|
272
|
+
_request_timeout=_request_timeout,
|
|
273
|
+
body=body)
|
|
274
|
+
|
|
275
|
+
def PATCH(self, url, headers=None, query_params=None, post_params=None,
|
|
276
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
277
|
+
return self.request("PATCH", url,
|
|
278
|
+
headers=headers,
|
|
279
|
+
query_params=query_params,
|
|
280
|
+
post_params=post_params,
|
|
281
|
+
_preload_content=_preload_content,
|
|
282
|
+
_request_timeout=_request_timeout,
|
|
283
|
+
body=body)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class ApiException(Exception):
|
|
287
|
+
|
|
288
|
+
def __init__(self, status=None, reason=None, http_resp=None):
|
|
289
|
+
if http_resp:
|
|
290
|
+
self.status = http_resp.status
|
|
291
|
+
self.reason = http_resp.reason
|
|
292
|
+
self.body = http_resp.data
|
|
293
|
+
self.headers = http_resp.getheaders()
|
|
294
|
+
else:
|
|
295
|
+
self.status = status
|
|
296
|
+
self.reason = reason
|
|
297
|
+
self.body = None
|
|
298
|
+
self.headers = None
|
|
299
|
+
|
|
300
|
+
def __str__(self):
|
|
301
|
+
"""Custom error messages for exception"""
|
|
302
|
+
error_message = "({0})\n"\
|
|
303
|
+
"Reason: {1}\n".format(self.status, self.reason)
|
|
304
|
+
if self.headers:
|
|
305
|
+
error_message += "HTTP response headers: {0}\n".format(
|
|
306
|
+
self.headers)
|
|
307
|
+
|
|
308
|
+
if self.body:
|
|
309
|
+
error_message += "HTTP response body: {0}\n".format(self.body)
|
|
310
|
+
|
|
311
|
+
return error_message
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Py4HEAppE
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Py4HEAppE is client library for easy access to HEAppE Middleware
|
|
5
|
+
Author-email: IT4Innovations <support.heappe@it4i.cz>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/It4innovations/Py4HEAppE
|
|
8
|
+
Project-URL: Repository, https://github.com/It4innovations/Py4HEAppE.git
|
|
9
|
+
Project-URL: Issues, https://github.com/It4innovations/Py4HEAppE/issues
|
|
10
|
+
Keywords: LEXIS,HEAppE
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: paramiko==3.5.0
|
|
17
|
+
Requires-Dist: scp==0.15.0
|
|
18
|
+
Requires-Dist: urllib3==2.2.3
|
|
19
|
+
Requires-Dist: certifi==2024.8.30
|
|
20
|
+
Requires-Dist: six==1.16.0
|
|
21
|
+
Requires-Dist: typer==0.13.1
|
|
22
|
+
Requires-Dist: python-dotenv==1.0.1
|
|
23
|
+
Requires-Dist: validators==0.34.0
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
<img align="right" width="35%" src="https://raw.githubusercontent.com/It4innovations/Py4HEAppE/refs/heads/master/docs/imgs/logo.png">
|
|
27
|
+
|
|
28
|
+
# Py4HEAppE (Python for HEAppE Middleware)
|
|
29
|
+
|
|
30
|
+
Py4HEAppE simplifies access to the [HEAppE](https://heappe.eu) features by providing a high-level Python interface that abstracts away the complexities of direct API interactions. This allows users to focus on their core tasks without worrying about the underlying details of API communication. It can be usable in <b>two modes</b> depends what the end-user needs:
|
|
31
|
+
- HEAppE CLI Commands
|
|
32
|
+
- HEAppE API Wrapper Library
|
|
33
|
+
|
|
34
|
+
## Key Benefits
|
|
35
|
+
|
|
36
|
+
### Ease of Use:
|
|
37
|
+
Py4HEAppE provides a straightforward and intuitive interface for interacting with the HEAppE API. Users can perform complex operations with simple function calls.
|
|
38
|
+
|
|
39
|
+
### Abstraction:
|
|
40
|
+
The library abstracts the intricacies of the HEAppE API, allowing users to work with high-level concepts and operations.
|
|
41
|
+
|
|
42
|
+
### Efficiency:
|
|
43
|
+
By using Py4HEAppE, users can quickly integrate HEAppE functionalities into their Python applications, reducing development time and effort.
|
|
44
|
+
|
|
45
|
+
### Consistency:
|
|
46
|
+
The library ensures consistent and reliable communication with the HEAppE API, handling errors and edge cases gracefully.
|
|
47
|
+
|
|
48
|
+
<!-- GETTING STARTED -->
|
|
49
|
+
## Getting Started
|
|
50
|
+
|
|
51
|
+
### Prerequisites
|
|
52
|
+
|
|
53
|
+
* Python (version 3.11)
|
|
54
|
+
* Pip (package installer)
|
|
55
|
+
* Access to Deployed HEAppE instance (HEAppE instance URL and HPC project identificator)
|
|
56
|
+
|
|
57
|
+
### Installation
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
pip install py4heappe
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
<b>Note:</b> In some cases, you can obtain a warning message like this <b>"WARNING: The script py4heappe.exe is installed in 'C:\Users\user\AppData\Roaming\Python\Python311\Scripts' which is not on PATH.</b>" If you obtained a similar warning message, it is necessary to add the mentioned path into your operation system <b>PATH</b> variable or use a path with an executable file (i.e. C:\Users\user\AppData\Roaming\Python\Python311\Scripts\py4heappe.exe).
|
|
64
|
+
|
|
65
|
+
## HEAppE CLI
|
|
66
|
+
|
|
67
|
+
The HEAppE CLI (Command Line Interface) provides a convenient way to interact with the HEAppE Middleware directly from your terminal. It allows users to perform various operations such as authentication, job management, and information retrieval without needing to write any code. This makes it an ideal tool for end-users who need to manage HEAppE Instance efficiently.
|
|
68
|
+
|
|
69
|
+
### Usage
|
|
70
|
+
For using HEAppE CLI it is neeaded to initializing Py4HEAppE for usage with a specific HEAppE Instance (It is necessary to call for the first usage). Command requires <b>HPC project accounting string</b> and <b>HEAppE Instance URL</b>.
|
|
71
|
+
|
|
72
|
+
```shell
|
|
73
|
+
# Initial Setup
|
|
74
|
+
py4heappe Conf Init
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
All mentioned functions are aggregated to CLI's specific <b>commands groups (commands aggregations)</b>. To do so, type the following to provide help on how to use managers via CLI.
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
# List of commands groups (commands aggregations)
|
|
81
|
+
py4heappe --help
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Available Commands Groups (commands aggregations):
|
|
85
|
+
|
|
86
|
+
```shell
|
|
87
|
+
# Authentication commands group
|
|
88
|
+
py4heappe Auth --help
|
|
89
|
+
|
|
90
|
+
# Command Template Management commands group
|
|
91
|
+
py4heappe CmdTemp --help
|
|
92
|
+
|
|
93
|
+
# Information commands group
|
|
94
|
+
py4heappe Info --help
|
|
95
|
+
|
|
96
|
+
# Report commands group
|
|
97
|
+
py4heappe Report --help
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
<b>Note:</b> On Windows operation system need to use <b>"py4heappe.exe"</b> instead of <b>"py4heappe"</b>.
|
|
101
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
102
|
+
|
|
103
|
+
## HEAppE API Wrapper Library
|
|
104
|
+
|
|
105
|
+
In this mode, the Py4HEAppE package is used as a wrapper for HEAppE API specification. It allows users to perform various operations from <b>HEAppE API</b>, such as authentication, job management, and information retrieval, without needing to write their API wrapper code. It can be easily integrated with internal <b>Python</b> projects that HEAppE Middleware wants to be used. More information about usability can be found in the section below.
|
|
106
|
+
|
|
107
|
+
### Usage
|
|
108
|
+
|
|
109
|
+
It is required to specify following modules in "requirements.txt" file.
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
paramiko==3.5.0
|
|
113
|
+
scp==0.15.0
|
|
114
|
+
urllib3==2.2.3
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The code snapshot illustrated an example of "how to" obtain cluster information from the HEAppE Instance. For more detailed examples of basic HPC workflow, please refer to the [example.py](https://github.com/It4innovations/Py4HEAppE/blob/master/docs/examples/example.py) file.
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
import json
|
|
121
|
+
import os
|
|
122
|
+
import time
|
|
123
|
+
from io import StringIO
|
|
124
|
+
from pathlib import Path
|
|
125
|
+
|
|
126
|
+
import py4heappe.core as hp
|
|
127
|
+
|
|
128
|
+
print("\nFetching cluster info...")
|
|
129
|
+
lac_body = {
|
|
130
|
+
"_preload_content": False
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
ciEndpoint = hp.ClusterInformationApi(api_instance)
|
|
134
|
+
r = ciEndpoint.heappe_cluster_information_list_available_clusters_get(**lac_body)
|
|
135
|
+
r_data = json.loads(r.data)
|
|
136
|
+
print(json.dumps(r_data, indent = 3))
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
## Acknowledgement
|
|
143
|
+
|
|
144
|
+
e-Infra CZ
|
|
145
|
+
This work was supported by the Ministry of Education, Youth and Sports of the Czech Republic through the e-INFRA CZ (ID:90254)
|
|
146
|
+
|
|
147
|
+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|