def listmodel(key=None):
    global base_repo
    global model_repo_host
    printmsg("Getting model list...")
    try:
        mmAuth = mmAuthorization.mmAuthorization("myAuth")
        authToken = mmAuth.getAuthToken(model_repo_host)
        headers = {
            mmAuthorization.AUTHORIZATION_HEADER:
            mmAuthorization.AUTHORIZATION_TOKEN + authToken
        }
    except:
        raise RuntimeError("ERROR! Failed to auth token")

    models_url = model_repo_host + "/modelRepository/models?limit=999&start=0"
    try:
        response = requests.get(models_url, headers=headers)
        jsondata = response.json()
        models = jsondata['items']
        if len(models) > 0:
            for model in models:
                #print(model)
                model_name = model['name']
                model_name = model_name.lower()
                model_id = model['id']
                model_version = model['modelVersionName']
                if key != None:
                    key = key.lower()
                # ignore if there's partial key and the model name doesn't have the key (case insensitive)
                if key != None and key != 'all' and key not in model_name:
                    continue
                print("Model name", model_name)
                print("Model UUID", model_id)
                print("Model version", model_version)
                if 'projectName' in model.keys(
                ) and model['projectName'] != None:
                    print("Project name", model['projectName'])
                if 'scoreCodeType' in model.keys():
                    print("Score Code Type", model['scoreCodeType'])
                else:
                    print('Warning! No score code type defined!')
                model_name = slugify(model_name)
                tagname = model_name + '_' + model_id
                repo = base_repo + tagname + ":latest"
                # TODO compare the model version with the image version
                print("Image URL (not verified):", repo)
                print("==========================")
        printmsg("Guides: > python mm_docker_cli.py publish <uuid>")
        printmsg("Guides: > python mm_docker_cli.py launch <image url>")
        printmsg(
            "Guides: > python mm_docker_cli.py score <image url> <input file>")
    except:
        raise RuntimeError("ERROR! Failed to get model list")
    def download_model_content(self, model_id):
        print("Downloading model", model_id, "from model repository...")

        # images folder under the current directory
        data_path = os.path.join(self.cur_path, 'images')
        if not os.path.exists(data_path):
            os.makedirs(data_path)
        self.print_msg("Images folder:", data_path)

        filename = "model-"+model_id+".zip"
        # remove extension
        dirname = os.path.splitext(filename)[0]
        # must be lowercase
        dirname = dirname.lower()

        subfolder = os.path.join(data_path, dirname)
        if not os.path.exists(subfolder):
            os.makedirs(subfolder)

        model_file_full_path = os.path.join(subfolder, filename)

        try:
            mm_auth = mmAuthorization.mmAuthorization("myAuth")
            auth_token = mm_auth.get_auth_token(self.model_repo_host)
            headers = {
                mmAuthorization.AUTHORIZATION_HEADER: mmAuthorization.AUTHORIZATION_TOKEN + auth_token
            }
        except:
            raise RuntimeError("ERROR! Failed to auth token")

        model_url = self.model_repo_host + "/modelRepository/models/"+model_id
        try:
            # http://<host>/modelRepository/models/d00bb4e3-0672-4e9a-a877-39249d2a98ab?format=zip
            result_url = model_url+"?format=zip"
            r = requests.get(result_url, allow_redirects=True, headers=headers)
            # print(r.status_code)
            if r.status_code == 404:
                raise RuntimeError("ERROR! Failed to get model file")

            open(model_file_full_path, 'wb').write(r.content)
            self.print_msg("Model zip file has been downloaded at", model_file_full_path)
        except:
            raise RuntimeError("ERROR! Failed to get model file")

        # copy astore file if it is an astore model
        self.copy_astore(subfolder, model_file_full_path, model_id)

        model_name, version_id, code_type = self.retrieve_model_info(model_url, headers)
        return model_file_full_path, model_name, version_id, code_type
    def download_model_astore(self, model_id, astore_name):
        try:
            mm_auth = mmAuthorization.mmAuthorization("myAuth")
            auth_token = mm_auth.get_auth_token(self.model_repo_host)
            headers = {
                "Accept": "application/vnd.sas.model.analytic.store+json",
                mmAuthorization.AUTHORIZATION_HEADER: mmAuthorization.AUTHORIZATION_TOKEN + auth_token
            }
        except:
            raise RuntimeError("ERROR! Failed to auth token")

        request_url = self.model_repo_host + f"/modelRepository/models/{model_id}/analyticStore/{astore_name}"

        try:
            r = requests.put(request_url, headers=headers)
            # print(r.status_code)
            if r.status_code != 202:
                raise RuntimeError("ERROR! Failed to generate astore file")

        except:
            raise RuntimeError("ERROR! Failed to generate astore file")

        return
# Copyright (c) 2020, SAS Institute Inc., Cary, NC, USA.  All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

import mmAuthorization
import requests
import json

viya_host = "localhost"
port = ":8080"
host_url="http://" + viya_host + port
destination_url = host_url + "/modelPublish/destinations/"

mm_auth = mmAuthorization.mmAuthorization("myAuth")

# admin user id and password
admin_userId = "SAS_USER_ADMIN_ID"
user_passwd = "SAS_USER_PASSWD"

# the domain which the SAS Credential Service stores AWS credentials
DOMAIN_NAME = "Domain Name"

# the kubernetes cluster name
K8S_NAME = "K8s Name"

# destination name
dest_name = "MY_AWS_DEST_NAME"

# AWS region
AWS_REGION = "us-east-1"

# the docker daemon is running on tcp socket
def publish(model_id):
    """
 * Get model by model_id and always getting the latest version.
 * Get model by name, project, version, repository, etc
 * Retrieve model zip file from model respository, such as modelxxxxxx.zip
 * Get astore by scp temporarily until the other method is ready to pull astore file from the SAS server
 * create subfolder <tag>, and store zip file and template files in subfolder
 * return image url if succeed
    """
    global model_repo_host

    if model_id is None:
        raise RuntimeError('Error! Model UUID is empty')

    print("Downloading model", model_id, "from model repository...")

    # images folder under the current directory
    data_path = os.path.join(cur_path, 'images')
    if not os.path.exists(data_path):
        os.makedirs(data_path)
    printmsg("Images folder:", data_path)

    filename = "model-" + model_id + ".zip"
    # remove extension
    tmpname = os.path.splitext(filename)[0]
    # must be lowercase
    tmpname = tmpname.lower()

    subfolder = os.path.join(data_path, tmpname)
    if not os.path.exists(subfolder):
        os.makedirs(subfolder)

    model_file_full_path = os.path.join(subfolder, filename)

    try:
        mmAuth = mmAuthorization.mmAuthorization("myAuth")
        authToken = mmAuth.getAuthToken(model_repo_host)
        headers = {
            mmAuthorization.AUTHORIZATION_HEADER:
            mmAuthorization.AUTHORIZATION_TOKEN + authToken
        }
    except:
        raise RuntimeError("ERROR! Failed to auth token")

    model_url = model_repo_host + "/modelRepository/models/" + model_id
    try:
        #http://<host>/modelRepository/models/d00bb4e3-0672-4e9a-a877-39249d2a98ab?format=zip
        result_url = model_url + "?format=zip"
        r = requests.get(result_url, allow_redirects=True, headers=headers)
        #print(r.status_code)
        if r.status_code == 404:
            raise RuntimeError("ERROR! Failed to get model file")

        open(model_file_full_path, 'wb').write(r.content)
        printmsg("Model zip file has been downloaded at", model_file_full_path)
    except:
        raise RuntimeError("ERROR! Failed to get model file")

    # get model_name, version_id, code_type too
    model_name, version_id, code_type = retrieve_model_info(model_url, headers)

    # verify meta data
    if model_name == None or version_id == None:
        raise RuntimeError('Unable to retrieve model name or current version!')

    model_name = slugify(model_name)
    printmsg("The name has been normalized to", model_name)

    if code_type == 'python' or code_type == 'Python':
        template_folder_name = 'template-py'  # pyml-base
    elif code_type == 'R' or code_type == 'r':
        template_folder_name = 'template-r'  # r-base
    else:
        template_folder_name = 'template'  # maspy-base

    template_folder = os.path.join(cur_path, template_folder_name)
    if not os.path.exists(template_folder):
        raise RuntimeError("Template folder not existed!")

    dockerfile = os.path.join(template_folder, 'Dockerfile')
    # make sure that one of files is named after Dockerfile
    if not os.path.isfile(dockerfile):
        raiseError("There's no Dockerfile under template folder")

    printmsg("Template folder:", template_folder)

    # copy template files into subfolder
    src_files = os.listdir(template_folder)
    for file_name in src_files:
        full_file_name = os.path.join(template_folder, file_name)
        if (os.path.isfile(full_file_name)):
            shutil.copy(full_file_name, subfolder)

    # download astore file if available
    copy_astore(subfolder, model_file_full_path)

    # read requirements.json from zip file if available
    # and include the dependency lines in Dockerfile
    handle_dependencies(subfolder, model_file_full_path)

    tagname = model_name + '_' + model_id

    local_tag = tagname + ':' + version_id
    local_tag_latest = tagname + ':latest'

    # build local image with docker daemon
    client = docker.from_env()

    print("Building image...")
    printmsg(local_tag)
    myimage, _ = client.images.build(path=subfolder,
                                     tag=local_tag,
                                     nocache=True)
    # tag it as latest version too
    printmsg(local_tag_latest)
    #    myimage.tag(local_tag_latest)
    myimage.tag(tagname, "latest")

    printmsg("Tag the image into a repository", myimage.short_id)
    remote_version_latest = push_to_repo(myimage, tagname, version_id)

    printmsg("==========================")
    printmsg("Guides: > python mm_docker_cli.py launch", remote_version_latest)
    printmsg("Guides: > python mm_docker_cli.py score", remote_version_latest,
             "<input file>")
    log('publish', model_id, version_id, remote_version_latest)
    return (remote_version_latest)