ANSA Secondary Development - Importing External Python Libraries in ANSA

Import external python in ANSA

NumPy

NumPy is an extension of Python for scientific computing. It supports large multidimensional arrays and has a large library of advanced mathematical functions to manipulate them.

Beginning with ANSA 21.0.0, v1. Version 18.2 of the NumberPy library is integrated into BETA using MKL LP64 (32-bit integer). Users can access it by importing libraries:

import numpy
numpy.show_config()

For more information about NumPy, click this link to get: NumPy.

SciPy

Scipy Python is a library for scientific computing. It contains modules for optimization, linear algebra, integration, interpolation, FFT, signal processing, ODE solving, and so on.

Version 1.5.1 of SciPy is installed in BETA.

import scipy
from scipy import linalg
import numpy as np

def find_det():
    arr = np.array([[1, 2],
                    [3, 4]])

    det_res = linalg.det(arr)
    print(det_res)

OpenSSL

OpenSSL is a toolkit library for the TLS and SSL protocols. It is also a common password library.

Version 1.1.1d is installed in BETA.

H5py

H5py yes HDF5 python interface for binary data format.

BETA has version 2.10.0 of H5py installed.

PIP and venv packages and environment management systems

Setting up a Python environment is challenging because libraries can have multiple dependencies and work with specific Python versions. And the package management system can help us solve these problems.

PIP

pip is a standard management system for installing and managing Python packages. pip was released with python. The BETA Python interface can be accessed in a program or from the command line.

Command Line Access

BETA_CAE_Systems/shared_v21.0.0/python/python.sh -m pip install requests

Access in Programs

import pip
pip.main(['install','requests'])

venv

venv Provides support for creating a "virtual environment" under your own site directory. Each environment is isolated from its own Python binaries and Python packages that are installed independently in the site directory. When the desired virtual environment is activated, the BETA Python interface (interpeter) imports packages from it without the user having to manage the imported packages.

Create a new virtual environment:

BETA_CAE_Systems/shared_v21.0.0/python/python.sh -m venv /path/to/create/venv/my_test_venv --system-site-packages

Activate a new environment:

/path/to/create/venv/my_test_venv/activate

Activation activates Python in the environment. Any pip installation performed will apply to this virtual environment. ANSA or META can automatically find the path to this environment.

Disabling environment:

deactivate

CONDA Packages and Environmental Management Systems

CONDA Is a package management system that allows easy installation of heavily dependent third-party libraries. Some libraries of the CONDA system can be imported into ANSA and META for use.

The following steps are used:

Download Conda

Download and install Miniconda. Miniconda is a reduced version of the Anaconda Python distribution.

Conda Environment Installation and Setup

The Conda installation directory needs to be added to the system's environment path.

in bash

export PATH="/home/my_name/miniconda3/bin":{$PATH}

in tcsh

setenv PATH $PATH:/home/my_name/miniconda3/bin

On windows:

c:\miniconda3\scripts

Conda's environment is an independent directory structure that allows multiple versions of the same library to exist simultaneously. ANSA and META come with Python 3.8. Therefore, we need to create an environment that is compatible with Python 3.8 libraries.

conda create --name python38 python=3.8

Finally, you need to activate the newly created environment so that the new installation is for Python 3.8.

Under Linux:

conda activate python38

Be careful:
Activation of virtual environments can only be done in bash

Under Windows:

conda activate python38

Installation Library

Install the required libraries in an active environment in the following ways:

conda install library_name

Import libraries into ANSA and META

In order to import Conda environments into ANSA or META scripts, add the site-packages path of Conda's Python 3.8 to the system path. To get the path to the site-packages, run the following command in Conda's python38 environment:

python3 -c "import site; print(site.getsitepackages()[0])"

Use the returned path in ANSA and META to import the required libraries.

import sys

CONDA_ENV = '/home/my_name/miniconda3/envs/python38/lib/python3.8/site-packages'
sys.path.append(CONDA_ENV)

import scipy

Conda in Corporate Intranet

In order to have a Python 3.8r compatible library on your corporate intranet, you need to set up a Conda Channel without accessing the Internet. Users with a separate miniconda installation will be able to install the required libraries from the local Conda Channel.

The general instructions for creating and setting custom channels are Here Find it.

A Python script is provided to set conda channels. The script runs in Python 3 and requires an Internet connection to download the libraries required for a given Python version.

Set conda channel python script:

import sys
import os
import urllib.parse
import urllib.request
import json
import optparse

class CondaRepo():
    def __init__(self, py_version, is_win, is_linux, is_mac):
        self.py_version = py_version
        self.py_version_float = float(py_version)
        if self.py_version_float < 3.5:
            self.main_repos = ['https://repo.anaconda.com/pkgs/free/']
        else:
            self.main_repos = ['https://repo.anaconda.com/pkgs/free/',
                               'https://repo.anaconda.com/pkgs/main/']
        self.output_path = ''
        self.is_win = is_win
        self.is_linux = is_linux
        self.is_mac = is_mac
        self.all_suffixes = ['noarch']

        if self.is_win:
            self.all_suffixes.append('win-64')
        if self.is_linux:
            self.all_suffixes.append('linux-64')
        if self.is_mac:
            self.all_suffixes.append('osx-64')
        
    
    @property
    def output_path(self):
        return self._output_path
    
    @output_path.setter
    def output_path(self, output_path):
        if not output_path:
            self._output_path = output_path
            return 
        
        if not os.path.isdir(output_path):
            raise OSError('channel path is not valid')
        if not os.access(output_path, os.W_OK):
            raise OSError('you do not have permission to write in the channel dir')
        self._output_path = output_path
    
    @property
    def py_version(self):
        return self._py_version
    
    @py_version.setter
    def py_version(self, py_version):
        if not py_version:
            self._py_version = py_version

        versions_dict = {'3.0':'py30',
                         '3.1':'py31',
                         '3.2':'py32',
                         '3.3':'py33',
                         '3.4':'py34',
                         '3.5':'py35',
                         '3.6':'py36',
                         '3.7':'py37',
                         '3.8':'py38'}
        self._py_version = versions_dict[py_version]
    
    @property
    def is_win(self):
        return self._is_win
    
    @is_win.setter
    def is_win(self, is_win):
        if type(is_win) == bool:
            self._is_win = is_win
            return

        bool_dict = {'true':True,
                     'false':False}
        self._is_win = bool_dict[is_win]
    
    @property
    def is_linux(self):
        return self._is_linux
    
    @is_linux.setter
    def is_linux(self, is_linux):
        if type(is_linux) == bool:
            self._is_linux = is_linux
            return

        bool_dict = {'true':True,
                     'false':False}
        self._is_linux = bool_dict[is_linux]
    
    @property
    def is_mac(self):
        return self._is_mac
    
    @is_mac.setter
    def is_mac(self, is_mac):
        if type(is_mac) == bool:
            self._is_mac = is_mac
            return

        bool_dict = {'true':True,
                     'false':False}
        self._is_mac = bool_dict[is_mac]

    def _create_subdir(self, subdir_name):
        dir_path = os.path.join(self.output_path, subdir_name)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

    def _download_libs(self, repos_info, repo, repo_dir):
        subdir = repos_info['info']['subdir']
        subdir_tmp  = os.path.join(repo_dir,subdir)
        self._create_subdir(subdir_tmp)
        save_path = os.path.join(self.output_path, repo_dir, subdir)

        def perform_download(subdir, pack_name):
            pack_name = pack_name.replace('tar.bz2', 'conda')
            save_path_tmp = os.path.join(save_path, pack_name)
            if os.path.exists(save_path_tmp):
                return
            print('downloading : %s - %s ...'%(subdir, pack_name))
            try:
                down_path = os.path.join(repo, subdir, pack_name)
                req = urllib.request.Request(down_path)
                ret = urllib.request.urlopen(req)
            except:
                print('unable to download : %s - %s ...'%(subdir, pack_name))
                pack_name = pack_name.replace('conda', 'tar.bz2')
                save_path_tmp = os.path.join(save_path, pack_name)
                try:
                    print('downloading : %s - %s ...'%(subdir, pack_name))
                    down_path = os.path.join(repo, subdir, pack_name)
                    req = urllib.request.Request(down_path)
                    ret = urllib.request.urlopen(req)
                except:
                    print('unable to download : %s - %s ...'%(subdir, pack_name))
                    return

            with open(save_path_tmp, 'wb') as f:
                f.write(ret.read())
            ret.close()

        perform_download(subdir, 'repodata.json')
        perform_download(subdir, 'repodata.json.bz2')
        #perform_download(subdir, 'repodata_from_packages.json')
        
        for pack_name, pack_info in repos_info['packages'].items():
            if subdir == 'noarch':
                perform_download(subdir, pack_name)
            else:
                if 'py' not in pack_info['build'] or self.py_version in pack_info['build'] or 'py_0' in pack_info['build']:
                    perform_download(subdir, pack_name)

    def _get_repo_info(self, repo, suffix):
        repo_data_path = os.path.join(repo, suffix, 'repodata.json')        
        req = urllib.request.Request(repo_data_path)
        with urllib.request.urlopen(req) as response:
            data = json.load(response)
        return data
    
    def start_download(self):
        workers = []
        for repo in self.main_repos:
            if 'free' in repo:
                subdir = 'free'
            else:
                subdir = 'main'
            self._create_subdir(subdir)
            for suffix in self.all_suffixes:
                repos_info = self._get_repo_info(repo, suffix)
                self._download_libs(repos_info, repo, subdir)

def parse_options():
    parser = optparse.OptionParser()
    parser.add_option('-c','--channel-dir', action='store',
                    default='', dest='channel_dir',
                    help='the setup directory of the conda channel')
    parser.add_option('-w','--windows-download', action='store',
                    default='false', dest='win_down',
                    help='true or false to download windows libraries')
    parser.add_option('-l','--linux-download', action='store',
                    default='false', dest='linux_down',
                    help='true or false to download linux libraries')
    parser.add_option('-m','--mac-download', action='store',
                    default='false', dest='mac_down',
                    help='true or false to download mac libraries')
    parser.add_option('-p','--python-version', action='store',
                    default='3.3', dest='py_version',
                    help='The python version for which to seek libraries 3.x format')
    
    opts, args = parser.parse_args()

    return opts, args

def start():
    opts, args = parse_options()
    bool_str = ('true', 'false')
    py_versions = ('3.0', '3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8')
    if not opts.channel_dir.strip():
        print('Missing --channel-dir argument. Run --help for details')
        raise SystemExit(1)
    if opts.win_down.lower() not in bool_str:
        print('Incorrect --windows-download argument. Run --help for details')
        raise SystemExit(1)
    if opts.linux_down.lower() not in bool_str:
        print('Incorrect --linux-download argument. Run --help for details')
        raise SystemExit(1)
    if opts.mac_down.lower() not in bool_str:
        print('Incorrect --mac-download argument. Run --help for details')
        raise SystemExit(1)
    if opts.py_version.strip() not in py_versions:
        print('Incorrect --python-version argument. Run --help for details')
        raise SystemExit(1)
    
    cr_obj = CondaRepo(opts.py_version.strip(),
                       opts.win_down.lower(),
                       opts.linux_down.lower(),
                       opts.mac_down.lower())
    cr_obj.output_path = opts.channel_dir.strip()

    cr_obj.start_download()

start()

Once a channel is established, any user can access it and install the required libraries. Users need to have a local miniconda installation. Conda needs to be set to find the created channel, not a remote repository on the Internet. To do this, locate in the user's home directory. condarc must look like this:

channels:
  - http://path/to_my/conda_channel/main/
  - http://path/to_my/conda_channel/free/

At this point, the user can create a python 3.8 environment and install the library as described above.

Install Matplotlib

Matplotlib is a 2D drawing library.

To install Matplotlib, execute in the conda environment you created earlier:

conda install matplotlib

The following example shows how to execute Matplolib code in ANSA or META:

import ansa
import sys

CONDA_ENV = '/home/my_name/miniconda3/envs/python38/lib/python3.8/site-packages'
sys.path.append(CONDA_ENV)


import matplotlib
from matplotlib import pyplot as plt

def my_plot():
    x_vals = [0.2, 0.7, 1.2, 2.7, 3.5]
    y_vals = [1.2, 1.8, 2.4, 3.9, 4.5]

    plt.suptitle('My Graph')
    ax = plt.subplot('111')
    ax.plot(x_vals, y_vals)
    plt.show()

Other Libraries

Other libraries can be installed and imported into ANSA or META. For example: Pandas, SymPy, etc.

Note:
When searching for and installing a new library in the Conda environment, special care should be taken to ensure that the library is compatible with Python 3.8.

This tutorial is from the help documentation for ANSA21

Scan the QR code below to pay attention to my WeChat Public Number - CAE software redevelopment Lab, read more exciting content!

Secondary Development of CAE Software Lab

Added by jmosterb on Sat, 19 Feb 2022 01:17:09 +0200