Source code for watson_machine_learning_client.runtimes

################################################################################
#
# Licensed Materials - Property of IBM
# (C) Copyright IBM Corp. 2017
# US Government Users Restricted Rights - Use, duplication disclosure restricted
# by GSA ADP Schedule Contract with IBM Corp.
#
################################################################################

from __future__ import print_function
import requests
requests.packages.urllib3.disable_warnings()
import json
import os
from watson_machine_learning_client.utils import INSTANCE_DETAILS_TYPE, RUNTIME_SPEC_DETAILS_TYPE, MODEL_DETAILS_TYPE, LIBRARY_DETAILS_TYPE, FUNCTION_DETAILS_TYPE, STR_TYPE, STR_TYPE_NAME, get_type_of_details, docstring_parameter, str_type_conv, print_text_header_h2, meta_props_str_conv
from watson_machine_learning_client.wml_client_error import WMLClientError
from watson_machine_learning_client.href_definitions import is_uid
from watson_machine_learning_client.wml_resource import WMLResource
from watson_machine_learning_client.metanames import RuntimeMetaNames, LibraryMetaNames
from watson_machine_learning_client.libs.repo.mlrepositoryartifact import MLRepositoryArtifact
from watson_machine_learning_client.libs.repo.mlrepository import MetaProps, MetaNames
from watson_machine_learning_client.href_definitions import API_VERSION, SPACES,PIPELINES, LIBRARIES, EXPERIMENTS, RUNTIMES, DEPLOYMENTS



def LibraryDefinition(name, version, filepath, description=None, platform=None, model_definition=None, custom=None, command=None, tags=None, space_uid=None):
    WMLResource._validate_type(name, 'name', STR_TYPE, True)
    WMLResource._validate_type(version, 'version', STR_TYPE, True)
    WMLResource._validate_type(platform, 'platform', dict, False)
    WMLResource._validate_type(description, 'description', STR_TYPE, False)
    WMLResource._validate_type(filepath, 'filepath', STR_TYPE, True)
    WMLResource._validate_type(model_definition, 'model_definition', bool, False)
    WMLResource._validate_type(custom, 'custom', dict, False)
    WMLResource._validate_type(command, 'command', STR_TYPE, False)
    WMLResource._validate_type(tags, 'tags', dict, False)
    WMLResource._validate_type(space_uid, 'space_uid', STR_TYPE, False)

    definition = {
        'name': name,
        'version': version,
        'filepath': filepath
    }

    if description is not None:
        definition['description'] = description

    if platform is not None:
        definition['platform'] = platform
    if model_definition is not None:
        definition['model_definition'] = model_definition
    if custom is not None:
        definition['custom'] = custom
    if command is not None:
        definition['command'] = command
    if tags is not None:
        definition['tags'] = tags
    if space_uid is not None:
        definition['space_uid'] = space_uid
    return definition


[docs]class Runtimes(WMLResource): """ Creates runtime specifications and associated custom libraries. .. note:: There are a list of pre-defined runtimes available. To see the list of pre-defined runtimes, use:\n >>> client.runtimes.list(pre_defined=True) """ def __init__(self, client): WMLResource.__init__(self, __name__, client) if not client.ICP: Runtimes._validate_type(client.service_instance.details, u'instance_details', dict, True) Runtimes._validate_type_of_details(client.service_instance.details, INSTANCE_DETAILS_TYPE) self.ConfigurationMetaNames = RuntimeMetaNames() self.LibraryMetaNames = LibraryMetaNames() self._ICP = client.ICP def _create_library_from_definition(self, definition, runtime_definition): self._validate_meta_prop(definition, 'name', STR_TYPE, True) self._validate_meta_prop(definition, 'version', STR_TYPE, True) self._validate_meta_prop(definition, 'platform', dict, False) self._validate_meta_prop(definition, 'description', STR_TYPE, False) self._validate_meta_prop(definition, 'filepath', STR_TYPE, True) self._validate_meta_prop(definition, 'model_defintion', bool, False) self._validate_meta_prop(definition, 'custom', dict, False) self._validate_meta_prop(definition, 'command', STR_TYPE, False) self._validate_meta_prop(definition, 'tags', dict, False) self._validate_meta_prop(definition, 'space_uid', STR_TYPE, False) lib_metadata = { self.LibraryMetaNames.NAME: definition['name'], self.LibraryMetaNames.VERSION: definition['version'], self.LibraryMetaNames.PLATFORM: definition['platform'] if 'platform' in definition and definition['platform'] is not None else { "name": runtime_definition[self.ConfigurationMetaNames.PLATFORM]['name'], "versions": [runtime_definition[self.ConfigurationMetaNames.PLATFORM]['version']] }, self.LibraryMetaNames.FILEPATH: definition['filepath'], self.LibraryMetaNames.MODEL_DEFINITION: definition['model_definiton'], self.LibraryMetaNames.COMMAND: definition['command'], self.LibraryMetaNames.CUSTOM: definition['custom'], self.LibraryMetaNames.TAGS: definition['tags'], self.LibraryMetaNames.SPACE_UID: definition['space_uid'], } if 'description' in definition: lib_metadata[self.LibraryMetaNames.DESCRIPTION] = definition['description'] if 'tags' in definition: lib_metadata[self.LibraryMetaNames.TAGS] = definition['tags'] if 'model_definition' in definition: lib_metadata[self.LibraryMetaNames.MODEL_DEFINITION] = definition['model_definition'] if 'custom' in definition: lib_metadata[self.LibraryMetaNames.CUSTOM] = definition['custom'] if 'command' in definition: lib_metadata[self.LibraryMetaNames.COMMAND] = definition['command'] if 'space_uid' in definition: lib_metadata[self.LibraryMetaNames.SPACE_UID] = definition['space_uid'] details = self.store_library(lib_metadata) return self.get_library_uid(details)
[docs] def store_library(self, meta_props): """ Create a library.\n **Parameters** .. important:: #. **meta_props**: meta data of the libraries configuration. To see available meta names use:\n >>> client.runtimes.LibraryMetaNames.get() **type**: dict\n **Output** .. important:: **returns**: Metadata of the library created.\n **return type**: dict\n **Example** >>> library_details = client.runtimes.store_library({ >>> client.runtimes.LibraryMetaNames.NAME: "libraries_custom", >>> client.runtimes.LibraryMetaNames.DESCRIPTION: "custom libraries for scoring", >>> client.runtimes.LibraryMetaNames.FILEPATH: custom_library_path, >>> client.runtimes.LibraryMetaNames.VERSION: "1.0", >>> client.runtimes.LibraryMetaNames.PLATFORM: {"name": "python", "versions": ["3.5"]} >>> }) """ self.LibraryMetaNames._validate(meta_props) lib_metadata = self.LibraryMetaNames._generate_resource_metadata(meta_props, with_validation=True) if self._client.CAMS: if self._client.default_space_id is not None: lib_metadata['space'] = {'href': "/v4/spaces/" + self._client.default_space_id} else: raise WMLClientError( "It is mandatory is set the space. Use client.set.default_space(<SPACE_GUID>) to set the space.") try: if not self._ICP: response_post = requests.post(self._href_definitions.get_custom_libraries_href(), json=lib_metadata, headers=self._client._get_headers()) else: response_post = requests.post(self._href_definitions.get_custom_libraries_href(), json=lib_metadata, headers=self._client._get_headers(), verify=False) details = self._handle_response(201, u'saving libraries', response_post) if self.LibraryMetaNames.FILEPATH in meta_props: try: base_url = self._wml_credentials[u'url'] libraries_content_url = base_url + details[u'metadata'][u'href'] + '/content' put_header = self._client._get_headers(no_content_type=True) with open(meta_props[self.LibraryMetaNames.FILEPATH], 'rb') as data: if not self._ICP: response_definition_put = requests.put(libraries_content_url, data=data, headers=put_header) else: response_definition_put = requests.put(libraries_content_url, data=data, headers=put_header, verify=False) except Exception as e: raise e self._handle_response(200, u'saving libraries content', response_definition_put, False) except Exception as e: raise WMLClientError('Failure during creation of libraries.', e) return details
def _create_runtime_spec(self, custom_libs_list, meta_props): metadata = { self.ConfigurationMetaNames.NAME : meta_props[self.ConfigurationMetaNames.NAME], self.ConfigurationMetaNames.PLATFORM: meta_props[self.ConfigurationMetaNames.PLATFORM], } if self.ConfigurationMetaNames.DESCRIPTION in meta_props: metadata[self.ConfigurationMetaNames.DESCRIPTION] = meta_props[self.ConfigurationMetaNames.DESCRIPTION] if self.ConfigurationMetaNames.CUSTOM in meta_props: metadata[self.ConfigurationMetaNames.CUSTOM] = {meta_props[self.ConfigurationMetaNames.CUSTOM]} if self.ConfigurationMetaNames.COMPUTE in meta_props: metadata[self.ConfigurationMetaNames.COMPUTE] = meta_props[self.ConfigurationMetaNames.COMPUTE] if self.ConfigurationMetaNames.SPACE_UID in meta_props: metadata[self.ConfigurationMetaNames.SPACE_UID] = { "href": "/v4/spaces/"+meta_props[self.ConfigurationMetaNames.SPACE_UID] } if self._client.CAMS: if self._client.default_space_id is not None: metadata['space'] = {'href': "/v4/spaces/" + self._client.default_space_id} else: raise WMLClientError( "It is mandatory to set the space. Use client.set.default_space(<SPACE_UID>) to proceed.") if custom_libs_list is not None: custom_list = [] for uid in custom_libs_list: each_href = {"href": "/v4/libraries/" + uid} custom_list.append(each_href) metadata["custom_libraries"] = custom_list if self.ConfigurationMetaNames.CONFIGURATION_FILEPATH in meta_props: metadata[MetaNames.CONTENT_LOCATION] = meta_props[self.ConfigurationMetaNames.CONFIGURATION_FILEPATH] try: if not self._ICP: response_post = requests.post(self._href_definitions.get_runtimes_href(), json=metadata, headers=self._client._get_headers()) else: response_post = requests.post(self._href_definitions.get_runtimes_href(), json=metadata, headers=self._client._get_headers(), verify=False) details = self._handle_response(201, u'saving runtimes', response_post) if self.ConfigurationMetaNames.CONFIGURATION_FILEPATH in meta_props: try: runtimes_content_url = self._wml_credentials[u'url'] + details[u'metadata'][u'href'] + '/content' put_header = self._client._get_headers(content_type="text/plain") with open(meta_props[self.ConfigurationMetaNames.CONFIGURATION_FILEPATH], 'rb') as data: if not self._ICP: response_definition_put = requests.put(runtimes_content_url, data=data,headers=put_header) else: response_definition_put = requests.put(runtimes_content_url, data=data,headers=put_header, verify=False) except Exception as e: raise e self._handle_response(200, u'saving runtimes content', response_definition_put, False) except Exception as e: raise WMLClientError('Failure during creation of runtime.', e) return details['metadata']['guid']
[docs] @docstring_parameter({'str_type': STR_TYPE_NAME}) def store(self, meta_props): """ Create a runtime.\n **Parameters** .. important:: #. **meta_props**: meta data of the runtime configuration. To see available meta names use:\n >>> client.runtimes.ConfigurationMetaNames.get() **type**: dict\n **Output** .. important:: **returns**: Metadata of the runtime created\n **return type**: dict\n **Example** Creating a library\n >>> lib_meta = { >>> client.runtimes.LibraryMetaNames.NAME: "libraries_custom", >>> client.runtimes.LibraryMetaNames.DESCRIPTION: "custom libraries for scoring", >>> client.runtimes.LibraryMetaNames.FILEPATH: "/home/user/my_lib.zip", >>> client.runtimes.LibraryMetaNames.VERSION: "1.0", >>> client.runtimes.LibraryMetaNames.PLATFORM: {"name": "python", "versions": ["3.5"]} >>> } >>> custom_library_details = client.runtimes.store_library(lib_meta) >>> custom_library_uid = client.runtimes.get_library_uid(custom_library_details) Creating a runtime\n >>> runtime_meta = { >>> client.runtimes.ConfigurationMetaNames.NAME: "runtime_spec_python_3.5", >>> client.runtimes.ConfigurationMetaNames.DESCRIPTION: "test", >>> client.runtimes.ConfigurationMetaNames.PLATFORM: { >>> "name": "python", >>> "version": "3.5" >>> }, >>> client.runtimes.ConfigurationMetaNames.LIBRARIES_UIDS: [custom_library_uid] # already existing lib is linked here >>> } >>> runtime_details = client.runtimes.store(meta) """ self.ConfigurationMetaNames._validate(meta_props) custom_libs_list = [] # if self.ConfigurationMetaNames.LIBRARIES_DEFINITIONS in meta_props: # custom_libs_list.extend( # [self._create_library_from_definition(definition, meta_props) for definition in # meta_props[self.ConfigurationMetaNames.LIBRARIES_DEFINITIONS]] # ) if self.ConfigurationMetaNames.LIBRARIES_UIDS in meta_props: custom_libs_list.extend(meta_props[self.ConfigurationMetaNames.LIBRARIES_UIDS]) runtime_uid = self._create_runtime_spec(custom_libs_list, meta_props) return self.get_details(runtime_uid)
[docs] @docstring_parameter({'str_type': STR_TYPE_NAME}) def get_details(self, runtime_uid=None,pre_defined=False, limit=None): """ Get metadata of stored runtime(s). If runtime ID is not specified returns all runtimes metadata. **Parameters** .. important:: #. **runtime_uid**: Unique Id(UID) of runtime (optional)\n **type**: str\n #. **pre_defined**: Boolean indicating to display predefined runtimes only. Default value is set to 'False'\n **type**: bool\n #. **limit**: limit number of fetched records (optional)\n **type**: int\n **Output** .. important:: **returns**: metadata of runtime(s)\n **return type**: dict The output can be {"resources": [dict]} or a dict\n .. note:: If UID is not specified, all runtimes metadata is fetched\n **Example** >>> runtime_details = client.runtimes.get_details(runtime_uid) >>> runtime_details = client.runtimes.get_details(runtime_uid=runtime_uid) >>> runtime_details = client.runtimes.get_details() """ runtime_uid = str_type_conv(runtime_uid) Runtimes._validate_type(runtime_uid, u'runtime_uid', STR_TYPE, False) # if runtime_uid is not None and not is_uid(runtime_uid): # raise WMLClientError(u'\'runtime_uid\' is not an uid: \'{}\''.format(runtime_uid)) url = self._href_definitions.get_runtimes_href() if runtime_uid is not None or self._client.default_project_id is not None: return self._get_no_space_artifact_details(url, runtime_uid, limit, 'runtime specs', pre_defined="True") if pre_defined: return self._get_artifact_details(url, runtime_uid, limit, 'runtime specs',pre_defined="True") else: return self._get_artifact_details(url, runtime_uid, limit, 'runtime specs')
[docs] def get_library_details(self, library_uid=None, limit=None): """ Get metadata of stored libraries. If library UID is not specified returns all libraries metadata. **Parameters** .. important:: #. **library_uid**: library UID (optional)\n **type**: str\n #. **limit**: limit number of fetched records (optional)\n **type**: int\n **Output** .. important:: **returns**: metadata of library(s)\n **return type**: dict The output can be {"resources": [dict]} or a dict\n .. note:: If UID is not specified, all libraries metadata is fetched\n **Example** >>> library_details = client.runtimes.get_library_details(library_uid) >>> library_details = client.runtimes.get_library_details(library_uid=library_uid) >>> library_details = client.runtimes.get_library_details() """ library_uid = str_type_conv(library_uid) Runtimes._validate_type(library_uid, u'library_uid', STR_TYPE, False) if library_uid is not None and not is_uid(library_uid): raise WMLClientError(u'\'library_uid\' is not an uid: \'{}\''.format(library_uid)) url = self._href_definitions.get_custom_libraries_href() if library_uid is not None or self._client.default_project_id is not None: return self._get_no_space_artifact_details(url, library_uid, limit, 'libraries') return self._get_artifact_details(url, library_uid, limit, 'libraries')
[docs] @staticmethod @docstring_parameter({'str_type': STR_TYPE_NAME}) def get_href(details): """ Get runtime_href from runtime details. **Parameters** .. important:: #. **runtime_details**: Metadata of the runtime\n **type**: dict\n **Output** .. important:: **returns**: runtime href\n **return type**: str **Example** >>> runtime_details = client.runtimes.get_details(runtime_uid) >>> runtime_href = client.runtimes.get_href(runtime_details) """ Runtimes._validate_type(details, u'details', dict, True) Runtimes._validate_type_of_details(details, [RUNTIME_SPEC_DETAILS_TYPE, MODEL_DETAILS_TYPE, FUNCTION_DETAILS_TYPE]) details_type = get_type_of_details(details) if details_type == RUNTIME_SPEC_DETAILS_TYPE: return Runtimes._get_required_element_from_dict(details, 'runtime_details', ['metadata', 'href']) elif details_type == MODEL_DETAILS_TYPE: return Runtimes._get_required_element_from_dict(details, 'model_details', ['entity', 'runtime', 'href']) elif details_type == FUNCTION_DETAILS_TYPE: return Runtimes._get_required_element_from_dict(details, 'function_details', ['entity', 'runtime', 'href']) else: raise WMLClientError('Unexpected details type: {}'.format(details_type))
[docs] @staticmethod @docstring_parameter({'str_type': STR_TYPE_NAME}) def get_uid(details): """ Get runtime_uid from runtime details. **Parameters** .. important:: #. **runtime_details**: Metadata of the runtime\n **type**: dict\n **Output** .. important:: **returns**: Unique Id of runtime\n **return type**: str **Example** >>> runtime_details = client.runtimes.get_details(runtime_uid) >>> runtime_uid = client.runtimes.get_uid(runtime_details) """ Runtimes._validate_type(details, u'details', dict, True) Runtimes._validate_type_of_details(details, [RUNTIME_SPEC_DETAILS_TYPE, MODEL_DETAILS_TYPE, FUNCTION_DETAILS_TYPE]) details_type = get_type_of_details(details) if details_type == RUNTIME_SPEC_DETAILS_TYPE: return Runtimes._get_required_element_from_dict(details, 'runtime_details', ['metadata', 'guid']) elif details_type == MODEL_DETAILS_TYPE: return Runtimes._get_required_element_from_dict(details, 'model_details', ['entity', 'runtime', 'href']).split('/')[-1] elif details_type == FUNCTION_DETAILS_TYPE: return Runtimes._get_required_element_from_dict(details, 'function_details', ['entity', 'runtime', 'href']).split('/')[-1] else: raise WMLClientError('Unexpected details type: {}'.format(details_type))
[docs] @staticmethod @docstring_parameter({'str_type': STR_TYPE_NAME}) def get_library_href(library_details): """ Get library_href from library details. **Parameters** .. important:: #. **library_details**: Metadata of the library\n **type**: dict\n **Output** .. important:: **returns**: library href\n **return type**: str **Example** >>> library_details = client.runtimes.get_library_details(library_uid) >>> library_url = client.runtimes.get_library_href(library_details) """ Runtimes._validate_type(library_details, u'library_details', dict, True) Runtimes._validate_type_of_details(library_details, LIBRARY_DETAILS_TYPE) return Runtimes._get_required_element_from_dict(library_details, 'library_details', ['metadata', 'href'])
[docs] @staticmethod @docstring_parameter({'str_type': STR_TYPE_NAME}) def get_library_uid(library_details): """ Get library_uid from library details. **Parameters** .. important:: #. **library_details**: Metadata of the library\n **type**: dict\n **Output** .. important:: **returns**: Unique Id of library\n **return type**: str **Example** >>> library_details = client.runtimes.get_library_details(library_uid) >>> library_uid = client.runtimes.get_library_uid(library_details) """ Runtimes._validate_type(library_details, u'library_details', dict, True) Runtimes._validate_type_of_details(library_details, LIBRARY_DETAILS_TYPE) # TODO error handling return Runtimes._get_required_element_from_dict(library_details, 'library_details', ['metadata', 'guid'])
def _get_runtimes_uids_for_lib(self, library_uid, runtime_details=None): # Return list of runtimes which contains library_uid that is passed. if runtime_details is None: runtime_details = self.get_details() return list(map( lambda x: x['metadata']['guid'], filter( lambda x: any( filter( lambda y: library_uid in y['href'], x['entity']['custom_libraries'] if 'custom_libraries' in x['entity'] else []) ), runtime_details['resources'] ) ))
[docs] @docstring_parameter({'str_type': STR_TYPE_NAME}) def delete(self, runtime_uid, with_libraries=False): """ Delete a runtime. **Parameters** .. important:: #. **runtime_uid**: Unique Id of Runtime\n **type**: str\n #. **with_libraries**: Boolean value indicating an option to delete the libraries associated with the runtime\n **type**: bool\n **Output** .. important:: **returns**: status ("SUCCESS" or "FAILED")\n **return type**: str\n **Example** >>> client.runtimes.delete(deployment_uid) """ runtime_uid = str_type_conv(runtime_uid) Runtimes._validate_type(runtime_uid, u'runtime_uid', STR_TYPE, True) Runtimes._validate_type(with_libraries, u'autoremove', bool, True) if runtime_uid is not None and not is_uid(runtime_uid): raise WMLClientError(u'\'runtime_uid\' is not an uid: \'{}\''.format(runtime_uid)) if with_libraries: runtime_details = self.get_details(runtime_uid) url = self._href_definitions.get_runtime_href(runtime_uid) if not self._ICP: response_delete = requests.delete( url, headers=self._client._get_headers()) else: response_delete = requests.delete( url, headers=self._client._get_headers(), verify=False) if with_libraries: if 'custom_libraries' in runtime_details['entity']: details = self.get_details() custom_libs_uids = map(lambda x: x['href'].split('/')[-1], runtime_details['entity']['custom_libraries']) custom_libs_to_remove = filter( lambda x: len(self._get_runtimes_uids_for_lib(x, details)) == 0, custom_libs_uids ) for uid in custom_libs_to_remove: print('Deleting orphaned library \'{}\' during autoremove delete.'.format(uid)) delete_status = self.delete_library(uid) print(delete_status) return self._handle_response(204, u'runtime deletion', response_delete, False)
@docstring_parameter({'str_type': STR_TYPE_NAME}) def _delete_orphaned_libraries(self): """ Delete all custom libraries without runtime. A way you might use this is: >>> client.runtimes.delete_orphaned_libraries() """ lib_details = self.get_library_details() details = self.get_details() for lib in lib_details['resources']: lib_uid = lib['metadata']['guid'] if len(self._get_runtimes_uids_for_lib(lib_uid, details)) == 0: print('Deleting orphaned \'{}\' library... '.format(lib_uid), end="") library_endpoint = self._href_definitions.get_custom_library_href(lib_uid) if not self._ICP: response_delete = requests.delete(library_endpoint, headers=self._client._get_headers()) else: response_delete = requests.delete(library_endpoint, headers=self._client._get_headers(), verify=False) try: self._handle_response(204, u'library deletion', response_delete, False) print('SUCCESS') except: pass
[docs] @docstring_parameter({'str_type': STR_TYPE_NAME}) def delete_library(self, library_uid): """ Delete a library. **Parameters** .. important:: #. **library_uid**: Unique Id of Library\n **type**: str\n **Output** .. important:: **returns**: status ("SUCCESS" or "FAILED")\n **return type**: str\n **Example** >>> client.runtimes.delete_library(library_uid) """ Runtimes._validate_type(library_uid, u'library_uid', STR_TYPE, True) library_endpoint = self._href_definitions.get_custom_library_href(library_uid) if not self._ICP: response_delete = requests.delete(library_endpoint, headers=self._client._get_headers()) else: response_delete = requests.delete(library_endpoint, headers=self._client._get_headers(), verify=False) return self._handle_response(204, u'library deletion', response_delete, False)
[docs] def list(self, limit=None,pre_defined=False): """ List stored runtimes. If limit is set to None there will be only first 50 records shown. **Parameters** .. important:: #. **limit**: limit number of fetched records\n **type**: int\n #. **pre_defined**: Boolean indicating to display predefined runtimes only. Default value is set to 'False'\n **type**: bool\n **Output** .. important:: This method only prints the list of runtimes in a table format.\n **return type**: None\n **Example** >>> client.runtimes.list() >>> client.runtimes.list(pre_defined=True) """ details = self.get_details(pre_defined=pre_defined) resources = details[u'resources'] values = [(m[u'metadata'][u'guid'], m[u'entity'][u'name'], m[u'metadata'][u'created_at'], m[u'entity'][u'platform']['name']) for m in resources] self._list(values, [u'GUID', u'NAME', u'CREATED', u'PLATFORM'], limit, 50)
def _list_runtimes_for_libraries(self): # TODO make public when the time'll come """ List of Unique Ids of runtimes for libraries. A way you might use this is: >>> client.runtimes.list_runtimes_for_libraries() >>> client.runtimes.list_runtimes_for_libraries(library_uid) """ details = self.get_library_details() runtime_details = self.get_details() values = [ (m[u'metadata'][u'guid'], m[u'entity'][u'name'], m[u'entity'][u'version'], ', '.join(self._get_runtimes_uids_for_lib(m[u'metadata'][u'guid'], runtime_details))) for m in details['resources']] values = sorted(sorted(values, key=lambda x: x[2], reverse=True), key=lambda x: x[1]) from tabulate import tabulate header = [u'GUID', u'NAME', u'VERSION', u'RUNTIME SPECS'] table = tabulate([header] + values) print(table)
[docs] def list_libraries(self, runtime_uid=None, limit=None): """ List stored libraries. If runtime UID is not provided, all libraries are listed else, libraries associated with a runtime are listed. If limit is set to None there will be only first 50 records shown. **Parameters** .. important:: #. **runtime_uid**: Unique Id of runtime (optional)\n **type**: str\n #. **limit**: limit number of fetched records\n **type**: int\n **Output** .. important:: This method only prints the list of libraries in a table format.\n **return type**: None\n **Example** >>> client.runtimes.list_libraries() >>> client.runtimes.list_libraries(runtime_uid) """ runtime_uid = str_type_conv(runtime_uid) Runtimes._validate_type(runtime_uid, u'runtime_uid', STR_TYPE, False) if runtime_uid is None: details = self.get_library_details() resources = details[u'resources'] values = [(m[u'metadata'][u'guid'], m[u'entity'][u'name'], m[u'entity'][u'version'], m[u'metadata'][u'created_at'], m[u'entity'][u'platform']['name'], m[u'entity'][u'platform'][u'versions']) for m in resources] self._list(values, [u'GUID', u'NAME', u'VERSION', u'CREATED', u'PLATFORM NAME', u'PLATFORM VERSIONS'], limit, 50) else: details = self.get_details(runtime_uid) if 'custom_libraries' not in details['entity'] or len(details['entity']['custom_libraries']) == 0: print('No libraries found for this runtime.') return values = [(m[u'href'].split('/')[-1], u'') for m in details['entity']['custom_libraries']] from tabulate import tabulate header = [u'GUID'] table = tabulate([header] + values) print(table)
[docs] def download_configuration(self, runtime_uid, filename=None): """ Downloads configuration file for runtime with specified uid. **Parameters** .. important:: #. **runtime_uid**: Unique Id(UID) of runtime\n **type**: str\n #. **filename**: filename of downloaded archive (optional)\n **default value**: runtime_configuration.yaml\n **type**: str\n **Output** .. important:: **returns**: Path to the downloaded runtime configuration\n **return type**: str\n .. note:: If filename is not specified, the default filename is "runtime_configuration.yaml".\n **Example** >>> filename="runtime.yml" >>> client.runtimes.download_configuration(runtime_uid, filename=filename) """ runtime_uid = str_type_conv(runtime_uid) Runtimes._validate_type(runtime_uid, u'runtime_uid', STR_TYPE, True) if not is_uid(runtime_uid): raise WMLClientError(u'\'runtime_uid\' is not an uid: \'{}\''.format(runtime_uid)) download_url = self._href_definitions.get_runtime_href(runtime_uid) + '/content' if not self._ICP: response_get = requests.get( download_url, headers=self._client._get_headers()) else: response_get = requests.get( download_url, headers=self._client._get_headers(), verify=False) if filename is None: filename = 'runtime_configuration.yaml' if response_get.status_code == 200: with open(filename, "wb") as new_file: new_file.write(response_get.content) new_file.close() print(u'Successfully downloaded runtime configuration file: ' + str(filename)) return os.getcwd() + "/"+filename else: raise WMLClientError(u'Unable to download configuration content: ' + response_get.text)
[docs] def download_library(self, library_uid, filename=None): """ Downloads library content with specified uid. **Parameters** .. important:: #. **library_uid**: Unique ID(UID) of library\n **type**: str\n #. **filename**: filename of downloaded archive (optional)\n **default value**: <LIBRARY-NAME>-<LIBRARY-VERSION>.zip\n **type**: str\n **Output** .. important:: **returns**: Path to the downloaded library content\n **return type**: str\n .. note:: If filename is not specified, the default filename is "<LIBRARY-NAME>-<LIBRARY-VERSION>.zip".\n **Example** >>> filename="library.tgz" >>> client.runtimes.download_library(runtime_uid, filename=filename) """ library_uid = str_type_conv(library_uid) Runtimes._validate_type(library_uid, u'library_uid', STR_TYPE, True) if not is_uid(library_uid): raise WMLClientError(u'\'library_uid\' is not an uid: \'{}\''.format(library_uid)) download_url = self._href_definitions.get_custom_library_href(library_uid) + '/content' if not self._ICP: response_get = requests.get( download_url, headers=self._client._get_headers()) else: response_get = requests.get( download_url, headers=self._client._get_headers(), verify=False) if filename is None: details = self.get_library_details(library_uid) filename = '{}-{}.zip'.format(details['entity']['name'], details['entity']['version']) if response_get.status_code == 200: with open(filename, "wb") as new_file: new_file.write(response_get.content) new_file.close() print(u'Successfully downloaded library content: ' + str(filename)) return os.getcwd() + "/"+filename else: raise WMLClientError(u'Unable to download library content: ' + response_get.text)
[docs] def update_library(self, library_uid, changes): """ Updates existing library metadata. **Parameters** .. important:: #. **library_uid**: Unique ID(UID) of library which definition should be updated\n **type**: str\n #. **changes**: elements which should be changed, where keys are ConfigurationMetaNames\n **type**: dict\n **Output** .. important:: **returns**: metadata of updated library\n **return type**: dict\n **Example** >>> metadata = { >>> client.runtimes.LibraryMetaNames.NAME:"updated_lib" >>> } >>> library_details = client.runtimes.update_library(library_uid, changes=metadata) """ library_uid = str_type_conv(library_uid) self._validate_type(library_uid, u'library_uid', STR_TYPE, True) self._validate_type(changes, u'changes', dict, True) meta_props_str_conv(changes) details = self.get_library_details(library_uid) patch_payload = self.LibraryMetaNames._generate_patch_payload(details['entity'], changes, with_validation=True) url = self._href_definitions.get_custom_library_href(library_uid) if not self._ICP: response = requests.patch(url, json=patch_payload, headers=self._client._get_headers()) else: response = requests.patch(url, json=patch_payload, headers=self._client._get_headers(), verify=False) updated_details = self._handle_response(200, u'library patch', response) return updated_details
[docs] def update_runtime(self, runtime_uid, changes): """ Updates existing runtime metadata. **Parameters** .. important:: #. **runtime_uid**: Unique ID(UID) of runtime which definition should be updated\n **type**: str\n #. **changes**: elements which should be changed, where keys are ConfigurationMetaNames\n **type**: dict\n **Output** .. important:: **returns**: metadata of updated runtime\n **return type**: dict\n **Example** >>> metadata = { >>> client.runtimes.ConfigurationMetaNames.NAME:"updated_runtime" >>> } >>> runtime_details = client.runtimes.update(runtime_uid, changes=metadata) """ library_uid = str_type_conv(runtime_uid) self._validate_type(library_uid, u'runtime_uid', STR_TYPE, True) self._validate_type(changes, u'changes', dict, True) meta_props_str_conv(changes) details = self.get_details(runtime_uid) patch_payload = self.LibraryMetaNames._generate_patch_payload(details['entity'], changes, with_validation=True) url = self._href_definitions.get_runtime_href(runtime_uid) if not self._ICP: response = requests.patch(url, json=patch_payload, headers=self._client._get_headers()) else: response = requests.patch(url, json=patch_payload, headers=self._client._get_headers(), verify=False) updated_details = self._handle_response(200, u'library patch', response) return updated_details
[docs] def clone_runtime(self, runtime_uid, space_id=None, action="copy", rev_id=None): """ Creates a new runtime identical with the given runtime either in the same space or in a new space. All dependent assets will be cloned too. **Parameters** .. important:: #. **runtime_id**: Unique ID of the runtime to be cloned:\n **type**: str\n #. **space_id**: Unique Id (UID) of the space to which the runtime needs to be cloned. (optional) **type**: str\n #. **action**: Action specifying "copy" or "move". (optional) **type**: str\n #. **rev_id**: Revision ID of the runtime. (optional) **type**: str\n **Output** .. important:: **returns**: Metadata of the runtime cloned.\n **return type**: dict\n **Example** >>> client.runtimes.clone_runtime(runtime_uid=artifact_id,space_id=space_uid,action="copy") .. note:: * If revision id is not specified, all revisions of the artifact are cloned\n * Default value of the parameter action is copy\n * Unique Id of Space is required for move action\n """ artifact = str_type_conv(runtime_uid) Runtimes._validate_type(artifact, 'runtime_uid', STR_TYPE, True) space = str_type_conv(space_id) rev = str_type_conv(rev_id) action = str_type_conv(action) clone_meta = {} if space is not None: clone_meta["space"] = {"href": API_VERSION + SPACES + "/" + space} if action is not None: clone_meta["action"] = action if rev is not None: clone_meta["rev"] = rev url = self._href_definitions.get_runtime_href(runtime_uid) if not self._ICP: response_post = requests.post(url, json=clone_meta, headers=self._client._get_headers()) else: response_post = requests.post(url, json=clone_meta, headers=self._client._get_headers(), verify=False) details = self._handle_response(expected_status_code=200, operationName=u'cloning runtime', response=response_post) return details
[docs] def clone_library(self, library_uid, space_id=None, action="copy", rev_id=None): """ Creates a new function library with the given library either in the same space or in a new space. All dependent assets will be cloned too. **Parameters** .. important:: #. **library_id**: Unique Id(UID) of the library to be cloned:\n **type**: str\n #. **space_id**: Unique ID (UID) of the space to which the library needs to be cloned. (optional) **type**: str\n #. **action**: Action specifying "copy" or "move". (optional) **type**: str\n #. **rev_id**: Revision ID of the library. (optional) **type**: str\n **Output** .. important:: **returns**: Metadata of the library cloned.\n **return type**: dict\n **Example** >>> client.runtmes.clone_library(library_uid=artifact_id,space_id=space_uid,action="copy") .. note:: * If revision id is not specified, all revisions of the artifact are cloned\n * Default value of the parameter action is copy\n * Space guid is mandatory for move action\n """ artifact = str_type_conv(library_uid) Runtimes._validate_type(artifact, 'library_uid', STR_TYPE, True) space = str_type_conv(space_id) rev = str_type_conv(rev_id) action = str_type_conv(action) clone_meta = {} if space is not None: clone_meta["space"] = {"href": API_VERSION + SPACES + "/" + space} if action is not None: clone_meta["action"] = action if rev is not None: clone_meta["rev"] = rev url = self._href_definitions.get_custom_library_href(library_uid) if not self._ICP: response_post = requests.post(url, json=clone_meta, headers=self._client._get_headers()) else: response_post = requests.post(url, json=clone_meta, headers=self._client._get_headers(), verify=False) details = self._handle_response(expected_status_code=200, operationName=u'cloning library', response=response_post) return details