#!/usr/bin/env python3

# A sample training component that trains a simple scikit-learn decision tree model.
# This implementation works in File mode and makes no assumptions about the input file names.
# Input is specified as CSV with a data point in each row and the labels in the first column.


import os
import json
import tarfile
import pickle
import sys
import traceback
import time
import subprocess
import shutil

import pandas as pd

# These are the paths to where SageMaker mounts interesting things in your container.

prefix = '/opt/ml/'

input_path = prefix + 'input/data'
output_path = os.path.join(prefix, 'output')
model_path = os.path.join(prefix, 'model')
input_model_path = os.path.join(input_path, 'model')
param_path = os.path.join(prefix, 'input/config/hyperparameters.json')

# This algorithm has a single channel of input data called 'training'. Since we run in
# File mode, the input files are copied to the directory specified here.
channel_name='training'
training_path = os.path.join(input_path, channel_name)


def json_cli(k, v):
    if len(k) > 1:
        param = '--' + k  
    else: 
        param = '-' + k
    v_str = str(v.rstrip(' '))
    if len(v_str):
        params = [param, v_str]
    else:
        params = [param]
    return params


def convert_json_params(dc):
    # params with no argument should be passed with just space string value ' '
    # aws seems to remove keys with empty string!
    #params = ' '.join([json_cli(k, v) for k, v in dc.items()])
    params = [p for k, v in dc.items() for p in json_cli(k, v)]
    return params


# The function to execute the training.
def train():
    print('Starting the training.')
    try:
        # Read in any hyperparameters that the user passed with the training job
        with open(param_path, 'r') as tc:
            pars_dc = json.load(tc)
        print('json hyperparams', pars_dc)
        print('directory contents')
        # for dirname, dirnames, filenames in os.walk(prefix, followlinks=True):
        #     # print path to all subdirectories first.
        #     for subdirname in dirnames:

        #         print('dir', os.path.join(dirname, subdirname))
        #         # print path to all filenames.

        #         for filename in filenames:
        #             print('file', os.path.join(dirname, filename))

        input_model_tar = os.path.join(input_model_path, 'model.tar.gz')
        input_model = os.path.join(input_model_path, 'model.bin')
        #model_files = [file for file in os.listdir(input_model_path)]
        #print('model files:', model_files)
        model = os.path.join(model_path, 'model.bin')
        
        vw_param_list = convert_json_params(pars_dc)
        
        vw_command = ['vw','--final_regressor', model] + vw_param_list
        if os.path.exists(input_model_tar):
            tar = tarfile.open(input_model_tar, "r:gz")
            tar.extractall(path = input_model_path)
            tar.close()
            vw_command += ['--initial_regressor', input_model]
        print ('vw command:', vw_command)
        # Note that hyperparameters are always passed in as
        # strings, so we need to do any necessary conversions.

        # TODO should we create the model filename/ data file or expect in params?

        # Take the set of files and read them all into a single pandas dataframe
        input_files = [os.path.join(training_path, file) 
                       for file in os.listdir(training_path)]
        print('input files', input_files)
        if len(input_files) == 0:
            raise ValueError(('There are no files in {}.\n' +
                              'This usually indicates that the channel ({}) was incorrectly specified,\n' +
                              'the data specification in S3 was incorrectly specified or the role specified\n' +
                              'does not have permission to access the data.').format(training_path, channel_name))
        start_time = time.time()
        p = subprocess.Popen(vw_command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             cwd=training_path)
        with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
            for line in iter(p.stdout.readline, b''):
                lin = line.decode('utf-8').rstrip()
                print(lin)
                print(lin, file=out)

        # timeout in seconds
        #with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
        #    out.write(stderr)
        #print(stderr)
        duration = time.time() - start_time
        print('Training complete in {} seconds.'.format(duration))
        data_file = pars_dc.get('data', pars_dc.get('d'))
        if data_file and pars_dc.get('noop') and pars_dc.get('cache', pars_dc.get('c')):
            cache_src = os.path.join(training_path, data_file + '.cache')
            cache_dst = os.path.join(model_path,
                                     os.path.basename(cache_src))
            shutil.copyfile(cache_src, cache_dst)
    except Exception as e:
        # Write out an error file. This will be returned as the failureReason in the
        # DescribeTrainingJob result.
        trc = traceback.format_exc()
        with open(os.path.join(output_path, 'failure'), 'w') as s:
            s.write('Exception during training: ' + str(e) + '\n' + trc)
        # Printing this causes the exception to be in the training job logs, as well.
        print('Exception during training: ' + str(e) + '\n' + trc, file=sys.stderr)
        # A non-zero exit code causes the training job to be marked as Failed.
        sys.exit(255)

if __name__ == '__main__':
    train()

    # A zero exit code causes the job to be marked a Succeeded.
    sys.exit(0)

b363a67fe7f49fd8d3569ce01052c7787e8b9a4c
<mask token>


def json_cli(k, v):
    if len(k) > 1:
        param = '--' + k
    else:
        param = '-' + k
    v_str = str(v.rstrip(' '))
    if len(v_str):
        params = [param, v_str]
    else:
        params = [param]
    return params


<mask token>


def train():
    print('Starting the training.')
    try:
        with open(param_path, 'r') as tc:
            pars_dc = json.load(tc)
        print('json hyperparams', pars_dc)
        print('directory contents')
        input_model_tar = os.path.join(input_model_path, 'model.tar.gz')
        input_model = os.path.join(input_model_path, 'model.bin')
        model = os.path.join(model_path, 'model.bin')
        vw_param_list = convert_json_params(pars_dc)
        vw_command = ['vw', '--final_regressor', model] + vw_param_list
        if os.path.exists(input_model_tar):
            tar = tarfile.open(input_model_tar, 'r:gz')
            tar.extractall(path=input_model_path)
            tar.close()
            vw_command += ['--initial_regressor', input_model]
        print('vw command:', vw_command)
        input_files = [os.path.join(training_path, file) for file in os.
            listdir(training_path)]
        print('input files', input_files)
        if len(input_files) == 0:
            raise ValueError(('There are no files in {}.\n' +
                """This usually indicates that the channel ({}) was incorrectly specified,
"""
                 +
                'the data specification in S3 was incorrectly specified or the role specified\n'
                 + 'does not have permission to access the data.').format(
                training_path, channel_name))
        start_time = time.time()
        p = subprocess.Popen(vw_command, stdout=subprocess.PIPE, stderr=
            subprocess.STDOUT, cwd=training_path)
        with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
            for line in iter(p.stdout.readline, b''):
                lin = line.decode('utf-8').rstrip()
                print(lin)
                print(lin, file=out)
        duration = time.time() - start_time
        print('Training complete in {} seconds.'.format(duration))
        data_file = pars_dc.get('data', pars_dc.get('d'))
        if data_file and pars_dc.get('noop') and pars_dc.get('cache',
            pars_dc.get('c')):
            cache_src = os.path.join(training_path, data_file + '.cache')
            cache_dst = os.path.join(model_path, os.path.basename(cache_src))
            shutil.copyfile(cache_src, cache_dst)
    except Exception as e:
        trc = traceback.format_exc()
        with open(os.path.join(output_path, 'failure'), 'w') as s:
            s.write('Exception during training: ' + str(e) + '\n' + trc)
        print('Exception during training: ' + str(e) + '\n' + trc, file=sys
            .stderr)
        sys.exit(255)


<mask token>

<mask token>


def json_cli(k, v):
    if len(k) > 1:
        param = '--' + k
    else:
        param = '-' + k
    v_str = str(v.rstrip(' '))
    if len(v_str):
        params = [param, v_str]
    else:
        params = [param]
    return params


def convert_json_params(dc):
    params = [p for k, v in dc.items() for p in json_cli(k, v)]
    return params


def train():
    print('Starting the training.')
    try:
        with open(param_path, 'r') as tc:
            pars_dc = json.load(tc)
        print('json hyperparams', pars_dc)
        print('directory contents')
        input_model_tar = os.path.join(input_model_path, 'model.tar.gz')
        input_model = os.path.join(input_model_path, 'model.bin')
        model = os.path.join(model_path, 'model.bin')
        vw_param_list = convert_json_params(pars_dc)
        vw_command = ['vw', '--final_regressor', model] + vw_param_list
        if os.path.exists(input_model_tar):
            tar = tarfile.open(input_model_tar, 'r:gz')
            tar.extractall(path=input_model_path)
            tar.close()
            vw_command += ['--initial_regressor', input_model]
        print('vw command:', vw_command)
        input_files = [os.path.join(training_path, file) for file in os.
            listdir(training_path)]
        print('input files', input_files)
        if len(input_files) == 0:
            raise ValueError(('There are no files in {}.\n' +
                """This usually indicates that the channel ({}) was incorrectly specified,
"""
                 +
                'the data specification in S3 was incorrectly specified or the role specified\n'
                 + 'does not have permission to access the data.').format(
                training_path, channel_name))
        start_time = time.time()
        p = subprocess.Popen(vw_command, stdout=subprocess.PIPE, stderr=
            subprocess.STDOUT, cwd=training_path)
        with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
            for line in iter(p.stdout.readline, b''):
                lin = line.decode('utf-8').rstrip()
                print(lin)
                print(lin, file=out)
        duration = time.time() - start_time
        print('Training complete in {} seconds.'.format(duration))
        data_file = pars_dc.get('data', pars_dc.get('d'))
        if data_file and pars_dc.get('noop') and pars_dc.get('cache',
            pars_dc.get('c')):
            cache_src = os.path.join(training_path, data_file + '.cache')
            cache_dst = os.path.join(model_path, os.path.basename(cache_src))
            shutil.copyfile(cache_src, cache_dst)
    except Exception as e:
        trc = traceback.format_exc()
        with open(os.path.join(output_path, 'failure'), 'w') as s:
            s.write('Exception during training: ' + str(e) + '\n' + trc)
        print('Exception during training: ' + str(e) + '\n' + trc, file=sys
            .stderr)
        sys.exit(255)


<mask token>

<mask token>
prefix = '/opt/ml/'
input_path = prefix + 'input/data'
output_path = os.path.join(prefix, 'output')
model_path = os.path.join(prefix, 'model')
input_model_path = os.path.join(input_path, 'model')
param_path = os.path.join(prefix, 'input/config/hyperparameters.json')
channel_name = 'training'
training_path = os.path.join(input_path, channel_name)


def json_cli(k, v):
    if len(k) > 1:
        param = '--' + k
    else:
        param = '-' + k
    v_str = str(v.rstrip(' '))
    if len(v_str):
        params = [param, v_str]
    else:
        params = [param]
    return params


def convert_json_params(dc):
    params = [p for k, v in dc.items() for p in json_cli(k, v)]
    return params


def train():
    print('Starting the training.')
    try:
        with open(param_path, 'r') as tc:
            pars_dc = json.load(tc)
        print('json hyperparams', pars_dc)
        print('directory contents')
        input_model_tar = os.path.join(input_model_path, 'model.tar.gz')
        input_model = os.path.join(input_model_path, 'model.bin')
        model = os.path.join(model_path, 'model.bin')
        vw_param_list = convert_json_params(pars_dc)
        vw_command = ['vw', '--final_regressor', model] + vw_param_list
        if os.path.exists(input_model_tar):
            tar = tarfile.open(input_model_tar, 'r:gz')
            tar.extractall(path=input_model_path)
            tar.close()
            vw_command += ['--initial_regressor', input_model]
        print('vw command:', vw_command)
        input_files = [os.path.join(training_path, file) for file in os.
            listdir(training_path)]
        print('input files', input_files)
        if len(input_files) == 0:
            raise ValueError(('There are no files in {}.\n' +
                """This usually indicates that the channel ({}) was incorrectly specified,
"""
                 +
                'the data specification in S3 was incorrectly specified or the role specified\n'
                 + 'does not have permission to access the data.').format(
                training_path, channel_name))
        start_time = time.time()
        p = subprocess.Popen(vw_command, stdout=subprocess.PIPE, stderr=
            subprocess.STDOUT, cwd=training_path)
        with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
            for line in iter(p.stdout.readline, b''):
                lin = line.decode('utf-8').rstrip()
                print(lin)
                print(lin, file=out)
        duration = time.time() - start_time
        print('Training complete in {} seconds.'.format(duration))
        data_file = pars_dc.get('data', pars_dc.get('d'))
        if data_file and pars_dc.get('noop') and pars_dc.get('cache',
            pars_dc.get('c')):
            cache_src = os.path.join(training_path, data_file + '.cache')
            cache_dst = os.path.join(model_path, os.path.basename(cache_src))
            shutil.copyfile(cache_src, cache_dst)
    except Exception as e:
        trc = traceback.format_exc()
        with open(os.path.join(output_path, 'failure'), 'w') as s:
            s.write('Exception during training: ' + str(e) + '\n' + trc)
        print('Exception during training: ' + str(e) + '\n' + trc, file=sys
            .stderr)
        sys.exit(255)


if __name__ == '__main__':
    train()
    sys.exit(0)

import os
import json
import tarfile
import pickle
import sys
import traceback
import time
import subprocess
import shutil
import pandas as pd
prefix = '/opt/ml/'
input_path = prefix + 'input/data'
output_path = os.path.join(prefix, 'output')
model_path = os.path.join(prefix, 'model')
input_model_path = os.path.join(input_path, 'model')
param_path = os.path.join(prefix, 'input/config/hyperparameters.json')
channel_name = 'training'
training_path = os.path.join(input_path, channel_name)


def json_cli(k, v):
    if len(k) > 1:
        param = '--' + k
    else:
        param = '-' + k
    v_str = str(v.rstrip(' '))
    if len(v_str):
        params = [param, v_str]
    else:
        params = [param]
    return params


def convert_json_params(dc):
    params = [p for k, v in dc.items() for p in json_cli(k, v)]
    return params


def train():
    print('Starting the training.')
    try:
        with open(param_path, 'r') as tc:
            pars_dc = json.load(tc)
        print('json hyperparams', pars_dc)
        print('directory contents')
        input_model_tar = os.path.join(input_model_path, 'model.tar.gz')
        input_model = os.path.join(input_model_path, 'model.bin')
        model = os.path.join(model_path, 'model.bin')
        vw_param_list = convert_json_params(pars_dc)
        vw_command = ['vw', '--final_regressor', model] + vw_param_list
        if os.path.exists(input_model_tar):
            tar = tarfile.open(input_model_tar, 'r:gz')
            tar.extractall(path=input_model_path)
            tar.close()
            vw_command += ['--initial_regressor', input_model]
        print('vw command:', vw_command)
        input_files = [os.path.join(training_path, file) for file in os.
            listdir(training_path)]
        print('input files', input_files)
        if len(input_files) == 0:
            raise ValueError(('There are no files in {}.\n' +
                """This usually indicates that the channel ({}) was incorrectly specified,
"""
                 +
                'the data specification in S3 was incorrectly specified or the role specified\n'
                 + 'does not have permission to access the data.').format(
                training_path, channel_name))
        start_time = time.time()
        p = subprocess.Popen(vw_command, stdout=subprocess.PIPE, stderr=
            subprocess.STDOUT, cwd=training_path)
        with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
            for line in iter(p.stdout.readline, b''):
                lin = line.decode('utf-8').rstrip()
                print(lin)
                print(lin, file=out)
        duration = time.time() - start_time
        print('Training complete in {} seconds.'.format(duration))
        data_file = pars_dc.get('data', pars_dc.get('d'))
        if data_file and pars_dc.get('noop') and pars_dc.get('cache',
            pars_dc.get('c')):
            cache_src = os.path.join(training_path, data_file + '.cache')
            cache_dst = os.path.join(model_path, os.path.basename(cache_src))
            shutil.copyfile(cache_src, cache_dst)
    except Exception as e:
        trc = traceback.format_exc()
        with open(os.path.join(output_path, 'failure'), 'w') as s:
            s.write('Exception during training: ' + str(e) + '\n' + trc)
        print('Exception during training: ' + str(e) + '\n' + trc, file=sys
            .stderr)
        sys.exit(255)


if __name__ == '__main__':
    train()
    sys.exit(0)

#!/usr/bin/env python3

# A sample training component that trains a simple scikit-learn decision tree model.
# This implementation works in File mode and makes no assumptions about the input file names.
# Input is specified as CSV with a data point in each row and the labels in the first column.


import os
import json
import tarfile
import pickle
import sys
import traceback
import time
import subprocess
import shutil

import pandas as pd

# These are the paths to where SageMaker mounts interesting things in your container.

prefix = '/opt/ml/'

input_path = prefix + 'input/data'
output_path = os.path.join(prefix, 'output')
model_path = os.path.join(prefix, 'model')
input_model_path = os.path.join(input_path, 'model')
param_path = os.path.join(prefix, 'input/config/hyperparameters.json')

# This algorithm has a single channel of input data called 'training'. Since we run in
# File mode, the input files are copied to the directory specified here.
channel_name='training'
training_path = os.path.join(input_path, channel_name)


def json_cli(k, v):
    if len(k) > 1:
        param = '--' + k  
    else: 
        param = '-' + k
    v_str = str(v.rstrip(' '))
    if len(v_str):
        params = [param, v_str]
    else:
        params = [param]
    return params


def convert_json_params(dc):
    # params with no argument should be passed with just space string value ' '
    # aws seems to remove keys with empty string!
    #params = ' '.join([json_cli(k, v) for k, v in dc.items()])
    params = [p for k, v in dc.items() for p in json_cli(k, v)]
    return params


# The function to execute the training.
def train():
    print('Starting the training.')
    try:
        # Read in any hyperparameters that the user passed with the training job
        with open(param_path, 'r') as tc:
            pars_dc = json.load(tc)
        print('json hyperparams', pars_dc)
        print('directory contents')
        # for dirname, dirnames, filenames in os.walk(prefix, followlinks=True):
        #     # print path to all subdirectories first.
        #     for subdirname in dirnames:

        #         print('dir', os.path.join(dirname, subdirname))
        #         # print path to all filenames.

        #         for filename in filenames:
        #             print('file', os.path.join(dirname, filename))

        input_model_tar = os.path.join(input_model_path, 'model.tar.gz')
        input_model = os.path.join(input_model_path, 'model.bin')
        #model_files = [file for file in os.listdir(input_model_path)]
        #print('model files:', model_files)
        model = os.path.join(model_path, 'model.bin')
        
        vw_param_list = convert_json_params(pars_dc)
        
        vw_command = ['vw','--final_regressor', model] + vw_param_list
        if os.path.exists(input_model_tar):
            tar = tarfile.open(input_model_tar, "r:gz")
            tar.extractall(path = input_model_path)
            tar.close()
            vw_command += ['--initial_regressor', input_model]
        print ('vw command:', vw_command)
        # Note that hyperparameters are always passed in as
        # strings, so we need to do any necessary conversions.

        # TODO should we create the model filename/ data file or expect in params?

        # Take the set of files and read them all into a single pandas dataframe
        input_files = [os.path.join(training_path, file) 
                       for file in os.listdir(training_path)]
        print('input files', input_files)
        if len(input_files) == 0:
            raise ValueError(('There are no files in {}.\n' +
                              'This usually indicates that the channel ({}) was incorrectly specified,\n' +
                              'the data specification in S3 was incorrectly specified or the role specified\n' +
                              'does not have permission to access the data.').format(training_path, channel_name))
        start_time = time.time()
        p = subprocess.Popen(vw_command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             cwd=training_path)
        with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
            for line in iter(p.stdout.readline, b''):
                lin = line.decode('utf-8').rstrip()
                print(lin)
                print(lin, file=out)

        # timeout in seconds
        #with open(os.path.join(model_path, 'results_log.txt'), 'w') as out:
        #    out.write(stderr)
        #print(stderr)
        duration = time.time() - start_time
        print('Training complete in {} seconds.'.format(duration))
        data_file = pars_dc.get('data', pars_dc.get('d'))
        if data_file and pars_dc.get('noop') and pars_dc.get('cache', pars_dc.get('c')):
            cache_src = os.path.join(training_path, data_file + '.cache')
            cache_dst = os.path.join(model_path,
                                     os.path.basename(cache_src))
            shutil.copyfile(cache_src, cache_dst)
    except Exception as e:
        # Write out an error file. This will be returned as the failureReason in the
        # DescribeTrainingJob result.
        trc = traceback.format_exc()
        with open(os.path.join(output_path, 'failure'), 'w') as s:
            s.write('Exception during training: ' + str(e) + '\n' + trc)
        # Printing this causes the exception to be in the training job logs, as well.
        print('Exception during training: ' + str(e) + '\n' + trc, file=sys.stderr)
        # A non-zero exit code causes the training job to be marked as Failed.
        sys.exit(255)

if __name__ == '__main__':
    train()

    # A zero exit code causes the job to be marked a Succeeded.
    sys.exit(0)
