# Customizing with third\-party and private Python libraries #

If your model requires custom components such as user\-defined transformers, estimators, or user\-defined tensors, you can create a custom software specification that is derived from a base, or a predefined specification\. Python functions and Python scripts also support custom software specifications\.

You can use custom software specification to reference any third\-party libraries, user\-created Python packages, or both\. Third\-party libraries or user\-created Python packages must be specified as package extensions so that they can be referenced in a custom software specification\.

You can customize deployment runtimes in these ways:

<!-- <ul> -->

 *  [Define customizations in a Watson Studio project and then promote them to a deployment space](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=cdpaas&locale=en#custom-ws)
 *  [Create package extensions and custom software specifications in a deployment space by using the Watson Machine Learning Python client](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=cdpaas&locale=en#custom-wml)

<!-- </ul> -->

For more information, see [Troubleshooting](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=cdpaas&locale=en#ts)\.

## Defining customizations in a Watson Studio project and then promoting them to a deployment space ##

Environments in Watson Studio projects can be customized to include third\-party libraries that can be installed from Anaconda or from the PyPI repository\.

For more information, see [Environments](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/environments-parent.html)\.

As part of custom environment creation, these steps are performed internally (visible to the user):

<!-- <ul> -->

 *  A package extension that contains the details of third\-party libraries is created in `conda YAML format`\.
 *  A custom software specification with the same name as the custom environment is created and the package extension that is created is associated with this custom software specification\.

<!-- </ul> -->

The models or Python functions/scripts created with the custom environment must reference the custom software specification when they are saved in Watson Machine Learning repository in the project scope\.

### Propagating software specifications and package extensions from projects to deployment spaces ###

To export custom software specifications and package extensions that were created in a Watson Studio project to a deployment space:

<!-- <ol> -->

1.  From your project interface, click the **Manage** tab\.
2.  Select **Environments**\.
3.  Click the **Templates** tab\.
4.  From your custom environment's **Options** menu, select **Promote to space**\.

<!-- </ol> -->

![Selecting "Promote to space" for a custom environment in Watson Studio interface](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/images/promote-custom-env-from-ws.png)

Alternatively, when you promote any model or Python function that is associated with a custom environment from a Watson Studio project to a deployment space, the associated custom software specification and package extension is also promoted to the deployment space\.

If you want to update software specifications and package extensions after you promote them to deployment space, follow these steps:

<!-- <ol> -->

1.  In the deployment space, delete the software specifications, package extensions, and associated models (optional) by using the Watson Machine Learning Python client\.
2.  In a project, promote the model, function, or script that is associated with the changed custom software specification and package extension to the space\.

<!-- </ol> -->

Software specifications are also included when you import a project or space that includes one\.

## Creating package extensions and custom software specifications in a deployment space by using the Watson Machine Learning Python client ##

You can use the Watson Machine Learning APIs or Python client to define a custom software specification that is derived from a base specification\.

High\-level steps to create a custom software specification that uses third\-party libraries or user\-created Python packages:

<!-- <ol> -->

1.  Optional: [Save a conda YAML file that contains a list of third\-party libraries](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=cdpaas&locale=en#save-conda-yaml) or [save a user\-created Python library and create a package extension](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=cdpaas&locale=en#save-user-created)\.
    
    Note: This step is not required if the model does not have any dependency on a third-party library or a user-created Python library.
2.  Create a custom software specification
3.  Add a reference of the package extensions to the custom software specification that you created\.

<!-- </ol> -->

### Saving a conda YAML file that contains a list of third\-party libraries ###

To save a conda YAML file that contains a list of third\-party libraries as a package extension and create a custom software specification that is linked to the package extension:

<!-- <ol> -->

1.  Authenticate and create the client\.
    
    Refer to [Authentication](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-authentication.html).
2.  Create and set the default deployment space, then list available software specifications\.
    
        metadata = {
             wml_client.spaces.ConfigurationMetaNames.NAME:
                 'examples-create-software-spec',
             wml_client.spaces.ConfigurationMetaNames.DESCRIPTION:
                 'For my models'
         }
         space_details = wml_client.spaces.store(meta_props=metadata)
         space_uid = wml_client.spaces.get_id(space_details)
        
         # set the default space
         wml_client.set.default_space(space_uid)
        
         # see available meta names for software specs
         print('Available software specs configuration:', wml_client.software_specifications.ConfigurationMetaNames.get())
         wml_client.software_specifications.list()
        
         asset_id = 'undefined'
         pe_asset_id = 'undefined'
3.  Create the metadata for package extensions to add to the base specification\.
    
        pe_metadata = {
             wml_client.package_extensions.ConfigurationMetaNames.NAME:
                 'My custom library',
             # optional:
             # wml_client.software_specifications.ConfigurationMetaNames.DESCRIPTION:
             wml_client.package_extensions.ConfigurationMetaNames.TYPE:
                 'conda_yml'
         }
4.  Create a yaml file that contains the list of packages and then save it as `customlibrary.yaml`\.
    
    Example yaml file:
    
        name: add-regex-package
         dependencies:
             - regex
    
    For more information, see [Examples of customizations](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/example-customizations.html).
5.  Store package extension information\.
    
        pe_asset_details = wml_client.package_extensions.store(
             meta_props=pe_metadata,
             file_path='customlibrary.yaml'
         )
         pe_asset_id = wml_client.package_extensions.get_id(pe_asset_details)
6.  Create the metadata for the software specification and store the software specification\.
    
        # Get the id of the base software specification
         base_id = wml_client.software_specifications.get_id_by_name('default_py3.9')
        
         # create the metadata for software specs
         ss_metadata = {
             wml_client.software_specifications.ConfigurationMetaNames.NAME:
                 'Python 3.9 with pre-installed ML package',
             wml_client.software_specifications.ConfigurationMetaNames.DESCRIPTION:
                 'Adding some custom libraries like regex', # optional
             wml_client.software_specifications.ConfigurationMetaNames.BASE_SOFTWARE_SPECIFICATION:
                 {'guid': base_id},
             wml_client.software_specifications.ConfigurationMetaNames.PACKAGE_EXTENSIONS:
                 [{'guid': pe_asset_id}]
         }
        
         # store the software spec
         ss_asset_details = wml_client.software_specifications.store(meta_props=ss_metadata)
        
         # get the id of the new asset
         asset_id = wml_client.software_specifications.get_id(ss_asset_details)
        
         # view new software specification details
         import pprint as pp
        
         ss_asset_details = wml_client.software_specifications.get_details(asset_id)
         print('Package extensions', pp.pformat(
             ss_asset_details['entity']['package_extensions']
         ))

<!-- </ol> -->

### Saving a user\-created Python library and creating a package extension ###

For more information, see [Requirements for using custom components in models](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-custom_libs_overview.html)\.

To save a user\-created Python package as a package extension and create a custom software specification that is linked to the package extension:

<!-- <ol> -->

1.  Authenticate and create the client\.
    
    Refer to [Authentication](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-authentication.html).
2.  Create and set the default deployment space, then list available software specifications\.
    
        metadata = {
             wml_client.spaces.ConfigurationMetaNames.NAME:
                 'examples-create-software-spec',
             wml_client.spaces.ConfigurationMetaNames.DESCRIPTION:
                 'For my models'
         }
         space_details = wml_client.spaces.store(meta_props=metadata)
         space_uid = wml_client.spaces.get_id(space_details)
        
         # set the default space
         wml_client.set.default_space(space_uid)
        
         # see available meta names for software specs
         print('Available software specs configuration:', wml_client.software_specifications.ConfigurationMetaNames.get())
         wml_client.software_specifications.list()
        
         asset_id = 'undefined'
         pe_asset_id = 'undefined'
3.  Create the metadata for package extensions to add to the base specification\.
    
    Note:You can specify `pip_zip` only as a value for the `wml_client.package_extensions.ConfigurationMetaNames.TYPE` metadata property.
    
        pe_metadata = {
             wml_client.package_extensions.ConfigurationMetaNames.NAME:
                 'My Python library',
             # optional:
             # wml_client.software_specifications.ConfigurationMetaNames.DESCRIPTION:
             wml_client.package_extensions.ConfigurationMetaNames.TYPE:
                 'pip.zip'
         }
4.  Specify the path of the user\-created Python library\.
    
        python_lib_file_path="my-python-library-0.1.zip"
    
    For more information, see [Requirements for using custom components in models](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-custom_libs_overview.html).
5.  Store package extension information\.
    
        pe_asset_details = wml_client.package_extensions.store(
             meta_props=pe_metadata,
             file_path=python_lib_file_path
         )
         pe_asset_id = wml_client.package_extensions.get_id(pe_asset_details)
6.  Create the metadata for the software specification and store the software specification\.
    
        # Get the id of the base software specification
         base_id = wml_client.software_specifications.get_id_by_name('default_py3.9')
        
         # create the metadata for software specs
         ss_metadata = {
             wml_client.software_specifications.ConfigurationMetaNames.NAME:
                 'Python 3.9 with pre-installed ML package',
             wml_client.software_specifications.ConfigurationMetaNames.DESCRIPTION:
                 'Adding some custom libraries like regex', # optional
             wml_client.software_specifications.ConfigurationMetaNames.BASE_SOFTWARE_SPECIFICATION:
                 {'guid': base_id},
             wml_client.software_specifications.ConfigurationMetaNames.PACKAGE_EXTENSIONS:
                 [{'guid': pe_asset_id}]
         }
        
         # store the software spec
         ss_asset_details = wml_client.software_specifications.store(meta_props=ss_metadata)
        
         # get the id of the new asset
         asset_id = wml_client.software_specifications.get_id(ss_asset_details)
        
         # view new software specification details
         import pprint as pp
        
         ss_asset_details = wml_client.software_specifications.get_details(asset_id)
         print('Package extensions', pp.pformat(
             ss_asset_details['entity']['package_extensions']
         ))

<!-- </ol> -->

## Troubleshooting ##

When a conda yml based custom library installation fails with this error: `Encountered error while installing custom library`, try these alternatives:

<!-- <ul> -->

 *  Use a different version of the same package that is available in Anaconda for the concerned Python version\.
 *  Install the library from the pypi repository, by using pip\. Edit the conda yml installation file contents:
    
        name: <conda yml file name>
          dependencies:
          - numpy
          - pip:
              - pandas==1.2.5

<!-- </ul> -->

**Parent topic:**[Customizing deployment runtimes](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-customize.html)

<!-- </article "role="article" "> -->