# Python models

To create a python model, following steps are advised:

## Define model input data

Variables consumed by model must be defined in `csv` format

{% code title="model.csv" lineNumbers="true" %}
```csv
true;x1;STRING;;	
true;x2;DOUBLE;;
true;x3;INTEGER;;
true;x4;MAP;;
false;x5;VECTOR;;
true;x6;BOOLEAN;;sample description
```
{% endcode %}

Each line contains information about one variable including

* field required indicator
* variable name
* variable type
* list of enum values
* optional description

Alternatively, python script to create file can be used

{% code lineNumbers="true" %}
```python
# Create .csv file with SCE parameters.
vars_def = """
true;x1;STRING;;	
true;x2;DOUBLE;;
true;x3;INTEGER;;
true;x4;MAP;;
false;x5;VECTOR;;
true;x6;BOOLEAN;;sample description
"""

model_file = open('./model.csv', 'wt')
model_file.write(vars_def)
model_file.close()
```
{% endcode %}

## Serialize model

Model object must be saved into `pickle` file. Minimally the output structure of the model must be defined. Common machine learning libraries for instance `sklearn` , `xgboost`are supproted as well.

<pre class="language-python" data-overflow="wrap" data-line-numbers><code class="lang-python">import pickle

<strong>model_object = {
</strong><strong>    'SCORE_RAW': 100,
</strong><strong>    'SCORE_CUT': 100,
</strong><strong>    'SCORE_RANK': 100,
</strong><strong>    'SCORE_NORMAL': 100
</strong><strong>}
</strong>with open('./model.pkl', 'wb') as model_file:
    pickle.dump(model_object, model_file)
model_file.close()
</code></pre>

## Prepare scoring script

Usually some data processing is needed. Thus in python script such operations can be prepared. Scoring `.py` script is obligatory and model object must be always returned.

{% code title="model.py" lineNumbers="true" %}
```python
import pandas as pd
import random

# variables are automatically loaded
# Load map variables to Dataframe
df = pd.DataFrame(x4['table'])

# some data processing can be added here
# df  = transformations(df)

model_object = {
    'SCORE_RAW': 100,
    'SCORE_CUT': 100,
    'SCORE_RANK': 100,
    'SCORE_NORMAL': 100
}

# another processing transformations
# for example replace scores with random value
for key in model_object:
    model_object[key] = random.randint(1, 100)

# model object need to be retuned
return model_object
```
{% endcode %}

## Upload model to Scoring One

Previously creaded 3 files: `model.csv`, `model.plk`, `model.py` must be packed together into one `zip` file to be able to send to Scoring One.

{% code lineNumbers="true" %}
```python
import zipfile

# Create .zip file to send it to SCE.
zf = zipfile.ZipFile(r"./model.zip", "w")
zf.write(r'./model.csv')
zf.write(r'./model.py')
zf.write(r'./model.pkl')
zf.close()
```
{% endcode %}

Then set up enviromental variables before sending request

{% code lineNumbers="true" %}
```python
api_environment_url_str = 'https://demo.scoring.one'
api_environment_key_str = '<your_key>'
scoring_code_name_str = 'model_python'
```
{% endcode %}

Finally use `requests` library to POST the data

```python
import datetime
import requests

date_processing_str = datetime.datetime.now().strftime('%Y-%m-%d')
api_url_str = "{}/api/python/code/create".format(api_environment_url_str)
headers_dict = {'Authorization': 'Bearer {}'.format(api_environment_key_str)}
params_dict = {
    'dateFrom': date_processing_str,
    'dateTo': date_processing_str,
    'fileName': 'model.zip',
    'scoringCodeName': scoring_code_name_str,
    'charset': 'UTF-8'
}

fileobj = open(r'./model.zip', 'rb')
response = requests.post(api_url_str,
                         params = params_dict,
                         files={"file": ("./model.zip", fileobj)},
                         headers=headers_dict)
print(response.text)
fileobj.close()
```
