Repository: scailable/sclblpy (language: python)

Issue:
F/remove sklarn
+ removed dependency on Sklearn etc, in setup.py and all the places where I could find it
+ removed run() and other pieces of the API that aren't supposed to be used any more
+ made sure the tests cover the use cases
+ added notebook that showcases the use of the package (can be used as secondary testing)


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index f14aa70..ffc8ace 100644
--- a/.gitignore
+++ b/.gitignore
@@ -144,3 +144,10 @@ example.py
 example2.py
 example3.py
 test_all_models.py
+
+
+#jupyter stuff
+.ipynb_checkpoints
+
+# .onnx models
+*.onnx
\ No newline at end of file
diff --git a/README.md b/README.md
index 93082bb..06fa36c 100644
--- a/README.md
+++ b/README.md
@@ -2,63 +2,73 @@
 
 [![PyPI Release](https://github.com/scailable/sclblpy/workflows/PyPI%20Release/badge.svg)](https://pypi.org/project/sclblpy/)
 
-`sclblpy` is the core python package provided by Scailable to convert models fit in python to WebAssembly and
-open them up as a REST endpoint.
 
-Currently the package supports the upload of fitted `sklearn` model objects, and it supports uploading `.onnx` models
-(by specifying a path to the `.onnx` file). The package can also be used to manage assignments of models to 
-registered devices. 
+Changelog: the package is currently being refactored. As such, it is currently a stub, as Scailable has changed its focus from Scikit Learn to ONNX, Scikit Learn support has been removed.
+1. Removal of support for additional packages - most importantly in the 'upload()' function which now will throw an error if `model_type` isn't onnx
+2. the `run()` function is going to be replaced by a function that allows the user to test their local setup; and as such is a stub
+
+
+`sclblpy` is the core python package provided by Scailable for interacting with our API. The scope of this package is (roughly):
+1. upload an `.onnx` model to the admin console
+2. Assign and deploy the uploaded model to a device that has previously been installed with the Scailable runtime and registered
+3. (upcoming) test device deployment
+
+
+
+
+Also, there will probably be breaking changes in the API in one of the upcoming releases, for more information see [our API documentation](https://docs.sclbl.net/).
+
 
 `sclblpy` is only functional in combination with a valid Scailable user account.
 
 - **Website:** [https://www.scailable.net](https://www.scailable.net)
 - **Docs:**
-   - On github: [https://github.com/scailable/sclblpy](https://github.com/scailable/sclblpy/blob/master/README.md)
+   - On GitHub (you are here): [https://github.com/scailable/sclblpy](https://github.com/scailable/sclblpy/blob/master/README.md)
    - On pypi: [https://docs.sclbl.net/sclblpy](https://docs.sclbl.net/sclblpy)
    - API docs Scailable: [https://docs.sclbl.net](https://docs.sclbl.net)
-- **Get an account:** [https://www.scailable.net](https://www.scailable.net?access-code=sclblpy-installation)
-- **Source:** [https://github.com/scailable/sclblpy/](https://github.com/scailable/sclblpy/)
-- **Getting started:** [https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started](https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started)
+- **Get an account:** [https://admin.sclbl.net/signup.html](https://admin.sclbl.net/signup.html) 
+- **Install the AI manager:**
+   - On any Linux device: [https://github.com/scailable/sclbl-tutorials/tree/master/solutions-manuals/sclbl-local-ai-manager](https://github.com/scailable/sclbl-tutorials/tree/master/solutions-manuals/sclbl-local-ai-manager)
+   - On an Advantech device: [https://github.com/scailable/sclbl-tutorials/tree/master/solutions-manuals](https://github.com/scailable/sclbl-tutorials/tree/master/solutions-manuals)
 
 ## Background
-The sclblpy package allows users with a valid scailable account (apply for one at [https://www.scailable.net](https://www.scailable.net))
+The sclblpy package allows users with a valid scailable account (get one at [https://admin.sclbl.net/signup.html](https://admin.sclbl.net/signup.html)) 
 to upload fitted ML / AI models to the Scailable toolchain server. This will result in:
 
-1. The model being tested on the client side.
+1. The model being tested for errors on the client side.
 2. The model being uploaded to Scailable, tested again, and if all test pass it will be converted to [WebAssembly](https://webassembly.org).
-3. The model being made available as an easy to access REST endpoint.
+3. The model being made available to deploy to a preregistered (link on how to do that) device
+4. (upcoming) The model being testable through test_run(example_input, device_id)
 
 ## Getting started
 
 The following functions are likely most used:
 
-### `sp.upload()` can be used to create model:
+### `sp.upload_onnx()` can be used to create model:
 ```python
-def upload(mod, features, docs={}, email=True, model_type="sklearn", _keep=False) -> bool:
-    """upload uploads a trained AI/ML model to Scailable.
+def upload_onnx(path, example="", docs={}, email=True) -> bool:
+    """upload_onnx uploads a fitted onnx model to Scailable.
 
-    The upload function is the main workhorse of the sclblpy package but effectively provides a
-    wrapper to choose between the
-     - upload_sklearn(mod, feature_vector, docs={}, email=True, _keep=False)
-     - upload_onnx(path, docs={}, email=True)
-    functions.
+    - The function first checks if the supplied path indeed references a .onnx file
+    - Next, the docs are checked; if none are provided a warning is issued and a simple
+    name is provided based on the model type.
+    - Finally the onnx file and the supporting docs are uploaded to the toolchain.
 
-    The function checks the type, and if type = "sklearn" (default) calls the upload_sklearn() function.
-    If type = "onnx" it calls the upload_onnx() function.
+    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
+        stop_print() method.
 
     Args:
-        mod: The model to be uploaded (type="sklearn" OR the path to the stored ONNX file (type="onnx").
-        features:
-            - An example feature_vector for your model (type="sklearn" only).
-            (i.e., the first row of your training data X obtained using row = X[0,:])
-            - The input str (binary) to the onnx model (type="onnx" only). Can be an empty string.
+        path: The path referencing the onnx model location (i.e., the .onnx file location).
+        example: String example input for the onnx file.
         docs: A dict{} containing the fields 'name' and 'documentation'.
         email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-        model_type: String indicating the type of model. Currently with options "sklearn" or "onnx". Default "sklearn"
-        _keep: Bool indicating whether the .gzipped file should be retained (type="sklearn" only). Default False.
 
     Returns:
-        False if upload failed, true otherwise"""
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    """
 ```
 `sp.models()` lists all created models, and `sp.delete_model()` can be used to delete a model. Finally, `sp.update()` can be used to
 overwrite / update an existing model.
@@ -81,120 +91,6 @@ def assign(cfid, did, rid, _verbose=True):
 ``` 
 `sp.assignments()` can be used to list current assignments, whereas `sp.delete_assignment()` can be used to delete an assignment. 
 
-## A simple example using `sklearn`
-After installing the package using `pip install sclblpy` you can easily fit a ML / AI model using your preferred tools and
-upload it to our toolchains. The following code block provides a simple example:
-
-````
-# Neccesary imports:
-import sclblpy as sp
-
-from sklearn import svm
-from sklearn import datasets
-
-# Start fitting a simple model:
-clf = svm.SVC()
-X, y = datasets.load_iris(return_X_y=True)
-clf.fit(X, y)
-
-# Create an example feature vector (required for sklearn models):
-row = X[130, :]
-
-# Create documentation (optional, but useful):
-docs = {}
-docs['name'] = "My first fitted model"
-docs['documentation'] = "Any documentation you would like to provide."
-
-# Upload the model:
-sp.upload(clf, row, docs=docs)
-````
-
-The call to `sp.upload()` will upload the fitted model, after running a number of local tests, to the 
-Scailable toolchain server and create an associated REST endpoint. Limited user feedback will be printed to show progress,
-and you will receive an email at the email address associated with your account when the conversion is fully completed (which might take a few minutes).
-This email also contains further details regarding the usage of your created endpoint.
-
-Note that upon first upload you will be prompted to provide your Scailable username and password; you can choose to
-store the provided credentials locally to enable easy login on subsequently uploads. (users can signup for an account at
- [https://www.scailable.net](https://www.scailable.net?access-code=sclblpy-installation)).
-
- 
-### More `sklearn` examples
-> These examples are merely intended to show the desired syntax for the various packages; we do not intend to fit models
-> that actually have a good predictive performance in these examples.
-
-Currently we support uploading `sklearn`, `statsmodels`, and `xgboost` models (run `sp.list_models()` to print an overview of all supported models). 
-Here we provide an example for each of these.
-
-### sklearn: the elastic net
-
-The [elastic net](https://web.stanford.edu/~hastie/Papers/elasticnet.pdf) provides a flexible regularized model that is 
-useful for many supervised learning tasks.
-
-````
-import sclblpy as sp
-from sklearn import linear_model  # Import linear_model
-from sklearn import datasets  # Import sklearn datasets
-
-iris_data = datasets.load_iris(return_X_y=True)
-X, y = iris_data
-
-mod = linear_model.ElasticNet()  # Instantiate the model
-
-mod.fit(X, y)  # Fit the model
-
-fv = X[0, :]  # An example feature vector
-docs = {'name': "ElasticNet example model", 'documentation' : "Documentation for this model."}
-
-sp.upload(mod, fv, docs)
-
-````
-
-### statsmodels: OLS regression
-
-The statsmodels package provides a number of regression models with flexible error functions. We provide a simple OLS
-example:
-
-```` 
-import sclblpy as sp
-
-import statsmodels.api as sm  # Import statsmodels
-from sklearn import datasets  # Import sklearn datasets
-
-iris_data = datasets.load_iris(return_X_y=True)
-X, y = iris_data
-
-est = sm.OLS(y, X)  # Specify the model
-mod = est.fit()  # Fit the model; note that we send the fitted model to scailable
-
-fv = X[0, :]  # An example feature vector
-docs = {'name': "OLS example model"}
-
-sp.upload(mod, fv, docs=docs)
-````
-
-### xgboost: tree boosting
-
-The xgboost package provides flexibly tree boosting models (see [xgboost](https://dl.acm.org/doi/abs/10.1145/2939672.2939785)).
-This model often performs very well "off the shelf" for many supervised learning tasks.
-
-```` 
-import sclblpy as sp
-
-from xgboost import XGBClassifier  # Import xgboost classifier
-from sklearn import datasets  # Import sklearn datasets
-
-iris_data = datasets.load_iris(return_X_y=True)
-X, y = iris_data
-
-mod = XGBClassifier()  # Instantiate the model
-mod.fit(X, y)  # Fit the model
-
-fv = X[0, :]  # An example feature vector
-docs = {'name': "XGBoost example model"}
-
-sp.upload(mod, fv, docs=docs)
-````
 
 ## A simple `.onnx` example
 
@@ -205,14 +101,13 @@ The following code can be used to upload a stored `.onnx` model:
 docs = {}
 docs['name'] = "Name of ONNX model"
 docs['documentation'] = "A long .md thing...."
-check = sp.upload("PATH-TO-MODEL/FILE-NAME.onnx", "", docs, model_type="onnx")
+check = upload_onnx("PATH-TO-MODEL/FILE-NAME.onnx", "", docs, email=True)
 ```
 
-Note that the file will be send to the Scailable platform; after it has been transpiled to WebAssembly you will receive 
-(by default) and email.
+Note that the file will be send to the Scailable platform; after it has been transpiled to WebAssembly you will receive an email (by default), but you can choose not to, by setting ``email=False``
 
 ## Additional functionality
-Next to the main ``upload()`` function, the package also exposes the following functions to administer endpoints:
+Next to the main ``upload_onnx()`` function, the package also exposes the following functions to administer endpoints:
 
 ````
 # List all models owned by the current user:
@@ -263,85 +158,6 @@ sp.remove_credentials()
 
 ````
 
-## Running an uploaded model
-After uploading a model to Scailable using the `sclblpy` package, you might also
-want to use `python` to consume the model. You will find example `python` code to consume
-your created endpiont in your [Scailable admin](https://admin.sclbl.net) which you can directly
-copy-paste into your python project. But, if you want it even easier you can also
-add the following to your code:
-
-````python
-from sclblpy import run
-
-cfid = "e93d0176-90f8-11ea-b602-9600004e79cc"  # This is the integer sum demo.
-fv = [1,2,3,4,5]
-result = run(cfid, fv)
-
-print(result) # Prints the full result from the Scailable server.
-````
-
-
-## Supported `sklearn` models
-
-The list of models supported by the current version of the `sclblpy` package can always be retrieved 
-using the `list_models()` function. Here we provide an overview:
-
-Package | Model | Tested (19-06-2020) | Note 
---- | --- | --- | --- 
-lightgbm | LGBMClassifier | ok |  
-lightgbm | LGBMRegressor | ok |  
-sklearn | ARDRegression | ok |  
-sklearn | BayesianRidge | ok |  
-sklearn | DecisionTreeClassifier | ok |  
-sklearn | DecisionTreeRegressor | ok |  
-sklearn | ElasticNet | ok |  
-sklearn | ElasticNetCV | ok |  
-sklearn | ExtraTreeClassifier | ok |  
-sklearn | ExtraTreeRegresso | ok |  
-sklearn | ExtraTreesClassifier | ok |  
-sklearn | ExtraTreesRegressor | ok |  
-sklearn | HuberRegressor | ok |  
-sklearn | Lars | ok |  
-sklearn | LarsCV | ok |  
-sklearn | Lasso | ok |  
-sklearn | LassoCV | ok |  
-sklearn | LassoLars | ok |  
-sklearn | LassoLarsCV | ok |  
-sklearn | LassoLarsIC | ok |  
-sklearn | LinearRegression | ok |  
-sklearn | LinearSVC | ok |  
-sklearn | LinearSVR | ok |  
-sklearn | LogisticRegression | ok |  
-sklearn | LogisticRegressionCV | ok |  
-sklearn | NuSVC | ok |  
-sklearn | NuSVR | ok |  
-sklearn | OrthogonalMatchingPursuit | ok |  
-sklearn | OrthogonalMatchingPursuitCV | ok |  
-sklearn | PassiveAggressiveClassifier | ok |  
-sklearn | PassiveAggressiveRegressor | ok |  
-sklearn | Perceptron | ok |  
-sklearn | RandomForestClassifier | ok |  
-sklearn | RandomForestRegressor | ok |  
-sklearn | RANSACRegressor | ok |  
-sklearn | Ridge | ok |  
-sklearn | RidgeClassifier | ok |  
-sklearn | RidgeClassifierCV | ok |  
-sklearn | RidgeCV | ok |  
-sklearn | SGDClassifier | ok |  
-sklearn | SGDRegressor | ok |  
-sklearn | SVC | ok |  
-sklearn | SVR | ok |  
-sklearn | TheilSenRegressor | ok |  
-statsmodels | Generalized Least Squares (GLS) | ok |  
-statsmodels | Generalized Least Squares with AR Errors (GLSAR) | ok |  
-statsmodels | Ordinary Least Squares (OLS) | ok |  
-statsmodels | Quantile Regression (QuantReg) | ok |  
-statsmodels | Weighted Least Squares (WLS) | ok |  
-xgboost | XGBClassifier | ok |  
-xgboost | XGBRegressor | ok |  
-xgboost | XGBRFClassifier | ok | Binary only
-xgboost | XGBRFRegressor | ok |  
-
 ## Supported `.onnx` files
 
 We currently support `ONNX` version 1.8 (and below) in full. However, if you encounter any problems
@@ -355,10 +171,9 @@ the following packages:
 * `numpy`
 * `requests`
 * `uuid`
-* `sklearn`
 
-The `statsmodels` and `xgboost` packages are imported when used. No `onnx` packages are
-neccesary for the `sclblpy` package to run.
+No `onnx` packages are
+necessary for the `sclblpy` package to run.
 
 ## Notes:
 
@@ -366,7 +181,7 @@ neccesary for the `sclblpy` package to run.
 * The methods `_set_toolchain_URL(string)` and `_set_usermanager_URL(string)` can be used to change the default location of
 the toolchain and user-management function. These are useful when running the Scailable stack locally. Also the method `_toggle_debug_mode()` can
 be used for troubleshooting (this will raise exceptions and provide a trace upon errors).
-* Docs generated using `pdoc --html --html-dir docs sclblpy/main.py`
-
+* Docs generated using `pdoc3 --force --html --output-dir docs sclblpy/main.py`
+* We are actively developing our stack; we try to list changes from one version to the next as clearly as possible. If you find any errors or issues please add an issue to this repo."
 If you are having trouble using the `sclblpy` package, please [submit an issue to our github](https://github.com/scailable/sclblpy/issues/new), 
 we will try to fix it as quickly as possible!
diff --git a/docs/main.html b/docs/main.html
new file mode 100644
index 0000000..c67fa22
--- /dev/null
+++ b/docs/main.html
@@ -0,0 +1,2648 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.10.0" />
+<title>main API documentation</title>
+<meta name="description" content="" />
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>main</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python"># File contains all public methods of the scblpy package
+import json
+import urllib
+import requests
+import sclblpy._globals as glob
+from sclblpy._bundle import _gzip_save, _gzip_delete
+from sclblpy._jwt import _check_jwt, _remove_credentials
+from sclblpy._utils import  _get_system_info
+from sclblpy.errors import UserManagerError, JWTError, UploadModelError, RunTaskError, CreateAssignmentError
+from sclblpy.version import __version__
+
+
+# welcome just prints a simple welcome message:
+def welcome():
+    &#34;&#34;&#34; Welcome simply prints a welcome message.
+    &#34;&#34;&#34;
+    print(&#34;\n*** Thanks for importing sclblpy! ***&#34;)
+    print(&#34;You can use the &#39;upload()&#39; function to upload your models.&#34;)
+    print(&#34;To inspect your currently uploaded models, use `endpoints()`.&#34;)
+    print(&#34;Check the docs at https://pypi.org/project/sclblpy/ for more info. \n&#34;)
+
+
+
+
+# upload_onnx uploads an onnx file to the toolchain-server
+def upload_onnx(path, example=&#34;&#34;, docs={}, email=True) -&gt; bool:
+    &#34;&#34;&#34;upload_onnx uploads a fitted onnx model to Scailable.
+
+    - The function first checks if the supplied path indeed references a .onnx file
+    - Next, the docs are checked; if none are provided a warning is issued and a simple
+    name is provided based on the model type.
+    - Finally the onnx file and the supporting docs are uploaded to the toolchain.
+
+    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
+        stop_print() method.
+
+    Args:
+        path: The path referencing the onnx model location (i.e., the .onnx file location).
+        example: String example input for the onnx file.
+        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;.
+        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
+
+    Returns:
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    &#34;&#34;&#34;
+    if glob.DEBUG:
+        print(&#34;We are checking your .onnx file...&#34;)
+
+    bundle = {}
+
+    # simply add example string to bundle:
+    bundle[&#39;example&#39;] = example
+
+    # check the docs:
+    bundle[&#39;docs&#39;] = {}
+    if docs:
+        bundle[&#39;docs&#39;] = docs
+    else:
+        try:  # This should work, but catching the exception just in case:
+            name = path
+        except Exception:
+            name = &#34;NAMELESS MODEL&#34;
+        bundle[&#39;docs&#39;][&#39;name&#39;] = name
+        bundle[&#39;docs&#39;][&#39;documentation&#39;] = &#34;-- EMPTY --&#34;
+        if not glob.SILENT:
+            print(&#34;WARNING: You did not provide any documentation. \n&#34;
+                  &#34;We will simply use &#34; + name + &#34; as its name without further documentation.&#34;)
+
+    # check if file exists:
+    if not path.endswith(&#39;.onnx&#39;):
+        if not glob.SILENT:
+            print(&#34;FATAL: You did not specify a .onnx path. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file (no .onnx extension).&#34;)
+
+    # try to open the file
+    try:
+        files = [(&#39;bundle&#39;, open(path, &#39;rb&#39;))]
+    except Exception:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to open the specified onnx file. Is the path correct? \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file.&#34;)
+        return False
+
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been uploaded. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # get system information
+    bundle[&#39;system_info&#39;] = _get_system_info()
+
+    # all ok, upload:
+    if auth:
+
+        url = glob.TOOLCHAIN_URL + &#34;/upload/&#34; + glob.JWT_USER_ID
+
+        # Hard coded tootlchain name:
+        toolchain_name = &#34;onnx2c&#34;
+
+        # Setup the actual request
+        data: dict = {
+            &#39;email&#39;: email,
+            &#39;package&#39;: __version__,
+            &#39;toolchain&#39;: toolchain_name,
+            &#39;name&#39;: bundle[&#39;docs&#39;].get(&#39;name&#39;, &#34;No name found.&#34;),
+            &#39;docs&#39;: bundle[&#39;docs&#39;].get(&#39;documentation&#39;, &#34;No docs provided.&#34;),
+            &#39;exampleInput&#39;: example,
+            &#39;exampleOutput&#39;: &#34;&#34;
+        }
+        payload: dict = {
+            &#39;data&#39;: json.dumps(data)
+        }
+
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN,
+        }
+
+        # Do the request
+        try:
+            response = requests.post(url, headers=headers, data=payload, files=files)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: Unable to carry out the upload request: the toolchain is not available. \n&#34;
+                      &#34;Your model has not been uploaded. PLACE 1 URL: {url}\n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the toolchain-server. \n&#34;
+                      &#34;Your model has not been uploaded. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the toolchain-server. \n&#34;
+                      &#34;Your model has not been uploaded. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The following content has been send to the toolchain server:&#34;)
+            print(bundle)
+
+        # user feedback:
+        if not glob.SILENT:
+            print(&#34;Your ONNX file was successfully uploaded to Scailable!&#34;)
+            print(&#34;NOTE: After transpiling, we will send you an email and your model will be available at &#34;
+                  &#34;https://admin.sclbl.net.&#34;)
+            print(&#34;Or, alternatively, you can use the &#39;models()&#39; function to list all your uploaded models. \n&#34;)
+
+        return True
+
+    else:
+        return False
+
+
+
+
+
+
+# update_onnx updates an onnx model
+def update_onnx(path, cfid, example=&#34;&#34;, docs={}, email=True) -&gt; bool:
+    &#34;&#34;&#34;upload_onnx updates a fitted onnx model to Scailable.
+
+    The update function is similar to the upload function in most respects (so, see its docs),
+    but instead of creating a new endpoint it overwrites the docs and model of an already existing
+    endpoint. Thus, there is an additional argument &#34;cfid&#34; providing the computeFunction Id
+    of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already
+    existing endpoints.
+
+    Note: If you solely want to change the documentation of an endpoint, you can either use the
+        update_docs() function or the online admin interface at https://admin.sclble.net.
+
+    Args:
+        path: The path referencing the onnx model location (i.e., the .onnx file location).
+        cfid: a string with a valid computeFunction ID.
+        example: String example input for the onnx file.
+        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;.
+        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
+
+    Returns:
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    &#34;&#34;&#34;
+    if glob.DEBUG:
+        print(&#34;We are checking your updated .onnx file...&#34;)
+
+    bundle = {}
+
+    # simply add example string to bundle:
+    bundle[&#39;example&#39;] = example
+
+    # check the docs:
+    bundle[&#39;docs&#39;] = {}
+    if docs:
+        bundle[&#39;docs&#39;] = docs
+    else:
+        try:  # This should work, but catching the exception just in case:
+            name = path
+        except Exception:
+            name = &#34;NAMELESS MODEL&#34;
+        bundle[&#39;docs&#39;][&#39;name&#39;] = name
+        bundle[&#39;docs&#39;][&#39;documentation&#39;] = &#34;-- EMPTY --&#34;
+        if not glob.SILENT:
+            print(&#34;WARNING: You did not provide any documentation. \n&#34;
+                  &#34;We will simply use &#34; + name + &#34; as its name without further documentation.&#34;)
+
+    # check if file exists:
+    if not path.endswith(&#39;.onnx&#39;):
+        if not glob.SILENT:
+            print(&#34;FATAL: You did not specify a .onnx path. \n&#34;
+                  &#34;Your model has not been updated. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file (no .onnx extension).&#34;)
+
+    # try to open the file
+    try:
+        files = [(&#39;bundle&#39;, open(path, &#39;rb&#39;))]
+    except Exception:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to open the specified onnx file. Is the path correct? \n&#34;
+                  &#34;Your model has not been updated. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file.&#34;)
+        return False
+
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been updated. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # get system information
+    bundle[&#39;system_info&#39;] = _get_system_info()
+
+    # all ok, upload:
+    if auth:
+
+        url = glob.TOOLCHAIN_URL + &#34;/upload/&#34; + glob.JWT_USER_ID + &#34;/&#34; + cfid
+
+        # Hard coded tootlchain name:
+        toolchain_name = &#34;onnx2c&#34;
+
+        # Setup the actual request
+        data: dict = {
+            &#39;email&#39;: email,
+            &#39;package&#39;: __version__,
+            &#39;toolchain&#39;: toolchain_name,
+            &#39;name&#39;: bundle[&#39;docs&#39;].get(&#39;name&#39;, &#34;No name found.&#34;),
+            &#39;docs&#39;: bundle[&#39;docs&#39;].get(&#39;documentation&#39;, &#34;No docs provided.&#34;),
+            &#39;exampleInput&#39;: example,
+            &#39;exampleOutput&#39;: &#34;&#34;
+        }
+        payload: dict = {
+            &#39;data&#39;: json.dumps(data)
+        }
+
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN,
+        }
+
+        try:
+            response = requests.put(url, headers=headers, data=payload, files=files)
+        except Exception as e:
+            if not glob.SILENT:
+                print(f&#34;FATAL: Unable to carry out the update request: the toolchain is not available. \n&#34;
+                      f&#34;Your model has not been updated. {url}, user id: {glob.JWT_USER_ID}, cfid:  {cfid}\n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the toolchain-server. \n&#34;
+                      &#34;Your model has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the toolchain-server. \n&#34;
+                      &#34;Your model has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The following content has been send to the toolchain server:&#34;)
+            print(bundle)
+
+        # user feedback:
+        if not glob.SILENT:
+            print(&#34;Your model was successfully submitted for an update. \n&#34;)
+
+        return True
+
+    else:
+        return False
+
+
+# update_docs updates the docs of a given model (but not the model itself:
+def update_docs(cfid, docs) -&gt; bool:
+    &#34;&#34;&#34;Updates the documentation of an already existing model
+
+    The update_docs function can be used to upload the documentation of an already existing model
+    by simply providing the cfid and the new docs object.
+
+    Args:
+        cfid: a string with a valid computeFunction ID.
+        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;
+
+    Returns:
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    &#34;&#34;&#34;
+
+    # check the docs:
+    print(docs)
+    name = docs.get(&#39;name&#39;, &#34;&#34;)
+    if name == &#34;&#34;:
+        print(&#34;FATAL: Please make sure to add a name to your documentation (using the &#39;name&#39;) field \n&#34;
+              &#34;Your model documentation has not been updated. \n&#34;)
+        return False
+    documentation = docs.get(&#39;documentation&#39;, &#34;&#34;)
+    if documentation == &#34;&#34;:
+        print(&#34;FATAL: Please make sure to your documentation (using the &#39;documentation&#39; field) \n&#34;
+              &#34;Your model documentation has not been updated. \n&#34;)
+        return False
+
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been uploaded. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # all ok, upload:
+    if auth:
+
+        url = glob.USER_MANAGER_URL + &#34;/compute-function/&#34; + glob.JWT_USER_ID + &#34;/&#34; + cfid
+
+        # Setup the actual request
+        data: dict = {
+            &#34;language&#34;: &#34;WASM&#34;,
+            &#34;public&#34;: True,
+            &#34;profit&#34;: 0.1,
+            &#34;cycles&#34;: 1.0,
+            &#34;name&#34;: name,
+            &#34;docs&#34;: documentation
+        }
+        payload: dict = {
+            &#39;data&#39;: json.dumps(data)
+        }
+
+        files = []
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN
+        }
+
+        # Do the request (and make sure to delete the gzip if errors occur)
+        try:
+            response = requests.put(url, headers=headers, data=payload, files=files)
+        except Exception as e:
+            if not glob.SILENT:
+                print(f&#34;FATAL: Unable to carry out the upload request: the toolchain is not available. \n&#34;
+                      &#34;Your model documentation has not been updated. PLACE 2 URL: {url} \n&#34;)
+                print(url)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the toolchain-server. \n&#34;
+                      &#34;Your model documentation has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the server. \n&#34;
+                      &#34;Your model documentation has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The documentation for &#34; + cfid + &#34; has been updated using:&#34;)
+            print(data)
+
+        # user feedback:
+        if not glob.SILENT:
+            print(&#34;Your model documentation has been updated. \n&#34;)
+        return True
+
+    else:
+        return False
+
+
+# assign assigns a model to a device
+def assign(cfid, did, rid, _verbose=False):
+    &#34;&#34;&#34; Assign a model to a device.
+
+    Using the global JWT string this function assigns a model (using its cfid) to a device (using its did).
+
+    Args:
+        cfid: String identifying the model / compute-function
+        did: String identifying the device
+        rid: String identifying the registration ID of the device (not, run &#34;devices&#34;
+        _verbose: Print feedback, default False
+
+    Returns:
+        Boolean indicating whether the assignment was successful.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        CreateAssignmentError for other failures.
+    &#34;&#34;&#34;
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been uploaded. \n&#34;)
+        if glob.DEBUG:
+            raise CreateAssignmentError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # check fields not empty
+    if not cfid or not did or not rid:
+        if not glob.SILENT:
+            print(&#34;FATAL: Please specify the correct ids. \n&#34;
+                  &#34;Your assignment has not been submitted. \n&#34;)
+        if glob.DEBUG:
+            raise CreateAssignmentError(&#34;We were unable submit your assignment.&#34;)
+        return False
+
+    # all ok, assign:
+    if auth:
+
+        url = glob.USER_MANAGER_URL + &#34;/assign/&#34; + glob.JWT_USER_ID
+
+        # Setup the actual request
+        data: dict = {
+            &#39;modelId&#39;: cfid,
+            &#39;deviceId&#39;: did,
+            &#39;registrationId&#39;: rid
+        }
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN,
+        }
+
+        try:
+            response = requests.post(url, headers=headers, data=json.dumps(data))
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: Unable to carry out the assignment; the usermanager is not available. \n&#34;
+                      &#34;Your model has not been assigned. \n&#34;)
+            if glob.DEBUG:
+                raise CreateAssignmentError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the user manager. \n&#34;
+                      &#34;Your assignment has not been submitted. \n&#34;)
+            if glob.DEBUG:
+                raise CreateAssignmentError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the usermanager. \n&#34;
+                      &#34;Your assignment has not been submitted. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The following content has been send to the usermanager to create an assignment:&#34;)
+            print(data)
+
+        # user feedback:
+        if not glob.SILENT:
+            if _verbose:
+                print(&#34;Your assignment has been added. \n&#34;)
+
+        return True
+
+    else:
+        return False
+
+
+# assignments gets all the assignments owned by the current user:
+def assignments(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34; Get all assignments (i.e., cfid-did combinations).
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/assignments/user/&#34; + glob.JWT_USER_ID + &#34;?limit=&#34; + str(limit) + &#34;&amp;offset=&#34; + str(
+        offset)
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;GET&#34;, url, headers=headers, data={})
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable retrieve your assignments.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to retrieve assignments. &#34; + str(e))
+        return False
+
+    # print if requested:
+    if _verbose and not glob.SILENT:
+        if not result:
+            if offset == 0:
+                print(&#34;You have not yet made any assignments.&#34;)
+                print(&#34;\nNeed help getting started?&#34;)
+                print(&#34; - See the sclblpy docs at https://pypi.org/project/sclblpy/.&#34;)
+                print(&#34; - See our getting started tutorial at &#34;
+                      &#34;https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.&#34;)
+                print(&#34; - Or, login to your admin at https://admin.sclbl.net. \n&#34;)
+            else:
+                print(&#34;No assignments found given the current settings; You could try to decrease the offset.&#34;)
+        else:
+            # Pretty printing of list
+            i = 1
+            print(&#34;We found the following assignments:\n&#34;)
+            for key in result:
+                print(&#39;  {}: {} &lt;-&gt; {} \n&#39;
+                      &#39;   - cfid: {} \n&#39;
+                      &#39;   - did: {} \n&#39;
+                      &#39;   - rid: {} \n&#39;.format(i, key[&#39;model_name&#39;], key[&#39;device_name&#39;], key[&#39;cfid&#39;], key[&#39;did&#39;], key[&#39;rid&#39;]))
+                i = i + 1
+
+    if _return:
+        return result
+    else:
+        return True
+
+
+# delete_assignments delete an assignment using its aid:
+def delete_assignment(aid) -&gt; bool:
+    &#34;&#34;&#34; Delete an assignment
+
+    Args:
+        aid: String, the assignment id (UUID format)
+
+    Returns:
+        Boolean, True if assignment is deleted
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/assign/&#34; + glob.JWT_USER_ID + &#34;/&#34; + aid
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;DELETE&#34;, url, headers=headers)
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable delete your assignment.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete assignment. &#34; + str(e))
+        return False
+
+    if glob.DEBUG:
+        print(result)
+
+    return True
+
+
+# devices lists all the devices owned by the current user:
+def devices(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34; Get all devices owned by the current user.
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/devices/&#34; + glob.JWT_USER_ID + &#34;?limit=&#34; + str(limit) + &#34;&amp;offset=&#34; + str(
+        offset)
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;GET&#34;, url, headers=headers, data={})
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable retrieve your devices.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to retrieve devices. &#34; + str(e))
+        return False
+
+    # print if requested:
+    if _verbose and not glob.SILENT:
+        if not result:
+            if offset == 0:
+                print(&#34;You have not yet registered any devices&#34;)
+                print(&#34;\nNeed help getting started?&#34;)
+                print(&#34; - See the sclblpy docs at https://pypi.org/project/sclblpy/.&#34;)
+                print(&#34; - See our getting started tutorial at &#34;
+                      &#34;https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.&#34;)
+                print(&#34; - Or, login to your admin at https://admin.sclbl.net. \n&#34;)
+            else:
+                print(&#34;No devices found given the current settings; You could try to decrease the offset.&#34;)
+        else:
+            # Pretty printing of list
+            baseUrl = glob.EXAMPLE__BASE_URL
+            i = 1
+            print(&#34;We found the following device registrations:\n&#34;)
+            for key in result:
+                print(&#39;  {}: {}, \n&#39;
+                      &#39;   - did: {} \n&#39;
+                      &#39;   - rid: {} \n&#39;.format(i, key[&#39;name&#39;], key[&#39;did&#39;], key[&#39;rid&#39;]))
+                i = i + 1
+            print(&#34;Login at https://admin.sclbl.net to administer your devices.\n&#34;)
+
+    if _return:
+        return result
+    else:
+        return True
+
+
+# delete_device delete a device using its device id
+def delete_device(did) -&gt; bool:
+    &#34;&#34;&#34; Delete a device
+
+    Args:
+        did: String, the device id (aaa-bbb-ccc format)
+
+    Returns:
+        Boolean, True if device is deleted
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/device/&#34; + glob.JWT_USER_ID + &#34;/&#34; + did
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;DELETE&#34;, url, headers=headers)
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable delete your device.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete device. &#34; + str(e))
+        return False
+
+    if glob.DEBUG:
+        print(result)
+
+    return True
+
+# models lists the models / endpoints for the current user.
+def models(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34; Print or return the endpoints available for the current user.
+
+    Simple wrapper for the endpoints() function.
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    return endpoints(offset=offset, limit=limit, _verbose=_verbose, _return=_return)
+
+
+# endpoints lists the models / end
+def endpoints(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34;Print or return the endpoints available for the current user.
+
+    Using the global JWT string this function by default prints a summary of the endpoints
+    owned by the current user. The endpoints can also be returned as a dict by setting _return=True.
+
+    Note that the call is paginated: use the offset and limit arguments to retrieve the desired
+    list of endpoints. Endpoints are sorted with the latest upload being first, and the function retrieves
+    the items from offset to (offset+limit). By default the 20 most recently created endpoints are returned.
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/compute-functions/&#34; + glob.JWT_USER_ID + &#34;?limit=&#34; + str(limit) + &#34;&amp;offset=&#34; + str(
+        offset)
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;GET&#34;, url, headers=headers, data={})
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable retrieve your endpoints.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to retrieve endpoints. &#34; + str(e))
+        return False
+
+    # print if requested:
+    if _verbose and not glob.SILENT:
+        if not result:
+            if offset == 0:
+                print(&#34;You currently do not own any active endpoints.&#34;)
+                print(&#34;\nNeed help getting started?&#34;)
+                print(&#34; - See the sclblpy docs at https://pypi.org/project/sclblpy/.&#34;)
+                print(&#34; - See our getting started tutorial at &#34;
+                      &#34;https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.&#34;)
+                print(&#34; - Or, login to your admin at https://admin.sclbl.net. \n&#34;)
+                print(&#34;NOTE: if you have just uploaded a model, please check your email; we will let you know when its &#34;
+                      &#34;available!\n&#34;)
+            else:
+                print(&#34;No endpoints found given the current settings; You could try to decrease the offset.&#34;)
+        else:
+            # Pretty printing of list
+            baseUrl = glob.EXAMPLE__BASE_URL
+            i = 1
+            print(&#34;You currently own the following endpoints:\n&#34;)
+            for key in result:
+                url = baseUrl + &#34;?cfid=&#34; + key[&#39;cfid&#39;]
+                url += &#34;&amp;exin=&#34; + urllib.parse.quote(key[&#39;exampleinput&#39;])
+
+                print(&#39;  {}: {}, \n&#39;
+                      &#39;   - cfid: {} \n&#39;
+                      &#39;   - example: {} \n&#39;.format(i, key[&#39;name&#39;], key[&#39;cfid&#39;], url))
+                i = i + 1
+            print(&#34;Login at https://admin.sclbl.net to administer your endpoints and see integration examples.\n&#34;)
+
+    if _return:
+        return result
+    else:
+        return True
+
+
+# delete model deletes a model:
+def delete_model(cfid: str) -&gt; bool:
+    &#34;&#34;&#34;Deletes a model by cfid.
+
+    Delete an model owned by the currently logged in user by cfid.
+
+    Args:
+        cfid: String of the compute function id.
+
+    Returns:
+        True if successful, False otherwise.
+
+    Raises  (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to delete endpoints
+    &#34;&#34;&#34;
+    return delete_endpoint(cfid)
+
+
+# delete_endpoint deletes a given endpoint by id
+def delete_endpoint(cfid: str) -&gt; bool:
+    &#34;&#34;&#34;Deletes an endpoint by cfid.
+
+    Delete an endpoint owned by the currently logged in user by cfid.
+
+    Args:
+        cfid: String of the compute function id.
+
+    Returns:
+        True if successful, False otherwise.
+
+    Raises  (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to delete endpoints
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/compute-function/&#34; + glob.JWT_USER_ID + &#34;/&#34; + cfid
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN,
+    }
+    try:
+        response = requests.request(&#34;DELETE&#34;, url, headers=headers, data={})
+        # Check if content type is JSON
+        if &#39;json&#39; in response.headers.get(&#39;Content-Type&#39;):
+            try:
+                result = json.loads(response.text)
+            except ValueError:  # simplejson.decoder.JSONDecodeError
+                if not glob.SILENT:
+                    print(&#34;Unable to decode JSON response from usermanager error.&#34;)
+                if glob.DEBUG:
+                    raise UserManagerError(result.get(&#34;Unable to decode JSON response from usermanager error.&#34;))
+                return False
+        else:
+            if not glob.SILENT:
+                print(&#34;Server at&#34;, glob.USER_MANAGER_URL, &#34;did not return a valid JSON document.&#34;)
+            if glob.DEBUG:
+                raise UserManagerError(&#34;Server at&#34;, glob.USER_MANAGER_URL, &#34;did not return a valid JSON document.&#34;)
+            return False
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to remove this endpoint from the server. \n&#34;
+                  &#34;Please try again later.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete endpoint. &#34; + str(e))
+        return False
+
+    if result.get(&#34;error&#34;) != &#34;&#34;:
+        if not glob.SILENT:
+            print(&#34;We were unable to remove this endpoint: \n&#34;
+                  &#34;Server error: &#34; + str(result.get(&#34;error&#34;)))
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete endpoint. &#34; + result.get(&#34;error&#34;))
+        return False
+
+    if not glob.SILENT:
+        print(&#34;Endpoint with cfid &#34; + cfid + &#34; was successfully deleted.&#34;)
+
+    return True
+
+
+# remove_credentials removes the user credentials
+def remove_credentials(_verbose=True) -&gt; bool:
+    &#34;&#34;&#34;Remove your stored credentials.
+
+    Remove the .creds.json file that stores the username and password
+    of the current user.
+
+    Args:
+        _verbose: Boolean indicator whether or not feedback should be printed. Default False.
+
+    Returns:
+        True is user credentials are found and deleted. False otherwise (often because they were not found).
+    &#34;&#34;&#34;
+
+    # actual function in _utils.py to prevent circular includes.
+    removed = _remove_credentials()
+    if removed:
+        if _verbose and not glob.SILENT:
+            print(&#34;Successfully removed your user credentials.&#34;)
+        return True
+    else:
+        if _verbose and not glob.SILENT:
+            print(&#34;No user credentials found.&#34;)
+        return False
+
+
+# stop_print stops verbose printing of the package
+def stop_print(_verbose=False) -&gt; bool:
+    &#34;&#34;&#34;Stop ALL printing of user feedback from package.
+
+    Args:
+        _verbose: Boolean indicator whether or not feedback should be printed. Default False.
+
+    Returns:
+        True
+    &#34;&#34;&#34;
+    if _verbose:
+        print(&#34;Printing user feedback set to &#39;False&#39;.&#34;)
+    glob.SILENT = True
+    return True
+
+
+# start_print starts verbose printing of the package
+def start_print() -&gt; bool:
+    &#34;&#34;&#34;(re)start printing user feedback
+
+    Returns:
+        True
+
+    &#34;&#34;&#34;
+    print(&#34;Printing user feedback set to &#39;True&#39;.&#34;)
+    glob.SILENT = False
+    return True
+
+
+
+# _set_toolchain_URL sets the location of the toolchain (for local testing)
+def _set_toolchain_URL(url: str) -&gt; str:
+    &#34;&#34;&#34;Change the location of the toolchain server.
+
+    This function is internal and should not be used by average users of the package. However,
+    it is useful for trouble-shooting the package either locally or on development servers.
+
+    Args:
+        url: String specifying the location of the toolchain server.
+
+    Returns:
+        str: The toolchains url.
+    &#34;&#34;&#34;
+    glob.TOOLCHAIN_URL = url
+
+    if not glob.SILENT:
+        print(&#34;Toolchain url changed to: &#34; + glob.TOOLCHAIN_URL)
+
+    return glob.TOOLCHAIN_URL
+
+
+# _set_usermanager_URL sets the location of the usermanager
+def _set_usermanager_URL(url: str) -&gt; str:
+    &#34;&#34;&#34;Change the location of the toolchain server
+
+    This function is internal and should not be used by average users of the package. However,
+    it is useful for trouble-shooting the package either locally or on development servers.
+
+    Args:
+        url: String specifying the location of the toolchain server
+
+    Returns:
+        The user-manager url
+    &#34;&#34;&#34;
+    glob.USER_MANAGER_URL = url
+
+    if not glob.SILENT:
+        print(&#34;User-manager (admin) url changed to: &#34; + glob.USER_MANAGER_URL)
+
+    return glob.USER_MANAGER_URL
+
+
+# _set_taskmanager_URL sets the location of the taskmanager
+def _set_taskmanager_URL(url: str) -&gt; str:
+    &#34;&#34;&#34;Change the location of the task manager
+
+    This function is internal and should not be used by average users of the package. However,
+    it is useful for trouble-shooting the package either locally or on development servers.
+
+    Args:
+        url: String specifying the location of the taskmanager server
+
+    Returns:
+        The task-manager url
+    &#34;&#34;&#34;
+    glob.TASK_MANAGER_URL = url
+
+    if not glob.SILENT:
+        print(&#34;User-manager (admin) url changed to: &#34; + glob.TASK_MANAGER_URL)
+
+    return glob.TASK_MANAGER_URL
+
+
+# _toggle_debug_mode turns debugging of or on.
+def _toggle_debug_mode() -&gt; bool:
+    &#34;&#34;&#34;Set debug to true or false.
+
+    Can be used for debugging purposes such that exceptions are raised (including the stack trace)
+    instead of suppressed.
+
+    Note: the debug status is always printed when executing this method.
+
+    Returns:
+        Boolean indicating the status of the DEBUG global.
+    &#34;&#34;&#34;
+    if glob.DEBUG:
+        glob.DEBUG = False
+        print(&#34;Debugging turned off.&#34;)
+    else:
+        glob.DEBUG = True
+        print(&#34;Debugging turned on.&#34;)
+
+    return glob.DEBUG
+
+
+# _check_input_type
+def _check_input_type(fv):
+    &#34;&#34;&#34;_check_input_type trie to determine the input type of the feature vector.
+
+    Utility used by run()
+    &#34;&#34;&#34;
+    if isinstance(fv, list):
+        return &#34;csv&#34;
+    else:
+
+        # Parse to json
+        try:
+            js = json.loads(fv)
+        except Exception as e:
+            return False
+
+        # Get the type
+        try:
+            input_type = js.get(&#34;type&#34;, False)
+            if input_type in [&#34;raw&#34;, &#34;pb&#34;]:
+                return input_type
+            else:
+                return False
+        except Exception as e:
+            return False
+
+
+def _run_csv(url, fv):
+    &#34;&#34;&#34; run an endpoint using csv input. &#34;&#34;&#34;
+    # Create the input vector:
+    try:
+        data = &#34;,&#34;.join(map(str, fv))
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to convert your feature_vector to a valid input string. &#34; + str(e))
+        if glob.DEBUG:
+            raise RunTaskError(&#34;We were unable to convert your feature_vector to a valid input string. &#34; + str(e))
+        return False
+
+    # Do the actual call:
+    try:
+        payload = &#34;{\&#34;input\&#34;:{\&#34;content-type\&#34;:\&#34;json\&#34;,\&#34;location\&#34;:\&#34;embedded\&#34;,\&#34;data\&#34;:\&#34;{\\\&#34;input\\\&#34;: [[&#34; + data + &#34;]]}\&#34;},\&#34;output\&#34;:{\&#34;content-type\&#34;:\&#34;json\&#34;,\&#34;location\&#34;:\&#34;echo\&#34;},\&#34;control\&#34;:1,\&#34;properties\&#34;:{\&#34;language\&#34;:\&#34;WASM\&#34;}}&#34;
+        headers = {
+            &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;
+        }
+        response = requests.request(&#34;POST&#34;, url, headers=headers, data=payload)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable execute the call. &#34; + str(e))
+        if glob.DEBUG:
+            raise RunTaskError(&#34;We were unable to execute the call to our servers. &#34; + str(e))
+        return False
+
+    return response
+
+
+def _run_pb(url, fv):
+    &#34;&#34;&#34; run an endpoint using pb input. &#34;&#34;&#34;
+    try:
+        payload = &#34;{\&#34;input\&#34;:{\&#34;content-type\&#34;:\&#34;json\&#34;,\&#34;location\&#34;:\&#34;embedded\&#34;,\&#34;data\&#34;:&#34; \
+                  + json.dumps(fv) + \
+                  &#34;},\&#34;output\&#34;:{\&#34;content-type\&#34;:\&#34;json\&#34;,\&#34;location\&#34;:\&#34;echo\&#34;},&#34; \
+                  &#34;\&#34;control\&#34;:1,\&#34;properties\&#34;:{\&#34;language\&#34;:\&#34;WASM\&#34;}}&#34;
+        headers = {
+            &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;
+        }
+        response = requests.request(&#34;POST&#34;, url, headers=headers, data=payload)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable execute the call. &#34; + str(e))
+        if glob.DEBUG:
+            raise RunTaskError(&#34;We were unable to execute the call to our servers. &#34; + str(e))
+        return False
+
+    return response
+
+
+def _run_raw(url, fv):
+    &#34;&#34;&#34; run an endpoint using raw input. &#34;&#34;&#34;
+    try:
+        payload = &#34;{\&#34;input\&#34;:{\&#34;content-type\&#34;:\&#34;json\&#34;,\&#34;location\&#34;:\&#34;embedded\&#34;,\&#34;data\&#34;:&#34; \
+                  + json.dumps(fv) + \
+                  &#34;},\&#34;output\&#34;:{\&#34;content-type\&#34;:\&#34;json\&#34;,\&#34;location\&#34;:\&#34;echo\&#34;},&#34; \
+                  &#34;\&#34;control\&#34;:1,\&#34;properties\&#34;:{\&#34;language\&#34;:\&#34;WASM\&#34;}}&#34;
+        headers = {
+            &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;
+        }
+        response = requests.request(&#34;POST&#34;, url, headers=headers, data=payload)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable execute the call. &#34; + str(e))
+        if glob.DEBUG:
+            raise RunTaskError(&#34;We were unable to execute the call to our servers. &#34; + str(e))
+        return False
+
+    return response
+
+
+# No command line options for this script:
+if __name__ == &#39;__main__&#39;:
+    print(&#34;No command line options available for main.py.&#34;)</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-functions">Functions</h2>
+<dl>
+<dt id="main.assign"><code class="name flex">
+<span>def <span class="ident">assign</span></span>(<span>cfid, did, rid)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Assign a model to a device.</p>
+<p>Using the global JWT string this function assigns a model (using its cfid) to a device (using its did).</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>cfid</code></strong></dt>
+<dd>String identifying the model / compute-function</dd>
+<dt><strong><code>did</code></strong></dt>
+<dd>String identifying the device</dd>
+<dt><strong><code>rid</code></strong></dt>
+<dd>String identifying the registration ID of the device (not, run "devices"</dd>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Print feedback, default False</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>Boolean indicating whether the assignment was successful.
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+CreateAssignmentError for other failures.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def assign(cfid, did, rid, _verbose=False):
+    &#34;&#34;&#34; Assign a model to a device.
+
+    Using the global JWT string this function assigns a model (using its cfid) to a device (using its did).
+
+    Args:
+        cfid: String identifying the model / compute-function
+        did: String identifying the device
+        rid: String identifying the registration ID of the device (not, run &#34;devices&#34;
+        _verbose: Print feedback, default False
+
+    Returns:
+        Boolean indicating whether the assignment was successful.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        CreateAssignmentError for other failures.
+    &#34;&#34;&#34;
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been uploaded. \n&#34;)
+        if glob.DEBUG:
+            raise CreateAssignmentError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # check fields not empty
+    if not cfid or not did or not rid:
+        if not glob.SILENT:
+            print(&#34;FATAL: Please specify the correct ids. \n&#34;
+                  &#34;Your assignment has not been submitted. \n&#34;)
+        if glob.DEBUG:
+            raise CreateAssignmentError(&#34;We were unable submit your assignment.&#34;)
+        return False
+
+    # all ok, assign:
+    if auth:
+
+        url = glob.USER_MANAGER_URL + &#34;/assign/&#34; + glob.JWT_USER_ID
+
+        # Setup the actual request
+        data: dict = {
+            &#39;modelId&#39;: cfid,
+            &#39;deviceId&#39;: did,
+            &#39;registrationId&#39;: rid
+        }
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN,
+        }
+
+        try:
+            response = requests.post(url, headers=headers, data=json.dumps(data))
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: Unable to carry out the assignment; the usermanager is not available. \n&#34;
+                      &#34;Your model has not been assigned. \n&#34;)
+            if glob.DEBUG:
+                raise CreateAssignmentError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the user manager. \n&#34;
+                      &#34;Your assignment has not been submitted. \n&#34;)
+            if glob.DEBUG:
+                raise CreateAssignmentError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the usermanager. \n&#34;
+                      &#34;Your assignment has not been submitted. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The following content has been send to the usermanager to create an assignment:&#34;)
+            print(data)
+
+        # user feedback:
+        if not glob.SILENT:
+            if _verbose:
+                print(&#34;Your assignment has been added. \n&#34;)
+
+        return True
+
+    else:
+        return False</code></pre>
+</details>
+</dd>
+<dt id="main.assignments"><code class="name flex">
+<span>def <span class="ident">assignments</span></span>(<span>offset=0, limit=20) ‑> dict</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Get all assignments (i.e., cfid-did combinations).</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>offset</code></strong></dt>
+<dd>Int indicating the pagination offset. Default 0</dd>
+<dt><strong><code>limit</code></strong></dt>
+<dd>Int inidcating the pagination limit. Default 20</dd>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be printed. Default True.</dd>
+<dt><strong><code>_return</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be returned as a dict. Default False.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<dl>
+<dt><code><a title="main.endpoints" href="#main.endpoints">endpoints()</a></code></dt>
+<dd>if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]</dd>
+</dl>
+<p>otherwise the function will simply return True after printing the endpoints to the screen.
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to retrieve endpoint details</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def assignments(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34; Get all assignments (i.e., cfid-did combinations).
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/assignments/user/&#34; + glob.JWT_USER_ID + &#34;?limit=&#34; + str(limit) + &#34;&amp;offset=&#34; + str(
+        offset)
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;GET&#34;, url, headers=headers, data={})
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable retrieve your assignments.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to retrieve assignments. &#34; + str(e))
+        return False
+
+    # print if requested:
+    if _verbose and not glob.SILENT:
+        if not result:
+            if offset == 0:
+                print(&#34;You have not yet made any assignments.&#34;)
+                print(&#34;\nNeed help getting started?&#34;)
+                print(&#34; - See the sclblpy docs at https://pypi.org/project/sclblpy/.&#34;)
+                print(&#34; - See our getting started tutorial at &#34;
+                      &#34;https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.&#34;)
+                print(&#34; - Or, login to your admin at https://admin.sclbl.net. \n&#34;)
+            else:
+                print(&#34;No assignments found given the current settings; You could try to decrease the offset.&#34;)
+        else:
+            # Pretty printing of list
+            i = 1
+            print(&#34;We found the following assignments:\n&#34;)
+            for key in result:
+                print(&#39;  {}: {} &lt;-&gt; {} \n&#39;
+                      &#39;   - cfid: {} \n&#39;
+                      &#39;   - did: {} \n&#39;
+                      &#39;   - rid: {} \n&#39;.format(i, key[&#39;model_name&#39;], key[&#39;device_name&#39;], key[&#39;cfid&#39;], key[&#39;did&#39;], key[&#39;rid&#39;]))
+                i = i + 1
+
+    if _return:
+        return result
+    else:
+        return True</code></pre>
+</details>
+</dd>
+<dt id="main.delete_assignment"><code class="name flex">
+<span>def <span class="ident">delete_assignment</span></span>(<span>aid) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Delete an assignment</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>aid</code></strong></dt>
+<dd>String, the assignment id (UUID format)</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>Boolean, True if assignment is deleted
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to retrieve endpoint details</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def delete_assignment(aid) -&gt; bool:
+    &#34;&#34;&#34; Delete an assignment
+
+    Args:
+        aid: String, the assignment id (UUID format)
+
+    Returns:
+        Boolean, True if assignment is deleted
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/assign/&#34; + glob.JWT_USER_ID + &#34;/&#34; + aid
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;DELETE&#34;, url, headers=headers)
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable delete your assignment.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete assignment. &#34; + str(e))
+        return False
+
+    if glob.DEBUG:
+        print(result)
+
+    return True</code></pre>
+</details>
+</dd>
+<dt id="main.delete_device"><code class="name flex">
+<span>def <span class="ident">delete_device</span></span>(<span>did) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Delete a device</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>did</code></strong></dt>
+<dd>String, the device id (aaa-bbb-ccc format)</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>Boolean, True if device is deleted
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to retrieve endpoint details</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def delete_device(did) -&gt; bool:
+    &#34;&#34;&#34; Delete a device
+
+    Args:
+        did: String, the device id (aaa-bbb-ccc format)
+
+    Returns:
+        Boolean, True if device is deleted
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/device/&#34; + glob.JWT_USER_ID + &#34;/&#34; + did
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;DELETE&#34;, url, headers=headers)
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable delete your device.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete device. &#34; + str(e))
+        return False
+
+    if glob.DEBUG:
+        print(result)
+
+    return True</code></pre>
+</details>
+</dd>
+<dt id="main.delete_endpoint"><code class="name flex">
+<span>def <span class="ident">delete_endpoint</span></span>(<span>cfid: str) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Deletes an endpoint by cfid.</p>
+<p>Delete an endpoint owned by the currently logged in user by cfid.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>cfid</code></strong></dt>
+<dd>String of the compute function id.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>True if successful, False otherwise.
+Raises
+(in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to delete endpoints</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def delete_endpoint(cfid: str) -&gt; bool:
+    &#34;&#34;&#34;Deletes an endpoint by cfid.
+
+    Delete an endpoint owned by the currently logged in user by cfid.
+
+    Args:
+        cfid: String of the compute function id.
+
+    Returns:
+        True if successful, False otherwise.
+
+    Raises  (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to delete endpoints
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/compute-function/&#34; + glob.JWT_USER_ID + &#34;/&#34; + cfid
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN,
+    }
+    try:
+        response = requests.request(&#34;DELETE&#34;, url, headers=headers, data={})
+        # Check if content type is JSON
+        if &#39;json&#39; in response.headers.get(&#39;Content-Type&#39;):
+            try:
+                result = json.loads(response.text)
+            except ValueError:  # simplejson.decoder.JSONDecodeError
+                if not glob.SILENT:
+                    print(&#34;Unable to decode JSON response from usermanager error.&#34;)
+                if glob.DEBUG:
+                    raise UserManagerError(result.get(&#34;Unable to decode JSON response from usermanager error.&#34;))
+                return False
+        else:
+            if not glob.SILENT:
+                print(&#34;Server at&#34;, glob.USER_MANAGER_URL, &#34;did not return a valid JSON document.&#34;)
+            if glob.DEBUG:
+                raise UserManagerError(&#34;Server at&#34;, glob.USER_MANAGER_URL, &#34;did not return a valid JSON document.&#34;)
+            return False
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to remove this endpoint from the server. \n&#34;
+                  &#34;Please try again later.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete endpoint. &#34; + str(e))
+        return False
+
+    if result.get(&#34;error&#34;) != &#34;&#34;:
+        if not glob.SILENT:
+            print(&#34;We were unable to remove this endpoint: \n&#34;
+                  &#34;Server error: &#34; + str(result.get(&#34;error&#34;)))
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to delete endpoint. &#34; + result.get(&#34;error&#34;))
+        return False
+
+    if not glob.SILENT:
+        print(&#34;Endpoint with cfid &#34; + cfid + &#34; was successfully deleted.&#34;)
+
+    return True</code></pre>
+</details>
+</dd>
+<dt id="main.delete_model"><code class="name flex">
+<span>def <span class="ident">delete_model</span></span>(<span>cfid: str) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Deletes a model by cfid.</p>
+<p>Delete an model owned by the currently logged in user by cfid.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>cfid</code></strong></dt>
+<dd>String of the compute function id.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>True if successful, False otherwise.
+Raises
+(in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to delete endpoints</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def delete_model(cfid: str) -&gt; bool:
+    &#34;&#34;&#34;Deletes a model by cfid.
+
+    Delete an model owned by the currently logged in user by cfid.
+
+    Args:
+        cfid: String of the compute function id.
+
+    Returns:
+        True if successful, False otherwise.
+
+    Raises  (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to delete endpoints
+    &#34;&#34;&#34;
+    return delete_endpoint(cfid)</code></pre>
+</details>
+</dd>
+<dt id="main.devices"><code class="name flex">
+<span>def <span class="ident">devices</span></span>(<span>offset=0, limit=20) ‑> dict</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Get all devices owned by the current user.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>offset</code></strong></dt>
+<dd>Int indicating the pagination offset. Default 0</dd>
+<dt><strong><code>limit</code></strong></dt>
+<dd>Int inidcating the pagination limit. Default 20</dd>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be printed. Default True.</dd>
+<dt><strong><code>_return</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be returned as a dict. Default False.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<dl>
+<dt><code><a title="main.endpoints" href="#main.endpoints">endpoints()</a></code></dt>
+<dd>if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]</dd>
+</dl>
+<p>otherwise the function will simply return True after printing the endpoints to the screen.
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to retrieve endpoint details</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def devices(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34; Get all devices owned by the current user.
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/devices/&#34; + glob.JWT_USER_ID + &#34;?limit=&#34; + str(limit) + &#34;&amp;offset=&#34; + str(
+        offset)
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;GET&#34;, url, headers=headers, data={})
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable retrieve your devices.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to retrieve devices. &#34; + str(e))
+        return False
+
+    # print if requested:
+    if _verbose and not glob.SILENT:
+        if not result:
+            if offset == 0:
+                print(&#34;You have not yet registered any devices&#34;)
+                print(&#34;\nNeed help getting started?&#34;)
+                print(&#34; - See the sclblpy docs at https://pypi.org/project/sclblpy/.&#34;)
+                print(&#34; - See our getting started tutorial at &#34;
+                      &#34;https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.&#34;)
+                print(&#34; - Or, login to your admin at https://admin.sclbl.net. \n&#34;)
+            else:
+                print(&#34;No devices found given the current settings; You could try to decrease the offset.&#34;)
+        else:
+            # Pretty printing of list
+            baseUrl = glob.EXAMPLE__BASE_URL
+            i = 1
+            print(&#34;We found the following device registrations:\n&#34;)
+            for key in result:
+                print(&#39;  {}: {}, \n&#39;
+                      &#39;   - did: {} \n&#39;
+                      &#39;   - rid: {} \n&#39;.format(i, key[&#39;name&#39;], key[&#39;did&#39;], key[&#39;rid&#39;]))
+                i = i + 1
+            print(&#34;Login at https://admin.sclbl.net to administer your devices.\n&#34;)
+
+    if _return:
+        return result
+    else:
+        return True</code></pre>
+</details>
+</dd>
+<dt id="main.endpoints"><code class="name flex">
+<span>def <span class="ident">endpoints</span></span>(<span>offset=0, limit=20) ‑> dict</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Print or return the endpoints available for the current user.</p>
+<p>Using the global JWT string this function by default prints a summary of the endpoints
+owned by the current user. The endpoints can also be returned as a dict by setting _return=True.</p>
+<p>Note that the call is paginated: use the offset and limit arguments to retrieve the desired
+list of endpoints. Endpoints are sorted with the latest upload being first, and the function retrieves
+the items from offset to (offset+limit). By default the 20 most recently created endpoints are returned.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>offset</code></strong></dt>
+<dd>Int indicating the pagination offset. Default 0</dd>
+<dt><strong><code>limit</code></strong></dt>
+<dd>Int inidcating the pagination limit. Default 20</dd>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be printed. Default True.</dd>
+<dt><strong><code>_return</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be returned as a dict. Default False.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<dl>
+<dt><code><a title="main.endpoints" href="#main.endpoints">endpoints()</a></code></dt>
+<dd>if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]</dd>
+</dl>
+<p>otherwise the function will simply return True after printing the endpoints to the screen.
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to retrieve endpoint details</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def endpoints(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34;Print or return the endpoints available for the current user.
+
+    Using the global JWT string this function by default prints a summary of the endpoints
+    owned by the current user. The endpoints can also be returned as a dict by setting _return=True.
+
+    Note that the call is paginated: use the offset and limit arguments to retrieve the desired
+    list of endpoints. Endpoints are sorted with the latest upload being first, and the function retrieves
+    the items from offset to (offset+limit). By default the 20 most recently created endpoints are returned.
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+
+    &#34;&#34;&#34;
+    try:
+        _check_jwt()
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable to renew your JWT lease. \n&#34;
+                  &#34;If this recurs use the remove_credentials() function to reset your login credentials.&#34;)
+        if glob.DEBUG:
+            raise JWTError(&#34;Unable to check JWT authorization. &#34; + str(e))
+        return False
+
+    url = glob.USER_MANAGER_URL + &#34;/compute-functions/&#34; + glob.JWT_USER_ID + &#34;?limit=&#34; + str(limit) + &#34;&amp;offset=&#34; + str(
+        offset)
+    headers = {
+        &#39;Authorization&#39;: glob.JWT_TOKEN
+    }
+
+    try:
+        response = requests.request(&#34;GET&#34;, url, headers=headers, data={})
+        result = json.loads(response.text)
+    except Exception as e:
+        if not glob.SILENT:
+            print(&#34;We were unable retrieve your endpoints.&#34;)
+        if glob.DEBUG:
+            raise UserManagerError(&#34;Unable to retrieve endpoints. &#34; + str(e))
+        return False
+
+    # print if requested:
+    if _verbose and not glob.SILENT:
+        if not result:
+            if offset == 0:
+                print(&#34;You currently do not own any active endpoints.&#34;)
+                print(&#34;\nNeed help getting started?&#34;)
+                print(&#34; - See the sclblpy docs at https://pypi.org/project/sclblpy/.&#34;)
+                print(&#34; - See our getting started tutorial at &#34;
+                      &#34;https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.&#34;)
+                print(&#34; - Or, login to your admin at https://admin.sclbl.net. \n&#34;)
+                print(&#34;NOTE: if you have just uploaded a model, please check your email; we will let you know when its &#34;
+                      &#34;available!\n&#34;)
+            else:
+                print(&#34;No endpoints found given the current settings; You could try to decrease the offset.&#34;)
+        else:
+            # Pretty printing of list
+            baseUrl = glob.EXAMPLE__BASE_URL
+            i = 1
+            print(&#34;You currently own the following endpoints:\n&#34;)
+            for key in result:
+                url = baseUrl + &#34;?cfid=&#34; + key[&#39;cfid&#39;]
+                url += &#34;&amp;exin=&#34; + urllib.parse.quote(key[&#39;exampleinput&#39;])
+
+                print(&#39;  {}: {}, \n&#39;
+                      &#39;   - cfid: {} \n&#39;
+                      &#39;   - example: {} \n&#39;.format(i, key[&#39;name&#39;], key[&#39;cfid&#39;], url))
+                i = i + 1
+            print(&#34;Login at https://admin.sclbl.net to administer your endpoints and see integration examples.\n&#34;)
+
+    if _return:
+        return result
+    else:
+        return True</code></pre>
+</details>
+</dd>
+<dt id="main.models"><code class="name flex">
+<span>def <span class="ident">models</span></span>(<span>offset=0, limit=20) ‑> dict</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Print or return the endpoints available for the current user.</p>
+<p>Simple wrapper for the endpoints() function.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>offset</code></strong></dt>
+<dd>Int indicating the pagination offset. Default 0</dd>
+<dt><strong><code>limit</code></strong></dt>
+<dd>Int inidcating the pagination limit. Default 20</dd>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be printed. Default True.</dd>
+<dt><strong><code>_return</code></strong></dt>
+<dd>Bool indicating whether the endpoints should be returned as a dict. Default False.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<dl>
+<dt><code><a title="main.endpoints" href="#main.endpoints">endpoints()</a></code></dt>
+<dd>if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]</dd>
+</dl>
+<p>otherwise the function will simply return True after printing the endpoints to the screen.
+Raises (in debug mode):
+JWTError if unable to obtain JWT authorization
+UserManagerError if unable to retrieve endpoint details</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def models(offset=0, limit=20, _verbose=True, _return=False) -&gt; dict:
+    &#34;&#34;&#34; Print or return the endpoints available for the current user.
+
+    Simple wrapper for the endpoints() function.
+
+    Args:
+        offset: Int indicating the pagination offset. Default 0
+        limit: Int inidcating the pagination limit. Default 20
+        _verbose: Bool indicating whether the endpoints should be printed. Default True.
+        _return: Bool indicating whether the endpoints should be returned as a dict. Default False.
+
+    Returns:
+         endpoints: if _return = True, a dict containing all the endpoints by the current user. [{},{},{}]
+         otherwise the function will simply return True after printing the endpoints to the screen.
+
+    Raises (in debug mode):
+        JWTError if unable to obtain JWT authorization
+        UserManagerError if unable to retrieve endpoint details
+    &#34;&#34;&#34;
+    return endpoints(offset=offset, limit=limit, _verbose=_verbose, _return=_return)</code></pre>
+</details>
+</dd>
+<dt id="main.remove_credentials"><code class="name flex">
+<span>def <span class="ident">remove_credentials</span></span>(<span>) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Remove your stored credentials.</p>
+<p>Remove the .creds.json file that stores the username and password
+of the current user.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Boolean indicator whether or not feedback should be printed. Default False.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>True is user credentials are found and deleted. False otherwise (often because they were not found).</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def remove_credentials(_verbose=True) -&gt; bool:
+    &#34;&#34;&#34;Remove your stored credentials.
+
+    Remove the .creds.json file that stores the username and password
+    of the current user.
+
+    Args:
+        _verbose: Boolean indicator whether or not feedback should be printed. Default False.
+
+    Returns:
+        True is user credentials are found and deleted. False otherwise (often because they were not found).
+    &#34;&#34;&#34;
+
+    # actual function in _utils.py to prevent circular includes.
+    removed = _remove_credentials()
+    if removed:
+        if _verbose and not glob.SILENT:
+            print(&#34;Successfully removed your user credentials.&#34;)
+        return True
+    else:
+        if _verbose and not glob.SILENT:
+            print(&#34;No user credentials found.&#34;)
+        return False</code></pre>
+</details>
+</dd>
+<dt id="main.start_print"><code class="name flex">
+<span>def <span class="ident">start_print</span></span>(<span>) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>(re)start printing user feedback</p>
+<h2 id="returns">Returns</h2>
+<p>True</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def start_print() -&gt; bool:
+    &#34;&#34;&#34;(re)start printing user feedback
+
+    Returns:
+        True
+
+    &#34;&#34;&#34;
+    print(&#34;Printing user feedback set to &#39;True&#39;.&#34;)
+    glob.SILENT = False
+    return True</code></pre>
+</details>
+</dd>
+<dt id="main.stop_print"><code class="name flex">
+<span>def <span class="ident">stop_print</span></span>(<span>) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Stop ALL printing of user feedback from package.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>_verbose</code></strong></dt>
+<dd>Boolean indicator whether or not feedback should be printed. Default False.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>True</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def stop_print(_verbose=False) -&gt; bool:
+    &#34;&#34;&#34;Stop ALL printing of user feedback from package.
+
+    Args:
+        _verbose: Boolean indicator whether or not feedback should be printed. Default False.
+
+    Returns:
+        True
+    &#34;&#34;&#34;
+    if _verbose:
+        print(&#34;Printing user feedback set to &#39;False&#39;.&#34;)
+    glob.SILENT = True
+    return True</code></pre>
+</details>
+</dd>
+<dt id="main.update_docs"><code class="name flex">
+<span>def <span class="ident">update_docs</span></span>(<span>cfid, docs) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates the documentation of an already existing model</p>
+<p>The update_docs function can be used to upload the documentation of an already existing model
+by simply providing the cfid and the new docs object.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>cfid</code></strong></dt>
+<dd>a string with a valid computeFunction ID.</dd>
+<dt><strong><code>docs</code></strong></dt>
+<dd>A dict{} containing the fields 'name' and 'documentation'</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>False if upload failed, true otherwise
+Raises
+(in debug mode):
+UploadModelError if unable to successfully bundle and upload the model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_docs(cfid, docs) -&gt; bool:
+    &#34;&#34;&#34;Updates the documentation of an already existing model
+
+    The update_docs function can be used to upload the documentation of an already existing model
+    by simply providing the cfid and the new docs object.
+
+    Args:
+        cfid: a string with a valid computeFunction ID.
+        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;
+
+    Returns:
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    &#34;&#34;&#34;
+
+    # check the docs:
+    print(docs)
+    name = docs.get(&#39;name&#39;, &#34;&#34;)
+    if name == &#34;&#34;:
+        print(&#34;FATAL: Please make sure to add a name to your documentation (using the &#39;name&#39;) field \n&#34;
+              &#34;Your model documentation has not been updated. \n&#34;)
+        return False
+    documentation = docs.get(&#39;documentation&#39;, &#34;&#34;)
+    if documentation == &#34;&#34;:
+        print(&#34;FATAL: Please make sure to your documentation (using the &#39;documentation&#39; field) \n&#34;
+              &#34;Your model documentation has not been updated. \n&#34;)
+        return False
+
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been uploaded. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # all ok, upload:
+    if auth:
+
+        url = glob.USER_MANAGER_URL + &#34;/compute-function/&#34; + glob.JWT_USER_ID + &#34;/&#34; + cfid
+
+        # Setup the actual request
+        data: dict = {
+            &#34;language&#34;: &#34;WASM&#34;,
+            &#34;public&#34;: True,
+            &#34;profit&#34;: 0.1,
+            &#34;cycles&#34;: 1.0,
+            &#34;name&#34;: name,
+            &#34;docs&#34;: documentation
+        }
+        payload: dict = {
+            &#39;data&#39;: json.dumps(data)
+        }
+
+        files = []
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN
+        }
+
+        # Do the request (and make sure to delete the gzip if errors occur)
+        try:
+            response = requests.put(url, headers=headers, data=payload, files=files)
+        except Exception as e:
+            if not glob.SILENT:
+                print(f&#34;FATAL: Unable to carry out the upload request: the toolchain is not available. \n&#34;
+                      &#34;Your model documentation has not been updated. PLACE 2 URL: {url} \n&#34;)
+                print(url)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the toolchain-server. \n&#34;
+                      &#34;Your model documentation has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the server. \n&#34;
+                      &#34;Your model documentation has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The documentation for &#34; + cfid + &#34; has been updated using:&#34;)
+            print(data)
+
+        # user feedback:
+        if not glob.SILENT:
+            print(&#34;Your model documentation has been updated. \n&#34;)
+        return True
+
+    else:
+        return False</code></pre>
+</details>
+</dd>
+<dt id="main.update_onnx"><code class="name flex">
+<span>def <span class="ident">update_onnx</span></span>(<span>path, cfid, example='', docs={}, email=True) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>upload_onnx updates a fitted onnx model to Scailable.</p>
+<p>The update function is similar to the upload function in most respects (so, see its docs),
+but instead of creating a new endpoint it overwrites the docs and model of an already existing
+endpoint. Thus, there is an additional argument "cfid" providing the computeFunction Id
+of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already
+existing endpoints.</p>
+<p>Note: If you solely want to change the documentation of an endpoint, you can either use the
+update_docs() function or the online admin interface at <a href="https://admin.sclble.net.">https://admin.sclble.net.</a></p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>path</code></strong></dt>
+<dd>The path referencing the onnx model location (i.e., the .onnx file location).</dd>
+<dt><strong><code>cfid</code></strong></dt>
+<dd>a string with a valid computeFunction ID.</dd>
+<dt><strong><code>example</code></strong></dt>
+<dd>String example input for the onnx file.</dd>
+<dt><strong><code>docs</code></strong></dt>
+<dd>A dict{} containing the fields 'name' and 'documentation'.</dd>
+<dt><strong><code>email</code></strong></dt>
+<dd>Bool indicating whether a confirmation email of a successful conversion should be send. Default True.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>False if upload failed, true otherwise
+Raises
+(in debug mode):
+UploadModelError if unable to successfully bundle and upload the model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_onnx(path, cfid, example=&#34;&#34;, docs={}, email=True) -&gt; bool:
+    &#34;&#34;&#34;upload_onnx updates a fitted onnx model to Scailable.
+
+    The update function is similar to the upload function in most respects (so, see its docs),
+    but instead of creating a new endpoint it overwrites the docs and model of an already existing
+    endpoint. Thus, there is an additional argument &#34;cfid&#34; providing the computeFunction Id
+    of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already
+    existing endpoints.
+
+    Note: If you solely want to change the documentation of an endpoint, you can either use the
+        update_docs() function or the online admin interface at https://admin.sclble.net.
+
+    Args:
+        path: The path referencing the onnx model location (i.e., the .onnx file location).
+        cfid: a string with a valid computeFunction ID.
+        example: String example input for the onnx file.
+        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;.
+        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
+
+    Returns:
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    &#34;&#34;&#34;
+    if glob.DEBUG:
+        print(&#34;We are checking your updated .onnx file...&#34;)
+
+    bundle = {}
+
+    # simply add example string to bundle:
+    bundle[&#39;example&#39;] = example
+
+    # check the docs:
+    bundle[&#39;docs&#39;] = {}
+    if docs:
+        bundle[&#39;docs&#39;] = docs
+    else:
+        try:  # This should work, but catching the exception just in case:
+            name = path
+        except Exception:
+            name = &#34;NAMELESS MODEL&#34;
+        bundle[&#39;docs&#39;][&#39;name&#39;] = name
+        bundle[&#39;docs&#39;][&#39;documentation&#39;] = &#34;-- EMPTY --&#34;
+        if not glob.SILENT:
+            print(&#34;WARNING: You did not provide any documentation. \n&#34;
+                  &#34;We will simply use &#34; + name + &#34; as its name without further documentation.&#34;)
+
+    # check if file exists:
+    if not path.endswith(&#39;.onnx&#39;):
+        if not glob.SILENT:
+            print(&#34;FATAL: You did not specify a .onnx path. \n&#34;
+                  &#34;Your model has not been updated. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file (no .onnx extension).&#34;)
+
+    # try to open the file
+    try:
+        files = [(&#39;bundle&#39;, open(path, &#39;rb&#39;))]
+    except Exception:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to open the specified onnx file. Is the path correct? \n&#34;
+                  &#34;Your model has not been updated. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file.&#34;)
+        return False
+
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been updated. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # get system information
+    bundle[&#39;system_info&#39;] = _get_system_info()
+
+    # all ok, upload:
+    if auth:
+
+        url = glob.TOOLCHAIN_URL + &#34;/upload/&#34; + glob.JWT_USER_ID + &#34;/&#34; + cfid
+
+        # Hard coded tootlchain name:
+        toolchain_name = &#34;onnx2c&#34;
+
+        # Setup the actual request
+        data: dict = {
+            &#39;email&#39;: email,
+            &#39;package&#39;: __version__,
+            &#39;toolchain&#39;: toolchain_name,
+            &#39;name&#39;: bundle[&#39;docs&#39;].get(&#39;name&#39;, &#34;No name found.&#34;),
+            &#39;docs&#39;: bundle[&#39;docs&#39;].get(&#39;documentation&#39;, &#34;No docs provided.&#34;),
+            &#39;exampleInput&#39;: example,
+            &#39;exampleOutput&#39;: &#34;&#34;
+        }
+        payload: dict = {
+            &#39;data&#39;: json.dumps(data)
+        }
+
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN,
+        }
+
+        try:
+            response = requests.put(url, headers=headers, data=payload, files=files)
+        except Exception as e:
+            if not glob.SILENT:
+                print(f&#34;FATAL: Unable to carry out the update request: the toolchain is not available. \n&#34;
+                      f&#34;Your model has not been updated. {url}, user id: {glob.JWT_USER_ID}, cfid:  {cfid}\n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the toolchain-server. \n&#34;
+                      &#34;Your model has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the toolchain-server. \n&#34;
+                      &#34;Your model has not been updated. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The following content has been send to the toolchain server:&#34;)
+            print(bundle)
+
+        # user feedback:
+        if not glob.SILENT:
+            print(&#34;Your model was successfully submitted for an update. \n&#34;)
+
+        return True
+
+    else:
+        return False</code></pre>
+</details>
+</dd>
+<dt id="main.upload_onnx"><code class="name flex">
+<span>def <span class="ident">upload_onnx</span></span>(<span>path, example='', docs={}, email=True) ‑> bool</span>
+</code></dt>
+<dd>
+<div class="desc"><p>upload_onnx uploads a fitted onnx model to Scailable.</p>
+<ul>
+<li>The function first checks if the supplied path indeed references a .onnx file</li>
+<li>Next, the docs are checked; if none are provided a warning is issued and a simple
+name is provided based on the model type.</li>
+<li>Finally the onnx file and the supporting docs are uploaded to the toolchain.</li>
+</ul>
+<p>Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
+stop_print() method.</p>
+<h2 id="args">Args</h2>
+<dl>
+<dt><strong><code>path</code></strong></dt>
+<dd>The path referencing the onnx model location (i.e., the .onnx file location).</dd>
+<dt><strong><code>example</code></strong></dt>
+<dd>String example input for the onnx file.</dd>
+<dt><strong><code>docs</code></strong></dt>
+<dd>A dict{} containing the fields 'name' and 'documentation'.</dd>
+<dt><strong><code>email</code></strong></dt>
+<dd>Bool indicating whether a confirmation email of a successful conversion should be send. Default True.</dd>
+</dl>
+<h2 id="returns">Returns</h2>
+<p>False if upload failed, true otherwise
+Raises
+(in debug mode):
+UploadModelError if unable to successfully bundle and upload the model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def upload_onnx(path, example=&#34;&#34;, docs={}, email=True) -&gt; bool:
+    &#34;&#34;&#34;upload_onnx uploads a fitted onnx model to Scailable.
+
+    - The function first checks if the supplied path indeed references a .onnx file
+    - Next, the docs are checked; if none are provided a warning is issued and a simple
+    name is provided based on the model type.
+    - Finally the onnx file and the supporting docs are uploaded to the toolchain.
+
+    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
+        stop_print() method.
+
+    Args:
+        path: The path referencing the onnx model location (i.e., the .onnx file location).
+        example: String example input for the onnx file.
+        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;.
+        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
+
+    Returns:
+        False if upload failed, true otherwise
+
+    Raises  (in debug mode):
+        UploadModelError if unable to successfully bundle and upload the model.
+    &#34;&#34;&#34;
+    if glob.DEBUG:
+        print(&#34;We are checking your .onnx file...&#34;)
+
+    bundle = {}
+
+    # simply add example string to bundle:
+    bundle[&#39;example&#39;] = example
+
+    # check the docs:
+    bundle[&#39;docs&#39;] = {}
+    if docs:
+        bundle[&#39;docs&#39;] = docs
+    else:
+        try:  # This should work, but catching the exception just in case:
+            name = path
+        except Exception:
+            name = &#34;NAMELESS MODEL&#34;
+        bundle[&#39;docs&#39;][&#39;name&#39;] = name
+        bundle[&#39;docs&#39;][&#39;documentation&#39;] = &#34;-- EMPTY --&#34;
+        if not glob.SILENT:
+            print(&#34;WARNING: You did not provide any documentation. \n&#34;
+                  &#34;We will simply use &#34; + name + &#34; as its name without further documentation.&#34;)
+
+    # check if file exists:
+    if not path.endswith(&#39;.onnx&#39;):
+        if not glob.SILENT:
+            print(&#34;FATAL: You did not specify a .onnx path. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file (no .onnx extension).&#34;)
+
+    # try to open the file
+    try:
+        files = [(&#39;bundle&#39;, open(path, &#39;rb&#39;))]
+    except Exception:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to open the specified onnx file. Is the path correct? \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to open the specified onnx file.&#34;)
+        return False
+
+    # check authorization:
+    auth = _check_jwt()
+    if not auth:
+        if not glob.SILENT:
+            print(&#34;FATAL: We were unable to obtain JWT authorization for your account. \n&#34;
+                  &#34;Your model has not been uploaded. \n&#34;)
+        if glob.DEBUG:
+            raise UploadModelError(&#34;We were unable to obtain JWT authorization.&#34;)
+        return False
+
+    # get system information
+    bundle[&#39;system_info&#39;] = _get_system_info()
+
+    # all ok, upload:
+    if auth:
+
+        url = glob.TOOLCHAIN_URL + &#34;/upload/&#34; + glob.JWT_USER_ID
+
+        # Hard coded tootlchain name:
+        toolchain_name = &#34;onnx2c&#34;
+
+        # Setup the actual request
+        data: dict = {
+            &#39;email&#39;: email,
+            &#39;package&#39;: __version__,
+            &#39;toolchain&#39;: toolchain_name,
+            &#39;name&#39;: bundle[&#39;docs&#39;].get(&#39;name&#39;, &#34;No name found.&#34;),
+            &#39;docs&#39;: bundle[&#39;docs&#39;].get(&#39;documentation&#39;, &#34;No docs provided.&#34;),
+            &#39;exampleInput&#39;: example,
+            &#39;exampleOutput&#39;: &#34;&#34;
+        }
+        payload: dict = {
+            &#39;data&#39;: json.dumps(data)
+        }
+
+        headers = {
+            &#39;Authorization&#39;: glob.JWT_TOKEN,
+        }
+
+        # Do the request
+        try:
+            response = requests.post(url, headers=headers, data=payload, files=files)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: Unable to carry out the upload request: the toolchain is not available. \n&#34;
+                      &#34;Your model has not been uploaded. PLACE 1 URL: {url}\n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We were unable to obtain JWT authorization: &#34; + str(e))
+            return False
+
+        # Error handling
+        try:
+            response_data = json.loads(response.text)
+        except Exception as e:
+            if not glob.SILENT:
+                print(&#34;FATAL: We did not receive a valid JSON response from the toolchain-server. \n&#34;
+                      &#34;Your model has not been uploaded. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + str(e))
+            return False
+
+        if response_data[&#39;error&#39;]:
+            if not glob.SILENT:
+                print(&#34;FATAL: An error was returned by the toolchain-server. \n&#34;
+                      &#34;Your model has not been uploaded. \n&#34;)
+            if glob.DEBUG:
+                raise UploadModelError(&#34;We did not receive a valid response from the server: &#34; + response_data[&#39;error&#39;])
+            return False
+
+        if glob.DEBUG:
+            print(&#34;The following content has been send to the toolchain server:&#34;)
+            print(bundle)
+
+        # user feedback:
+        if not glob.SILENT:
+            print(&#34;Your ONNX file was successfully uploaded to Scailable!&#34;)
+            print(&#34;NOTE: After transpiling, we will send you an email and your model will be available at &#34;
+                  &#34;https://admin.sclbl.net.&#34;)
+            print(&#34;Or, alternatively, you can use the &#39;models()&#39; function to list all your uploaded models. \n&#34;)
+
+        return True
+
+    else:
+        return False</code></pre>
+</details>
+</dd>
+<dt id="main.welcome"><code class="name flex">
+<span>def <span class="ident">welcome</span></span>(<span>)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Welcome simply prints a welcome message.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def welcome():
+    &#34;&#34;&#34; Welcome simply prints a welcome message.
+    &#34;&#34;&#34;
+    print(&#34;\n*** Thanks for importing sclblpy! ***&#34;)
+    print(&#34;You can use the &#39;upload()&#39; function to upload your models.&#34;)
+    print(&#34;To inspect your currently uploaded models, use `endpoints()`.&#34;)
+    print(&#34;Check the docs at https://pypi.org/project/sclblpy/ for more info. \n&#34;)</code></pre>
+</details>
+</dd>
+</dl>
+</section>
+<section>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3><a href="#header-functions">Functions</a></h3>
+<ul class="two-column">
+<li><code><a title="main.assign" href="#main.assign">assign</a></code></li>
+<li><code><a title="main.assignments" href="#main.assignments">assignments</a></code></li>
+<li><code><a title="main.delete_assignment" href="#main.delete_assignment">delete_assignment</a></code></li>
+<li><code><a title="main.delete_device" href="#main.delete_device">delete_device</a></code></li>
+<li><code><a title="main.delete_endpoint" href="#main.delete_endpoint">delete_endpoint</a></code></li>
+<li><code><a title="main.delete_model" href="#main.delete_model">delete_model</a></code></li>
+<li><code><a title="main.devices" href="#main.devices">devices</a></code></li>
+<li><code><a title="main.endpoints" href="#main.endpoints">endpoints</a></code></li>
+<li><code><a title="main.models" href="#main.models">models</a></code></li>
+<li><code><a title="main.remove_credentials" href="#main.remove_credentials">remove_credentials</a></code></li>
+<li><code><a title="main.start_print" href="#main.start_print">start_print</a></code></li>
+<li><code><a title="main.stop_print" href="#main.stop_print">stop_print</a></code></li>
+<li><code><a title="main.update_docs" href="#main.update_docs">update_docs</a></code></li>
+<li><code><a title="main.update_onnx" href="#main.update_onnx">update_onnx</a></code></li>
+<li><code><a title="main.upload_onnx" href="#main.upload_onnx">upload_onnx</a></code></li>
+<li><code><a title="main.welcome" href="#main.welcome">welcome</a></code></li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/main.m.html b/docs/main.m.html
deleted file mode 100644
index 6c07ef7..0000000
--- a/docs/main.m.html
+++ /dev/null
@@ -1,2792 +0,0 @@
-<!doctype html>
-<head>
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
-
-    <title>main API documentation</title>
-    <meta name="description" content="" />
-
-  <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,300' rel='stylesheet' type='text/css'>
-  
-  <style type="text/css">
-  
-* {
-  box-sizing: border-box;
-}
-/*! normalize.css v1.1.1 | MIT License | git.io/normalize */
-
-/* ==========================================================================
-   HTML5 display definitions
-   ========================================================================== */
-
-/**
- * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
-    display: block;
-}
-
-/**
- * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.
- */
-
-audio,
-canvas,
-video {
-    display: inline-block;
-    *display: inline;
-    *zoom: 1;
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
-    display: none;
-    height: 0;
-}
-
-/**
- * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.
- * Known issue: no IE 6 support.
- */
-
-[hidden] {
-    display: none;
-}
-
-/* ==========================================================================
-   Base
-   ========================================================================== */
-
-/**
- * 1. Prevent system color scheme's background color being used in Firefox, IE,
- *    and Opera.
- * 2. Prevent system color scheme's text color being used in Firefox, IE, and
- *    Opera.
- * 3. Correct text resizing oddly in IE 6/7 when body `font-size` is set using
- *    `em` units.
- * 4. Prevent iOS text size adjust after orientation change, without disabling
- *    user zoom.
- */
-
-html {
-    background: #fff; /* 1 */
-    color: #000; /* 2 */
-    font-size: 100%; /* 3 */
-    -webkit-text-size-adjust: 100%; /* 4 */
-    -ms-text-size-adjust: 100%; /* 4 */
-}
-
-/**
- * Address `font-family` inconsistency between `textarea` and other form
- * elements.
- */
-
-html,
-button,
-input,
-select,
-textarea {
-    font-family: sans-serif;
-}
-
-/**
- * Address margins handled incorrectly in IE 6/7.
- */
-
-body {
-    margin: 0;
-}
-
-/* ==========================================================================
-   Links
-   ========================================================================== */
-
-/**
- * Address `outline` inconsistency between Chrome and other browsers.
- */
-
-a:focus {
-    outline: thin dotted;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
-    outline: 0;
-}
-
-/* ==========================================================================
-   Typography
-   ========================================================================== */
-
-/**
- * Address font sizes and margins set differently in IE 6/7.
- * Address font sizes within `section` and `article` in Firefox 4+, Safari 5,
- * and Chrome.
- */
-
-h1 {
-    font-size: 2em;
-    margin: 0.67em 0;
-}
-
-h2 {
-    font-size: 1.5em;
-    margin: 0.83em 0;
-}
-
-h3 {
-    font-size: 1.17em;
-    margin: 1em 0;
-}
-
-h4 {
-    font-size: 1em;
-    margin: 1.33em 0;
-}
-
-h5 {
-    font-size: 0.83em;
-    margin: 1.67em 0;
-}
-
-h6 {
-    font-size: 0.67em;
-    margin: 2.33em 0;
-}
-
-/**
- * Address styling not present in IE 7/8/9, Safari 5, and Chrome.
- */
-
-abbr[title] {
-    border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.
- */
-
-b,
-strong {
-    font-weight: bold;
-}
-
-blockquote {
-    margin: 1em 40px;
-}
-
-/**
- * Address styling not present in Safari 5 and Chrome.
- */
-
-dfn {
-    font-style: italic;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- * Known issue: no IE 6/7 normalization.
- */
-
-hr {
-    -moz-box-sizing: content-box;
-    box-sizing: content-box;
-    height: 0;
-}
-
-/**
- * Address styling not present in IE 6/7/8/9.
- */
-
-mark {
-    background: #ff0;
-    color: #000;
-}
-
-/**
- * Address margins set differently in IE 6/7.
- */
-
-p,
-pre {
-    margin: 1em 0;
-}
-
-/**
- * Correct font family set oddly in IE 6, Safari 4/5, and Chrome.
- */
-
-code,
-kbd,
-pre,
-samp {
-    font-family: monospace, serif;
-    _font-family: 'courier new', monospace;
-    font-size: 1em;
-}
-
-/**
- * Improve readability of pre-formatted text in all browsers.
- */
-
-pre {
-    white-space: pre;
-    white-space: pre-wrap;
-    word-wrap: break-word;
-}
-
-/**
- * Address CSS quotes not supported in IE 6/7.
- */
-
-q {
-    quotes: none;
-}
-
-/**
- * Address `quotes` property not supported in Safari 4.
- */
-
-q:before,
-q:after {
-    content: '';
-    content: none;
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
-    font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
-    font-size: 75%;
-    line-height: 0;
-    position: relative;
-    vertical-align: baseline;
-}
-
-sup {
-    top: -0.5em;
-}
-
-sub {
-    bottom: -0.25em;
-}
-
-/* ==========================================================================
-   Lists
-   ========================================================================== */
-
-/**
- * Address margins set differently in IE 6/7.
- */
-
-dl,
-menu,
-ol,
-ul {
-    margin: 1em 0;
-}
-
-dd {
-    margin: 0 0 0 40px;
-}
-
-/**
- * Address paddings set differently in IE 6/7.
- */
-
-menu,
-ol,
-ul {
-    padding: 0 0 0 40px;
-}
-
-/**
- * Correct list images handled incorrectly in IE 7.
- */
-
-nav ul,
-nav ol {
-    list-style: none;
-    list-style-image: none;
-}
-
-/* ==========================================================================
-   Embedded content
-   ========================================================================== */
-
-/**
- * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.
- * 2. Improve image quality when scaled in IE 7.
- */
-
-img {
-    border: 0; /* 1 */
-    -ms-interpolation-mode: bicubic; /* 2 */
-}
-
-/**
- * Correct overflow displayed oddly in IE 9.
- */
-
-svg:not(:root) {
-    overflow: hidden;
-}
-
-/* ==========================================================================
-   Figures
-   ========================================================================== */
-
-/**
- * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11.
- */
-
-figure {
-    margin: 0;
-}
-
-/* ==========================================================================
-   Forms
-   ========================================================================== */
-
-/**
- * Correct margin displayed oddly in IE 6/7.
- */
-
-form {
-    margin: 0;
-}
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
-    border: 1px solid #c0c0c0;
-    margin: 0 2px;
-    padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct color not being inherited in IE 6/7/8/9.
- * 2. Correct text not wrapping in Firefox 3.
- * 3. Correct alignment displayed oddly in IE 6/7.
- */
-
-legend {
-    border: 0; /* 1 */
-    padding: 0;
-    white-space: normal; /* 2 */
-    *margin-left: -7px; /* 3 */
-}
-
-/**
- * 1. Correct font size not being inherited in all browsers.
- * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5,
- *    and Chrome.
- * 3. Improve appearance and consistency in all browsers.
- */
-
-button,
-input,
-select,
-textarea {
-    font-size: 100%; /* 1 */
-    margin: 0; /* 2 */
-    vertical-align: baseline; /* 3 */
-    *vertical-align: middle; /* 3 */
-}
-
-/**
- * Address Firefox 3+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-button,
-input {
-    line-height: normal;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+.
- * Correct `select` style inheritance in Firefox 4+ and Opera.
- */
-
-button,
-select {
-    text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- *    and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- *    `input` and others.
- * 4. Remove inner spacing in IE 7 without affecting normal text inputs.
- *    Known issue: inner spacing remains in IE 6.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
-    -webkit-appearance: button; /* 2 */
-    cursor: pointer; /* 3 */
-    *overflow: visible;  /* 4 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
-    cursor: default;
-}
-
-/**
- * 1. Address box sizing set to content-box in IE 8/9.
- * 2. Remove excess padding in IE 8/9.
- * 3. Remove excess padding in IE 7.
- *    Known issue: excess padding remains in IE 6.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
-    box-sizing: border-box; /* 1 */
-    padding: 0; /* 2 */
-    *height: 13px; /* 3 */
-    *width: 13px; /* 3 */
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
- *    (include `-moz` to future-proof).
- */
-
-input[type="search"] {
-    -webkit-appearance: textfield; /* 1 */
-    -moz-box-sizing: content-box;
-    -webkit-box-sizing: content-box; /* 2 */
-    box-sizing: content-box;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari 5 and Chrome
- * on OS X.
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
-    -webkit-appearance: none;
-}
-
-/**
- * Remove inner padding and border in Firefox 3+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-    border: 0;
-    padding: 0;
-}
-
-/**
- * 1. Remove default vertical scrollbar in IE 6/7/8/9.
- * 2. Improve readability and alignment in all browsers.
- */
-
-textarea {
-    overflow: auto; /* 1 */
-    vertical-align: top; /* 2 */
-}
-
-/* ==========================================================================
-   Tables
-   ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
-    border-collapse: collapse;
-    border-spacing: 0;
-}
-
-  </style>
-
-  <style type="text/css">
-  
-  html, body {
-    margin: 0;
-    padding: 0;
-    min-height: 100%;
-  }
-  body {
-    background: #fff;
-    font-family: "Source Sans Pro", "Helvetica Neueue", Helvetica, sans;
-    font-weight: 300;
-    font-size: 16px;
-    line-height: 1.6em;
-  }
-  #content {
-    width: 70%;
-    max-width: 850px;
-    float: left;
-    padding: 30px 60px;
-    border-left: 1px solid #ddd;
-  }
-  #sidebar {
-    width: 25%;
-    float: left;
-    padding: 30px;
-    overflow: hidden;
-  }
-  #nav {
-    font-size: 130%;
-    margin: 0 0 15px 0;
-  }
-
-  #top {
-    display: block;
-    position: fixed;
-    bottom: 5px;
-    left: 5px;
-    font-size: .85em;
-    text-transform: uppercase;
-  }
-
-  #footer {
-    font-size: .75em;
-    padding: 5px 30px;
-    border-top: 1px solid #ddd;
-    text-align: right;
-  }
-    #footer p {
-      margin: 0 0 0 30px;
-      display: inline-block;
-    }
-
-  h1, h2, h3, h4, h5 {
-    font-weight: 300;
-  }
-  h1 {
-    font-size: 2.5em;
-    line-height: 1.1em;
-    margin: 0 0 .50em 0;
-  }
-
-  h2 {
-    font-size: 1.75em;
-    margin: 1em 0 .50em 0;
-  }
-
-  h3 {
-    margin: 25px 0 10px 0;
-  }
-
-  h4 {
-    margin: 0;
-    font-size: 105%;
-  }
-
-  a {
-    color: #058;
-    text-decoration: none;
-    transition: color .3s ease-in-out;
-  }
-
-  a:hover {
-    color: #e08524;
-    transition: color .3s ease-in-out;
-  }
-
-  pre, code, .mono, .name {
-    font-family: "Ubuntu Mono", "Cousine", "DejaVu Sans Mono", monospace;
-  }
-
-  .title .name {
-    font-weight: bold;
-  }
-  .section-title {
-    margin-top: 2em;
-  }
-  .ident {
-    color: #900;
-  }
-
-  code {
-    background: #f9f9f9;
-  } 
-
-  pre {
-    background: #fefefe;
-    border: 1px solid #ddd;
-    box-shadow: 2px 2px 0 #f3f3f3;
-    margin: 0 30px;
-    padding: 15px 30px;
-  }
-
-  .codehilite {
-    margin: 0 30px 10px 30px;
-  }
-
-    .codehilite pre {
-      margin: 0;
-    }
-    .codehilite .err { background: #ff3300; color: #fff !important; } 
-
-  table#module-list {
-    font-size: 110%;
-  }
-
-    table#module-list tr td:first-child {
-      padding-right: 10px;
-      white-space: nowrap;
-    }
-
-    table#module-list td {
-      vertical-align: top;
-      padding-bottom: 8px;
-    }
-
-      table#module-list td p {
-        margin: 0 0 7px 0;
-      }
-
-  .def {
-    display: table;
-  }
-
-    .def p {
-      display: table-cell;
-      vertical-align: top;
-      text-align: left;
-    }
-
-    .def p:first-child {
-      white-space: nowrap;
-    }
-
-    .def p:last-child {
-      width: 100%;
-    }
-
-
-  #index {
-    list-style-type: none;
-    margin: 0;
-    padding: 0;
-  }
-    ul#index .class_name {
-      /* font-size: 110%; */
-      font-weight: bold;
-    }
-    #index ul {
-      margin: 0;
-    }
-
-  .item {
-    margin: 0 0 15px 0;
-  }
-
-    .item .class {
-      margin: 0 0 25px 30px;
-    }
-
-      .item .class ul.class_list {
-        margin: 0 0 20px 0;
-      }
-
-    .item .name {
-      background: #fafafa;
-      margin: 0;
-      font-weight: bold;
-      padding: 5px 10px;
-      border-radius: 3px;
-      display: inline-block;
-      min-width: 40%;
-    }
-      .item .name:hover {
-        background: #f6f6f6;
-      }
-
-    .item .empty_desc {
-      margin: 0 0 5px 0;
-      padding: 0;
-    }
-
-    .item .inheritance {
-      margin: 3px 0 0 30px;
-    }
-
-    .item .inherited {
-      color: #666;
-    }
-
-    .item .desc {
-      padding: 0 8px;
-      margin: 0;
-    }
-
-      .item .desc p {
-        margin: 0 0 10px 0;
-      }
-
-    .source_cont {
-      margin: 0;
-      padding: 0;
-    }
-
-    .source_link a {
-      background: #ffc300;
-      font-weight: 400;
-      font-size: .75em;
-      text-transform: uppercase;
-      color: #fff;
-      text-shadow: 1px 1px 0 #f4b700;
-      
-      padding: 3px 8px;
-      border-radius: 2px;
-      transition: background .3s ease-in-out;
-    }
-      .source_link a:hover {
-        background: #FF7200;
-        text-shadow: none;
-        transition: background .3s ease-in-out;
-      }
-
-    .source {
-      display: none;
-      max-height: 600px;
-      overflow-y: scroll;
-      margin-bottom: 15px;
-    }
-
-      .source .codehilite {
-        margin: 0;
-      }
-
-  .desc h1, .desc h2, .desc h3 {
-    font-size: 100% !important;
-  }
-  .clear {
-    clear: both;
-  }
-
-  @media all and (max-width: 950px) {
-    #sidebar {
-      width: 35%;
-    }
-    #content {
-      width: 65%;
-    }
-  }
-  @media all and (max-width: 650px) {
-    #top {
-      display: none;
-    }
-    #sidebar {
-      float: none;
-      width: auto;
-    }
-    #content {
-      float: none;
-      width: auto;
-      padding: 30px;
-    }
-
-    #index ul {
-      padding: 0;
-      margin-bottom: 15px;
-    }
-    #index ul li {
-      display: inline-block;
-      margin-right: 30px;
-    }
-    #footer {
-      text-align: left;
-    }
-    #footer p {
-      display: block;
-      margin: inherit;
-    }
-  }
-
-  /*****************************/
-
-  </style>
-
-  <style type="text/css">
-  .codehilite .hll { background-color: #ffffcc }
-.codehilite  { background: #f8f8f8; }
-.codehilite .c { color: #408080; font-style: italic } /* Comment */
-.codehilite .err { border: 1px solid #FF0000 } /* Error */
-.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
-.codehilite .o { color: #666666 } /* Operator */
-.codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
-.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */
-.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */
-.codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
-.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */
-.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */
-.codehilite .gd { color: #A00000 } /* Generic.Deleted */
-.codehilite .ge { font-style: italic } /* Generic.Emph */
-.codehilite .gr { color: #FF0000 } /* Generic.Error */
-.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.codehilite .gi { color: #00A000 } /* Generic.Inserted */
-.codehilite .go { color: #888888 } /* Generic.Output */
-.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
-.codehilite .gs { font-weight: bold } /* Generic.Strong */
-.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.codehilite .gt { color: #0044DD } /* Generic.Traceback */
-.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
-.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
-.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
-.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
-.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
-.codehilite .kt { color: #B00040 } /* Keyword.Type */
-.codehilite .m { color: #666666 } /* Literal.Number */
-.codehilite .s { color: #BA2121 } /* Literal.String */
-.codehilite .na { color: #7D9029 } /* Name.Attribute */
-.codehilite .nb { color: #008000 } /* Name.Builtin */
-.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
-.codehilite .no { color: #880000 } /* Name.Constant */
-.codehilite .nd { color: #AA22FF } /* Name.Decorator */
-.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */
-.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
-.codehilite .nf { color: #0000FF } /* Name.Function */
-.codehilite .nl { color: #A0A000 } /* Name.Label */
-.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
-.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
-.codehilite .nv { color: #19177C } /* Name.Variable */
-.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
-.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
-.codehilite .mb { color: #666666 } /* Literal.Number.Bin */
-.codehilite .mf { color: #666666 } /* Literal.Number.Float */
-.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
-.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
-.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
-.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
-.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
-.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
-.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
-.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
-.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
-.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
-.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
-.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
-.codehilite .sx { color: #008000 } /* Literal.String.Other */
-.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */
-.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
-.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
-.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
-.codehilite .fm { color: #0000FF } /* Name.Function.Magic */
-.codehilite .vc { color: #19177C } /* Name.Variable.Class */
-.codehilite .vg { color: #19177C } /* Name.Variable.Global */
-.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
-.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
-.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */
-  </style>
-
-  <style type="text/css">
-  
-/* ==========================================================================
-   EXAMPLE Media Queries for Responsive Design.
-   These examples override the primary ('mobile first') styles.
-   Modify as content requires.
-   ========================================================================== */
-
-@media only screen and (min-width: 35em) {
-    /* Style adjustments for viewports that meet the condition */
-}
-
-@media print,
-       (-o-min-device-pixel-ratio: 5/4),
-       (-webkit-min-device-pixel-ratio: 1.25),
-       (min-resolution: 120dpi) {
-    /* Style adjustments for high resolution devices */
-}
-
-/* ==========================================================================
-   Print styles.
-   Inlined to avoid required HTTP connection: h5bp.com/r
-   ========================================================================== */
-
-@media print {
-    * {
-        background: transparent !important;
-        color: #000 !important; /* Black prints faster: h5bp.com/s */
-        box-shadow: none !important;
-        text-shadow: none !important;
-    }
-
-    a,
-    a:visited {
-        text-decoration: underline;
-    }
-
-    a[href]:after {
-        content: " (" attr(href) ")";
-    }
-
-    abbr[title]:after {
-        content: " (" attr(title) ")";
-    }
-
-    /*
-     * Don't show links for images, or javascript/internal links
-     */
-
-    .ir a:after,
-    a[href^="javascript:"]:after,
-    a[href^="#"]:after {
-        content: "";
-    }
-
-    pre,
-    blockquote {
-        border: 1px solid #999;
-        page-break-inside: avoid;
-    }
-
-    thead {
-        display: table-header-group; /* h5bp.com/t */
-    }
-
-    tr,
-    img {
-        page-break-inside: avoid;
-    }
-
-    img {
-        max-width: 100% !important;
-    }
-
-    @page {
-        margin: 0.5cm;
-    }
-
-    p,
-    h2,
-    h3 {
-        orphans: 3;
-        widows: 3;
-    }
-
-    h2,
-    h3 {
-        page-break-after: avoid;
-    }
-}
-
-  </style>
-
-  <script type="text/javascript">
-  function toggle(id, $link) {
-    $node = document.getElementById(id);
-    if (!$node)
-    return;
-    if (!$node.style.display || $node.style.display == 'none') {
-    $node.style.display = 'block';
-    $link.innerHTML = 'Hide source &nequiv;';
-    } else {
-    $node.style.display = 'none';
-    $link.innerHTML = 'Show source &equiv;';
-    }
-  }
-  </script>
-</head>
-<body>
-<a href="#" id="top">Top</a>
-
-<div id="container">
-    
-  
-  <div id="sidebar">
-    <h1>Index</h1>
-    <ul id="index">
-
-    <li class="set"><h3><a href="#header-functions">Functions</a></h3>
-      
-  <ul>
-    <li class="mono"><a href="#main.delete_endpoint">delete_endpoint</a></li>
-    <li class="mono"><a href="#main.endpoints">endpoints</a></li>
-    <li class="mono"><a href="#main.list_models">list_models</a></li>
-    <li class="mono"><a href="#main.remove_credentials">remove_credentials</a></li>
-    <li class="mono"><a href="#main.start_print">start_print</a></li>
-    <li class="mono"><a href="#main.stop_print">stop_print</a></li>
-    <li class="mono"><a href="#main.update">update</a></li>
-    <li class="mono"><a href="#main.update_docs">update_docs</a></li>
-    <li class="mono"><a href="#main.upload">upload</a></li>
-  </ul>
-
-    </li>
-
-
-    </ul>
-  </div>
-
-    <article id="content">
-      
-  
-
-  
-
-
-  <header id="section-intro">
-  <h1 class="title"><span class="name">main</span> module</h1>
-  
-  
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main', this);">Show source &equiv;</a></p>
-  <div id="source-main" class="source">
-    <div class="codehilite"><pre><span></span><span class="c1"># File contains all public methods of the scblpy package</span>
-<span class="kn">import</span> <span class="nn">json</span>
-<span class="kn">import</span> <span class="nn">requests</span>
-
-<span class="kn">import</span> <span class="nn">sclblpy._globals</span> <span class="k">as</span> <span class="nn">glob</span>
-<span class="kn">from</span> <span class="nn">sclblpy._bundle</span> <span class="kn">import</span> <span class="n">_gzip_save</span><span class="p">,</span> <span class="n">_gzip_delete</span>
-<span class="kn">from</span> <span class="nn">sclblpy._jwt</span> <span class="kn">import</span> <span class="n">_check_jwt</span><span class="p">,</span> <span class="n">_remove_credentials</span>
-<span class="kn">from</span> <span class="nn">sclblpy._utils</span> <span class="kn">import</span> <span class="n">_get_model_name</span><span class="p">,</span> <span class="n">_get_system_info</span><span class="p">,</span> <span class="n">_predict</span><span class="p">,</span> <span class="n">_get_model_package</span><span class="p">,</span> <span class="n">_load_supported_models</span><span class="p">,</span> \
-    <span class="n">_check_model</span>
-<span class="kn">from</span> <span class="nn">sclblpy.errors</span> <span class="kn">import</span> <span class="n">UserManagerError</span><span class="p">,</span> <span class="n">JWTError</span><span class="p">,</span> <span class="n">UploadModelError</span>
-<span class="kn">from</span> <span class="nn">sclblpy.version</span> <span class="kn">import</span> <span class="n">__version__</span>
-
-
-<span class="k">def</span> <span class="nf">upload</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">,</span> <span class="n">docs</span><span class="o">=</span><span class="p">{},</span> <span class="n">email</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">_keep</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Uploads a fitted model to Scailable.</span>
-
-<span class="sd">    The upload function is the main workhorse of the sclblpy package.</span>
-<span class="sd">    The function first checks whether the supplied model is ok (part of the list and fitted).</span>
-
-<span class="sd">    Next, it checks whether an example row is provided and if so it creates the example</span>
-<span class="sd">    input and output .json objects.</span>
-
-<span class="sd">    Next, the docs are checked; if none are provided a warning is issued and a simple</span>
-<span class="sd">    name is provided based on the model type.</span>
-
-<span class="sd">    Subsequently, we package the whole thing, including details of the user system, into a</span>
-<span class="sd">    gzipped file that is stored on disc.</span>
-
-<span class="sd">    Finally the whole package is uploaded to the toolchain.</span>
-
-<span class="sd">    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the</span>
-<span class="sd">        stop_print() method.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        mod: The model to be uploaded.</span>
-<span class="sd">        feature_vector: An example feature_vector for your model.</span>
-<span class="sd">            (i.e., the first row of your training data X obtained using row = X[0,:])</span>
-<span class="sd">        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;</span>
-<span class="sd">        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.</span>
-<span class="sd">        _keep: Bool indicating whether the .gzipped file should be retained. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        False if upload failed, true otherwise</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        UploadModelError if unable to successfully bundle and upload the model.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="n">bundle</span> <span class="o">=</span> <span class="p">{}</span>
-
-    <span class="c1"># Check model:</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_check_model</span><span class="p">(</span><span class="n">mod</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: The model you are trying to upload is not (yet) supported or has not been fitted. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please see README.md for a list of supported models. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your models has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;The uploaded model is not supported.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;fitted_model&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">mod</span>
-
-    <span class="c1"># check input vector and generate an example:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="k">if</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">any</span><span class="p">():</span>
-        <span class="c1"># try prediction</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">output</span> <span class="o">=</span> <span class="n">_predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">)</span>  <span class="c1"># predict raises error if unable to generate predcition</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to create an example inference. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;Unable to generate prediction: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-        <span class="c1"># format data:</span>
-        <span class="n">input_str</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s1">&#39;[[</span><span class="si">%s</span><span class="s1">]]&#39;</span> <span class="o">%</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">tolist</span><span class="p">()])</span>
-        <span class="n">example</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;input&#39;</span><span class="p">:</span> <span class="n">input_str</span><span class="p">,</span> <span class="s2">&quot;output&quot;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">output</span><span class="p">)}</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">example</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: You did not provide a required example instance. (see docs). </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># check the docs:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="k">if</span> <span class="n">docs</span><span class="p">:</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">docs</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">try</span><span class="p">:</span>  <span class="c1"># This should work, but catching the exception just in case:</span>
-            <span class="n">name</span> <span class="o">=</span> <span class="n">_get_model_name</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
-            <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;NAMELESS MODEL&quot;</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">][</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">][</span><span class="s1">&#39;documentation&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;-- EMPTY --&quot;</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;WARNING: You did not provide any documentation. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;We will simply use &quot;</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">&quot; as its name without further documentation.&quot;</span><span class="p">)</span>
-
-    <span class="c1"># check authorization:</span>
-    <span class="n">auth</span> <span class="o">=</span> <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">auth</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to obtain JWT authorization for your account. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># get system information</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;system_info&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_get_system_info</span><span class="p">()</span>
-
-    <span class="c1"># gzip the bundle</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_gzip_save</span><span class="p">(</span><span class="n">bundle</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to gzip your model bundle. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to save the bundle.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># all ok, upload:</span>
-    <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
-
-        <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span> <span class="o">+</span> <span class="s2">&quot;/upload/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span>
-
-        <span class="c1"># Map python package to the right toolchain:</span>
-        <span class="n">pkg_name</span> <span class="o">=</span> <span class="n">_get_model_package</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
-        <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
-        <span class="k">if</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;sklearn&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;statsmodels&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;xgboost&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;lightgbm&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-
-        <span class="c1"># Setup the actual request</span>
-        <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;email&#39;</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span>
-            <span class="s1">&#39;package&#39;</span><span class="p">:</span> <span class="n">__version__</span><span class="p">,</span>
-            <span class="s1">&#39;toolchain&#39;</span><span class="p">:</span> <span class="n">toolchain_name</span><span class="p">,</span>
-            <span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s2">&quot;No name found.&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;docs&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;documentation&#39;</span><span class="p">,</span> <span class="s2">&quot;No docs provided.&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;exampleInput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;input&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;exampleOutput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;output&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">)</span>
-        <span class="p">}</span>
-        <span class="n">payload</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;data&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-        <span class="p">}</span>
-
-        <span class="n">files</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;bundle&#39;</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="n">glob</span><span class="o">.</span><span class="n">GZIP_BUNDLE</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">))]</span>
-        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-        <span class="p">}</span>
-
-        <span class="c1"># Do the request (and make sure to delete the gzip if errors occur)</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Unable to carry out the upload request: the toolchain is not available. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="c1"># Error handling</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We did not receive a valid JSON response from the toolchain-server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: An error was returned by the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">])</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;The following content has been send to the toolchain server:&quot;</span><span class="p">)</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">bundle</span><span class="p">)</span>
-
-        <span class="c1"># user feedback:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Your model was successfully uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-
-        <span class="c1"># remove bundle:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-            <span class="n">_gzip_delete</span><span class="p">()</span>
-
-        <span class="k">return</span> <span class="kc">True</span>
-
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-
-<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">,</span> <span class="n">cfid</span><span class="p">,</span> <span class="n">docs</span><span class="o">=</span><span class="p">{},</span> <span class="n">email</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">_keep</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Updates an already existing model.</span>
-
-<span class="sd">    The update function is similar to the upload function in most respects (so, see its docs),</span>
-<span class="sd">    but instead of creating a new endpoint it overwrites the docs and model of an already exisitng</span>
-<span class="sd">    endpoint. Thus, there is an additional argument &quot;cfid&quot; providing the computeFunction Id</span>
-<span class="sd">    of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already</span>
-<span class="sd">    existing endpoints.</span>
-
-<span class="sd">    Note: If you solely want to change the documentation of an endpoint, you can either use the</span>
-<span class="sd">        update_docs() function or the online admin interface at https://admin.sclble.net.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        mod: The model to be uploaded.</span>
-<span class="sd">        feature_vector: An example feature_vector for your model.</span>
-<span class="sd">            (i.e., the first row of your training data X obtained using row = X[0,:])</span>
-<span class="sd">        cfid: a string with a valid computeFunction ID.</span>
-<span class="sd">        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;. Default {}.</span>
-<span class="sd">        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.</span>
-<span class="sd">        _keep: Bool indicating whether the .gzipped file should be retained. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        False if upload failed, true otherwise</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        UploadModelError if unable to successfully bundle and upload the model.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="n">bundle</span> <span class="o">=</span> <span class="p">{}</span>
-
-    <span class="c1"># Check model:</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_check_model</span><span class="p">(</span><span class="n">mod</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: The model you are trying to upload is not (yet) supported or has not been fitted. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please see README.md for a list of supported models. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your models has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;The submitted model is not supported.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;fitted_model&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">mod</span>
-
-    <span class="c1"># check input vector and generate an example:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="k">if</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">any</span><span class="p">():</span>
-        <span class="c1"># try prediction</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">output</span> <span class="o">=</span> <span class="n">_predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">)</span>  <span class="c1"># predict raises error if unable to generate predcition</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to create an example inference. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;Unable to generate prediction: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-        <span class="c1"># format data:</span>
-        <span class="n">input_str</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s1">&#39;[[</span><span class="si">%s</span><span class="s1">]]&#39;</span> <span class="o">%</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">tolist</span><span class="p">()])</span>
-        <span class="n">example</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;input&#39;</span><span class="p">:</span> <span class="n">input_str</span><span class="p">,</span> <span class="s2">&quot;output&quot;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">output</span><span class="p">)}</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">example</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: You did not provide a required example instance. (see docs). </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># check the docs:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="n">docs_update</span> <span class="o">=</span> <span class="kc">True</span>
-    <span class="k">if</span> <span class="n">docs</span><span class="p">:</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">docs</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="n">docs_update</span> <span class="o">=</span> <span class="kc">False</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;WARNING: You did not provide any documentation. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;We will only update the .wasm model, not the documentation.&quot;</span><span class="p">)</span>
-
-    <span class="c1"># check authorization:</span>
-    <span class="n">auth</span> <span class="o">=</span> <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">auth</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to obtain JWT authorization for your account. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># get system information</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;system_info&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_get_system_info</span><span class="p">()</span>
-
-    <span class="c1"># gzip the bundle</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_gzip_save</span><span class="p">(</span><span class="n">bundle</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to gzip your model bundle. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to save the bundle.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># all ok, upload:</span>
-    <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
-
-        <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span> <span class="o">+</span> <span class="s2">&quot;/upload/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">+</span> <span class="n">cfid</span>
-        <span class="nb">print</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
-
-        <span class="c1"># Map python package to the right toolchain:</span>
-        <span class="n">pkg_name</span> <span class="o">=</span> <span class="n">_get_model_package</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
-        <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
-        <span class="k">if</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;sklearn&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;statsmodels&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;xgboost&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;lightgbm&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-
-        <span class="c1"># Setup the actual request</span>
-        <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;email&#39;</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span>
-            <span class="s1">&#39;package&#39;</span><span class="p">:</span> <span class="n">__version__</span><span class="p">,</span>
-            <span class="s1">&#39;toolchain&#39;</span><span class="p">:</span> <span class="n">toolchain_name</span><span class="p">,</span>
-            <span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;docs&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;documentation&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;updateDocs&#39;</span><span class="p">:</span> <span class="n">docs_update</span><span class="p">,</span>
-            <span class="s1">&#39;exampleInput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;input&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;exampleOutput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;output&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">)</span>
-        <span class="p">}</span>
-        <span class="n">payload</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;data&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-        <span class="p">}</span>
-
-        <span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-
-        <span class="n">files</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;bundle&#39;</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="n">glob</span><span class="o">.</span><span class="n">GZIP_BUNDLE</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">))]</span>
-        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-        <span class="p">}</span>
-
-        <span class="c1"># Do the request (and make sure to delete the gzip if errors occur)</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Unable to carry out the upload request: the toolchain is not available. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="c1"># Error handling</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We did not receive a valid JSON response from the toolchain-server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: An error was returned by the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">])</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;The following content has been send to the toolchain server:&quot;</span><span class="p">)</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">bundle</span><span class="p">)</span>
-
-        <span class="c1"># user feedback:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Your model was successfully submitted for an update. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-
-        <span class="c1"># remove bundle:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-            <span class="n">_gzip_delete</span><span class="p">()</span>
-
-        <span class="k">return</span> <span class="kc">True</span>
-
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-
-<span class="k">def</span> <span class="nf">update_docs</span><span class="p">(</span><span class="n">cfid</span><span class="p">,</span> <span class="n">docs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Updates the documentation of an already existing model</span>
-
-<span class="sd">    The update_docs function can be used to upload the documentation of an already existing model</span>
-<span class="sd">    by simply providing the cfid and the new docs object.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        cfid: a string with a valid computeFunction ID.</span>
-<span class="sd">        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        False if upload failed, true otherwise</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        UploadModelError if unable to successfully bundle and upload the model.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-
-    <span class="c1"># check the docs:</span>
-    <span class="n">name</span> <span class="o">=</span> <span class="n">docs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
-    <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Please make sure to add a name to your documentation (using the &#39;name&#39;) field </span><span class="se">\n</span><span class="s2">&quot;</span>
-              <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-    <span class="n">documentation</span> <span class="o">=</span> <span class="n">docs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;documentation&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
-    <span class="k">if</span> <span class="n">documentation</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Please make sure to your documentation (using the &#39;documentation&#39; field) </span><span class="se">\n</span><span class="s2">&quot;</span>
-              <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># check authorization:</span>
-    <span class="n">auth</span> <span class="o">=</span> <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">auth</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to obtain JWT authorization for your account. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># all ok, upload:</span>
-    <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
-
-        <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">+</span> <span class="s2">&quot;/compute-function/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">+</span> <span class="n">cfid</span>
-
-        <span class="c1"># Setup the actual request</span>
-        <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s2">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;WASM&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;public&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
-            <span class="s2">&quot;profit&quot;</span><span class="p">:</span> <span class="mf">0.1</span><span class="p">,</span>
-            <span class="s2">&quot;cycles&quot;</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span>
-            <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
-            <span class="s2">&quot;docs&quot;</span><span class="p">:</span> <span class="n">documentation</span>
-        <span class="p">}</span>
-        <span class="n">payload</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;data&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-        <span class="p">}</span>
-
-        <span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
-        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-        <span class="p">}</span>
-
-        <span class="c1"># Do the request (and make sure to delete the gzip if errors occur)</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Unable to carry out the upload request: the toolchain is not available. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="c1"># Error handling</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We did not receive a valid JSON response from the toolchain-server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: An error was returned by the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">])</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;The documentation for &quot;</span> <span class="o">+</span> <span class="n">cfid</span> <span class="o">+</span> <span class="s2">&quot; has been updated using:&quot;</span><span class="p">)</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-
-        <span class="c1"># user feedback:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Your model documentation has been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">True</span>
-
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-
-<span class="k">def</span> <span class="nf">endpoints</span><span class="p">(</span><span class="n">_verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Return the endpoints available for the current user.</span>
-
-<span class="sd">    Using the global JWT string this function returns a dict</span>
-<span class="sd">    of the endpoints by the current user.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        _verbose: Bool indicating whether the endpoints should be printed. Default True.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">         endpoints: a list containing all the endpoints by the current user. [{},{},{}]</span>
-
-<span class="sd">    Raises (in debug mode):</span>
-<span class="sd">        JWTError if unable to obtain JWT authorization</span>
-<span class="sd">        UserManagerError if unable to retrieve endpoint details</span>
-
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to renew your JWT lease. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;If this recurs use the remove_credentials() function to reset your login credentials.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">JWTError</span><span class="p">(</span><span class="s2">&quot;Unable to check JWT authorization. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">+</span> <span class="s2">&quot;/compute-functions/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span>
-    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-        <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-    <span class="p">}</span>
-
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{})</span>
-        <span class="n">result</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable retrieve your endpoints. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please try again later.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Unable to retrieve endpoints. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># print if requested:</span>
-    <span class="k">if</span> <span class="n">_verbose</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;You currently do not own any active endpoints.&quot;</span><span class="p">)</span>
-        <span class="k">else</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;You currently own the following endpoints:&quot;</span><span class="p">)</span>
-            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Name: </span><span class="si">{}</span><span class="s1">, cfid: </span><span class="si">{}</span><span class="s1">.&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">],</span> <span class="n">key</span><span class="p">[</span><span class="s1">&#39;cfid&#39;</span><span class="p">]))</span>
-
-    <span class="k">return</span> <span class="n">result</span>
-
-
-<span class="k">def</span> <span class="nf">delete_endpoint</span><span class="p">(</span><span class="n">cfid</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Deletes an endpoint by cfid.</span>
-
-<span class="sd">    Delete an endpoint owned by the currently logged in user by cfid.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        cfid: String of the compute function id.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True if successful, False otherwise.</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        JWTError if unable to obtain JWT authorization</span>
-<span class="sd">        UserManagerError if unable to delete endpoints</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to renew your JWT lease. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;If this recurs use the remove_credentials() function to reset your login credentials.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">JWTError</span><span class="p">(</span><span class="s2">&quot;Unable to check JWT authorization. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">+</span> <span class="s2">&quot;/compute-function/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">+</span> <span class="n">cfid</span>
-    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-        <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-    <span class="p">}</span>
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;DELETE&quot;</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{})</span>
-        <span class="c1"># Check if content type is JSON</span>
-        <span class="k">if</span> <span class="s1">&#39;json&#39;</span> <span class="ow">in</span> <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Type&#39;</span><span class="p">):</span>
-            <span class="k">try</span><span class="p">:</span>
-                <span class="n">result</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-            <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>  <span class="c1"># simplejson.decoder.JSONDecodeError</span>
-                <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Unable to decode JSON response from usermanager error.&quot;</span><span class="p">)</span>
-                <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                    <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Unable to decode JSON response from usermanager error.&quot;</span><span class="p">))</span>
-                <span class="k">return</span> <span class="kc">False</span>
-        <span class="k">else</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Server at&quot;</span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span><span class="p">,</span> <span class="s2">&quot;did not return a valid JSON document.&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Server at&quot;</span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span><span class="p">,</span> <span class="s2">&quot;did not return a valid JSON document.&quot;</span><span class="p">)</span>
-            <span class="k">return</span> <span class="kc">False</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to remove this endpoint from the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please try again later.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Unable to delete endpoint. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">)</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to remove this endpoint: </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Server error: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">)))</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Unable to delete endpoint. &quot;</span> <span class="o">+</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Endpoint with cfid &quot;</span> <span class="o">+</span> <span class="n">cfid</span> <span class="o">+</span> <span class="s2">&quot; was successfully deleted.&quot;</span><span class="p">)</span>
-
-    <span class="k">return</span> <span class="kc">True</span>
-
-
-<span class="k">def</span> <span class="nf">remove_credentials</span><span class="p">(</span><span class="n">_verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Remove your stored credentials.</span>
-
-<span class="sd">    Remove the .creds.json file that stores the username and password</span>
-<span class="sd">    of the current user.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        _verbose: Boolean indicator whether or not feedback should be printed. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True is user credentials are found and deleted. False otherwise (often because they were not found).</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-
-    <span class="c1"># actual function in _utils.py to prevent circular includes.</span>
-    <span class="n">removed</span> <span class="o">=</span> <span class="n">_remove_credentials</span><span class="p">()</span>
-    <span class="k">if</span> <span class="n">removed</span><span class="p">:</span>
-        <span class="k">if</span> <span class="n">_verbose</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Successfully removed your user credentials.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">True</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">if</span> <span class="n">_verbose</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;No user credentials found.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-
-<span class="k">def</span> <span class="nf">stop_print</span><span class="p">(</span><span class="n">_verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Stop ALL printing of user feedback from package.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        _verbose: Boolean indicator whether or not feedback should be printed. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">_verbose</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing user feedback set to &#39;False&#39;.&quot;</span><span class="p">)</span>
-    <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span> <span class="o">=</span> <span class="kc">True</span>
-    <span class="k">return</span> <span class="kc">True</span>
-
-
-<span class="k">def</span> <span class="nf">start_print</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;(re)start printing user feedback</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True</span>
-
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing user feedback set to &#39;True&#39;.&quot;</span><span class="p">)</span>
-    <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span> <span class="o">=</span> <span class="kc">False</span>
-    <span class="k">return</span> <span class="kc">True</span>
-
-
-<span class="k">def</span> <span class="nf">list_models</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Print or return a list of all supported models.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        A dictionary detailing the supported models</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SUPPORTED_MODELS</span><span class="p">:</span>
-        <span class="n">_load_supported_models</span><span class="p">()</span>
-
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Currently supported models:&quot;</span><span class="p">)</span>
-        <span class="nb">print</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">glob</span><span class="o">.</span><span class="n">SUPPORTED_MODELS</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">))</span>
-
-    <span class="k">return</span> <span class="n">glob</span><span class="o">.</span><span class="n">SUPPORTED_MODELS</span>
-
-
-<span class="k">def</span> <span class="nf">_set_toolchain_URL</span><span class="p">(</span><span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Change the location of the toolchain server.</span>
-
-<span class="sd">    This function is internal and should not be used by average users of the package. However,</span>
-<span class="sd">    it is useful for trouble-shooting the package either locally or on development servers.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        url: String specifying the location of the toolchain server.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        str: The toolchains url.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span> <span class="o">=</span> <span class="n">url</span>
-
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Toolchain url changed to: &quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span><span class="p">)</span>
-
-    <span class="k">return</span> <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span>
-
-
-<span class="k">def</span> <span class="nf">_set_usermanager_URL</span><span class="p">(</span><span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Change the location of the toolchain server</span>
-
-<span class="sd">    This function is internal and should not be used by average users of the package. However,</span>
-<span class="sd">    it is useful for trouble-shooting the package either locally or on development servers.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        url: String specifying the location of the toolchain server</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        The user-manager url</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">=</span> <span class="n">url</span>
-
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;User-manager (admin) url changed to: &quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span><span class="p">)</span>
-
-    <span class="k">return</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span>
-
-
-<span class="k">def</span> <span class="nf">_toggle_debug_mode</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Set debug to true or false.</span>
-
-<span class="sd">    Can be used for debugging purposes such that exceptions are raised (including the stack trace)</span>
-<span class="sd">    instead of suppressed.</span>
-
-<span class="sd">    Note: the debug status is always printed when executing this method.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        Boolean indicating the status of the DEBUG global.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-        <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="kc">False</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Debugging turned off.&quot;</span><span class="p">)</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span> <span class="o">=</span> <span class="kc">True</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Debugging turned on.&quot;</span><span class="p">)</span>
-
-    <span class="k">return</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span>
-
-
-<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
-    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;No command line options available for main.py.&quot;</span><span class="p">)</span>
-</pre></div>
-
-  </div>
-
-  </header>
-
-  <section id="section-items">
-
-    <h2 class="section-title" id="header-functions">Functions</h2>
-      
-  <div class="item">
-    <div class="name def" id="main.delete_endpoint">
-    <p>def <span class="ident">delete_endpoint</span>(</p><p>cfid)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Deletes an endpoint by cfid.</p>
-<p>Delete an endpoint owned by the currently logged in user by cfid.</p>
-<p>Args:
-    cfid: String of the compute function id.</p>
-<p>Returns:
-    True if successful, False otherwise.</p>
-<p>Raises  (in debug mode):
-    JWTError if unable to obtain JWT authorization
-    UserManagerError if unable to delete endpoints</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.delete_endpoint', this);">Show source &equiv;</a></p>
-  <div id="source-main.delete_endpoint" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">delete_endpoint</span><span class="p">(</span><span class="n">cfid</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Deletes an endpoint by cfid.</span>
-
-<span class="sd">    Delete an endpoint owned by the currently logged in user by cfid.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        cfid: String of the compute function id.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True if successful, False otherwise.</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        JWTError if unable to obtain JWT authorization</span>
-<span class="sd">        UserManagerError if unable to delete endpoints</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to renew your JWT lease. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;If this recurs use the remove_credentials() function to reset your login credentials.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">JWTError</span><span class="p">(</span><span class="s2">&quot;Unable to check JWT authorization. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">+</span> <span class="s2">&quot;/compute-function/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">+</span> <span class="n">cfid</span>
-    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-        <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-    <span class="p">}</span>
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;DELETE&quot;</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{})</span>
-        <span class="c1"># Check if content type is JSON</span>
-        <span class="k">if</span> <span class="s1">&#39;json&#39;</span> <span class="ow">in</span> <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Type&#39;</span><span class="p">):</span>
-            <span class="k">try</span><span class="p">:</span>
-                <span class="n">result</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-            <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>  <span class="c1"># simplejson.decoder.JSONDecodeError</span>
-                <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Unable to decode JSON response from usermanager error.&quot;</span><span class="p">)</span>
-                <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                    <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Unable to decode JSON response from usermanager error.&quot;</span><span class="p">))</span>
-                <span class="k">return</span> <span class="kc">False</span>
-        <span class="k">else</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Server at&quot;</span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span><span class="p">,</span> <span class="s2">&quot;did not return a valid JSON document.&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Server at&quot;</span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span><span class="p">,</span> <span class="s2">&quot;did not return a valid JSON document.&quot;</span><span class="p">)</span>
-            <span class="k">return</span> <span class="kc">False</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to remove this endpoint from the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please try again later.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Unable to delete endpoint. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">)</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to remove this endpoint: </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Server error: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">)))</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Unable to delete endpoint. &quot;</span> <span class="o">+</span> <span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;error&quot;</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Endpoint with cfid &quot;</span> <span class="o">+</span> <span class="n">cfid</span> <span class="o">+</span> <span class="s2">&quot; was successfully deleted.&quot;</span><span class="p">)</span>
-
-    <span class="k">return</span> <span class="kc">True</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.endpoints">
-    <p>def <span class="ident">endpoints</span>(</p><p>_verbose=True)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Return the endpoints available for the current user.</p>
-<p>Using the global JWT string this function returns a dict
-of the endpoints by the current user.</p>
-<p>Args:
-    _verbose: Bool indicating whether the endpoints should be printed. Default True.</p>
-<p>Returns:
-     endpoints: a list containing all the endpoints by the current user. [{},{},{}]</p>
-<p>Raises (in debug mode):
-    JWTError if unable to obtain JWT authorization
-    UserManagerError if unable to retrieve endpoint details</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.endpoints', this);">Show source &equiv;</a></p>
-  <div id="source-main.endpoints" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">endpoints</span><span class="p">(</span><span class="n">_verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Return the endpoints available for the current user.</span>
-
-<span class="sd">    Using the global JWT string this function returns a dict</span>
-<span class="sd">    of the endpoints by the current user.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        _verbose: Bool indicating whether the endpoints should be printed. Default True.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">         endpoints: a list containing all the endpoints by the current user. [{},{},{}]</span>
-
-<span class="sd">    Raises (in debug mode):</span>
-<span class="sd">        JWTError if unable to obtain JWT authorization</span>
-<span class="sd">        UserManagerError if unable to retrieve endpoint details</span>
-
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable to renew your JWT lease. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;If this recurs use the remove_credentials() function to reset your login credentials.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">JWTError</span><span class="p">(</span><span class="s2">&quot;Unable to check JWT authorization. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">+</span> <span class="s2">&quot;/compute-functions/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span>
-    <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-        <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-    <span class="p">}</span>
-
-    <span class="k">try</span><span class="p">:</span>
-        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{})</span>
-        <span class="n">result</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;We were unable retrieve your endpoints. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please try again later.&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UserManagerError</span><span class="p">(</span><span class="s2">&quot;Unable to retrieve endpoints. &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># print if requested:</span>
-    <span class="k">if</span> <span class="n">_verbose</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;You currently do not own any active endpoints.&quot;</span><span class="p">)</span>
-        <span class="k">else</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;You currently own the following endpoints:&quot;</span><span class="p">)</span>
-            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Name: </span><span class="si">{}</span><span class="s1">, cfid: </span><span class="si">{}</span><span class="s1">.&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">],</span> <span class="n">key</span><span class="p">[</span><span class="s1">&#39;cfid&#39;</span><span class="p">]))</span>
-
-    <span class="k">return</span> <span class="n">result</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.list_models">
-    <p>def <span class="ident">list_models</span>(</p><p>)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Print or return a list of all supported models.</p>
-<p>Returns:
-    A dictionary detailing the supported models</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.list_models', this);">Show source &equiv;</a></p>
-  <div id="source-main.list_models" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">list_models</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">dict</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Print or return a list of all supported models.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        A dictionary detailing the supported models</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SUPPORTED_MODELS</span><span class="p">:</span>
-        <span class="n">_load_supported_models</span><span class="p">()</span>
-
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Currently supported models:&quot;</span><span class="p">)</span>
-        <span class="nb">print</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">glob</span><span class="o">.</span><span class="n">SUPPORTED_MODELS</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">))</span>
-
-    <span class="k">return</span> <span class="n">glob</span><span class="o">.</span><span class="n">SUPPORTED_MODELS</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.remove_credentials">
-    <p>def <span class="ident">remove_credentials</span>(</p><p>_verbose=True)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Remove your stored credentials.</p>
-<p>Remove the .creds.json file that stores the username and password
-of the current user.</p>
-<p>Args:
-    _verbose: Boolean indicator whether or not feedback should be printed. Default False.</p>
-<p>Returns:
-    True is user credentials are found and deleted. False otherwise (often because they were not found).</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.remove_credentials', this);">Show source &equiv;</a></p>
-  <div id="source-main.remove_credentials" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">remove_credentials</span><span class="p">(</span><span class="n">_verbose</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Remove your stored credentials.</span>
-
-<span class="sd">    Remove the .creds.json file that stores the username and password</span>
-<span class="sd">    of the current user.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        _verbose: Boolean indicator whether or not feedback should be printed. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True is user credentials are found and deleted. False otherwise (often because they were not found).</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-
-    <span class="c1"># actual function in _utils.py to prevent circular includes.</span>
-    <span class="n">removed</span> <span class="o">=</span> <span class="n">_remove_credentials</span><span class="p">()</span>
-    <span class="k">if</span> <span class="n">removed</span><span class="p">:</span>
-        <span class="k">if</span> <span class="n">_verbose</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Successfully removed your user credentials.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">True</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">if</span> <span class="n">_verbose</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;No user credentials found.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.start_print">
-    <p>def <span class="ident">start_print</span>(</p><p>)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>(re)start printing user feedback</p>
-<p>Returns:
-    True</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.start_print', this);">Show source &equiv;</a></p>
-  <div id="source-main.start_print" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">start_print</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;(re)start printing user feedback</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True</span>
-
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing user feedback set to &#39;True&#39;.&quot;</span><span class="p">)</span>
-    <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span> <span class="o">=</span> <span class="kc">False</span>
-    <span class="k">return</span> <span class="kc">True</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.stop_print">
-    <p>def <span class="ident">stop_print</span>(</p><p>_verbose=False)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Stop ALL printing of user feedback from package.</p>
-<p>Args:
-    _verbose: Boolean indicator whether or not feedback should be printed. Default False.</p>
-<p>Returns:
-    True</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.stop_print', this);">Show source &equiv;</a></p>
-  <div id="source-main.stop_print" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">stop_print</span><span class="p">(</span><span class="n">_verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Stop ALL printing of user feedback from package.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        _verbose: Boolean indicator whether or not feedback should be printed. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        True</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">_verbose</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing user feedback set to &#39;False&#39;.&quot;</span><span class="p">)</span>
-    <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span> <span class="o">=</span> <span class="kc">True</span>
-    <span class="k">return</span> <span class="kc">True</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.update">
-    <p>def <span class="ident">update</span>(</p><p>mod, feature_vector, cfid, docs={}, email=True, _keep=False)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Updates an already existing model.</p>
-<p>The update function is similar to the upload function in most respects (so, see its docs),
-but instead of creating a new endpoint it overwrites the docs and model of an already exisitng
-endpoint. Thus, there is an additional argument "cfid" providing the computeFunction Id
-of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already
-existing endpoints.</p>
-<p>Note: If you solely want to change the documentation of an endpoint, you can either use the
-    update_docs() function or the online admin interface at https://admin.sclble.net.</p>
-<p>Args:
-    mod: The model to be uploaded.
-    feature_vector: An example feature_vector for your model.
-        (i.e., the first row of your training data X obtained using row = X[0,:])
-    cfid: a string with a valid computeFunction ID.
-    docs: A dict{} containing the fields 'name' and 'documentation'. Default {}.
-    email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-    _keep: Bool indicating whether the .gzipped file should be retained. Default False.</p>
-<p>Returns:
-    False if upload failed, true otherwise</p>
-<p>Raises  (in debug mode):
-    UploadModelError if unable to successfully bundle and upload the model.</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.update', this);">Show source &equiv;</a></p>
-  <div id="source-main.update" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">,</span> <span class="n">cfid</span><span class="p">,</span> <span class="n">docs</span><span class="o">=</span><span class="p">{},</span> <span class="n">email</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">_keep</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Updates an already existing model.</span>
-
-<span class="sd">    The update function is similar to the upload function in most respects (so, see its docs),</span>
-<span class="sd">    but instead of creating a new endpoint it overwrites the docs and model of an already exisitng</span>
-<span class="sd">    endpoint. Thus, there is an additional argument &quot;cfid&quot; providing the computeFunction Id</span>
-<span class="sd">    of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already</span>
-<span class="sd">    existing endpoints.</span>
-
-<span class="sd">    Note: If you solely want to change the documentation of an endpoint, you can either use the</span>
-<span class="sd">        update_docs() function or the online admin interface at https://admin.sclble.net.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        mod: The model to be uploaded.</span>
-<span class="sd">        feature_vector: An example feature_vector for your model.</span>
-<span class="sd">            (i.e., the first row of your training data X obtained using row = X[0,:])</span>
-<span class="sd">        cfid: a string with a valid computeFunction ID.</span>
-<span class="sd">        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;. Default {}.</span>
-<span class="sd">        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.</span>
-<span class="sd">        _keep: Bool indicating whether the .gzipped file should be retained. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        False if upload failed, true otherwise</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        UploadModelError if unable to successfully bundle and upload the model.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="n">bundle</span> <span class="o">=</span> <span class="p">{}</span>
-
-    <span class="c1"># Check model:</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_check_model</span><span class="p">(</span><span class="n">mod</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: The model you are trying to upload is not (yet) supported or has not been fitted. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please see README.md for a list of supported models. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your models has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;The submitted model is not supported.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;fitted_model&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">mod</span>
-
-    <span class="c1"># check input vector and generate an example:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="k">if</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">any</span><span class="p">():</span>
-        <span class="c1"># try prediction</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">output</span> <span class="o">=</span> <span class="n">_predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">)</span>  <span class="c1"># predict raises error if unable to generate predcition</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to create an example inference. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;Unable to generate prediction: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-        <span class="c1"># format data:</span>
-        <span class="n">input_str</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s1">&#39;[[</span><span class="si">%s</span><span class="s1">]]&#39;</span> <span class="o">%</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">tolist</span><span class="p">()])</span>
-        <span class="n">example</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;input&#39;</span><span class="p">:</span> <span class="n">input_str</span><span class="p">,</span> <span class="s2">&quot;output&quot;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">output</span><span class="p">)}</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">example</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: You did not provide a required example instance. (see docs). </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># check the docs:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="n">docs_update</span> <span class="o">=</span> <span class="kc">True</span>
-    <span class="k">if</span> <span class="n">docs</span><span class="p">:</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">docs</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="n">docs_update</span> <span class="o">=</span> <span class="kc">False</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;WARNING: You did not provide any documentation. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;We will only update the .wasm model, not the documentation.&quot;</span><span class="p">)</span>
-
-    <span class="c1"># check authorization:</span>
-    <span class="n">auth</span> <span class="o">=</span> <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">auth</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to obtain JWT authorization for your account. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># get system information</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;system_info&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_get_system_info</span><span class="p">()</span>
-
-    <span class="c1"># gzip the bundle</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_gzip_save</span><span class="p">(</span><span class="n">bundle</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to gzip your model bundle. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to save the bundle.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># all ok, upload:</span>
-    <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
-
-        <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span> <span class="o">+</span> <span class="s2">&quot;/upload/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">+</span> <span class="n">cfid</span>
-        <span class="nb">print</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
-
-        <span class="c1"># Map python package to the right toolchain:</span>
-        <span class="n">pkg_name</span> <span class="o">=</span> <span class="n">_get_model_package</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
-        <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
-        <span class="k">if</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;sklearn&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;statsmodels&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;xgboost&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;lightgbm&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-
-        <span class="c1"># Setup the actual request</span>
-        <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;email&#39;</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span>
-            <span class="s1">&#39;package&#39;</span><span class="p">:</span> <span class="n">__version__</span><span class="p">,</span>
-            <span class="s1">&#39;toolchain&#39;</span><span class="p">:</span> <span class="n">toolchain_name</span><span class="p">,</span>
-            <span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;docs&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;documentation&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;updateDocs&#39;</span><span class="p">:</span> <span class="n">docs_update</span><span class="p">,</span>
-            <span class="s1">&#39;exampleInput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;input&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;exampleOutput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;output&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">)</span>
-        <span class="p">}</span>
-        <span class="n">payload</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;data&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-        <span class="p">}</span>
-
-        <span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-
-        <span class="n">files</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;bundle&#39;</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="n">glob</span><span class="o">.</span><span class="n">GZIP_BUNDLE</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">))]</span>
-        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-        <span class="p">}</span>
-
-        <span class="c1"># Do the request (and make sure to delete the gzip if errors occur)</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Unable to carry out the upload request: the toolchain is not available. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="c1"># Error handling</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We did not receive a valid JSON response from the toolchain-server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: An error was returned by the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">])</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;The following content has been send to the toolchain server:&quot;</span><span class="p">)</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">bundle</span><span class="p">)</span>
-
-        <span class="c1"># user feedback:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Your model was successfully submitted for an update. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-
-        <span class="c1"># remove bundle:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-            <span class="n">_gzip_delete</span><span class="p">()</span>
-
-        <span class="k">return</span> <span class="kc">True</span>
-
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">return</span> <span class="kc">False</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.update_docs">
-    <p>def <span class="ident">update_docs</span>(</p><p>cfid, docs)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Updates the documentation of an already existing model</p>
-<p>The update_docs function can be used to upload the documentation of an already existing model
-by simply providing the cfid and the new docs object.</p>
-<p>Args:
-    cfid: a string with a valid computeFunction ID.
-    docs: A dict{} containing the fields 'name' and 'documentation'</p>
-<p>Returns:
-    False if upload failed, true otherwise</p>
-<p>Raises  (in debug mode):
-    UploadModelError if unable to successfully bundle and upload the model.</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.update_docs', this);">Show source &equiv;</a></p>
-  <div id="source-main.update_docs" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">update_docs</span><span class="p">(</span><span class="n">cfid</span><span class="p">,</span> <span class="n">docs</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Updates the documentation of an already existing model</span>
-
-<span class="sd">    The update_docs function can be used to upload the documentation of an already existing model</span>
-<span class="sd">    by simply providing the cfid and the new docs object.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        cfid: a string with a valid computeFunction ID.</span>
-<span class="sd">        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        False if upload failed, true otherwise</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        UploadModelError if unable to successfully bundle and upload the model.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-
-    <span class="c1"># check the docs:</span>
-    <span class="n">name</span> <span class="o">=</span> <span class="n">docs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
-    <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Please make sure to add a name to your documentation (using the &#39;name&#39;) field </span><span class="se">\n</span><span class="s2">&quot;</span>
-              <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-    <span class="n">documentation</span> <span class="o">=</span> <span class="n">docs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;documentation&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
-    <span class="k">if</span> <span class="n">documentation</span> <span class="o">==</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
-        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Please make sure to your documentation (using the &#39;documentation&#39; field) </span><span class="se">\n</span><span class="s2">&quot;</span>
-              <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># check authorization:</span>
-    <span class="n">auth</span> <span class="o">=</span> <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">auth</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to obtain JWT authorization for your account. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># all ok, upload:</span>
-    <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
-
-        <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">USER_MANAGER_URL</span> <span class="o">+</span> <span class="s2">&quot;/compute-function/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span> <span class="o">+</span> <span class="n">cfid</span>
-
-        <span class="c1"># Setup the actual request</span>
-        <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s2">&quot;language&quot;</span><span class="p">:</span> <span class="s2">&quot;WASM&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;public&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
-            <span class="s2">&quot;profit&quot;</span><span class="p">:</span> <span class="mf">0.1</span><span class="p">,</span>
-            <span class="s2">&quot;cycles&quot;</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span>
-            <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
-            <span class="s2">&quot;docs&quot;</span><span class="p">:</span> <span class="n">documentation</span>
-        <span class="p">}</span>
-        <span class="n">payload</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;data&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-        <span class="p">}</span>
-
-        <span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
-        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-        <span class="p">}</span>
-
-        <span class="c1"># Do the request (and make sure to delete the gzip if errors occur)</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Unable to carry out the upload request: the toolchain is not available. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="c1"># Error handling</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We did not receive a valid JSON response from the toolchain-server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: An error was returned by the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model documentation has not been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">])</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;The documentation for &quot;</span> <span class="o">+</span> <span class="n">cfid</span> <span class="o">+</span> <span class="s2">&quot; has been updated using:&quot;</span><span class="p">)</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-
-        <span class="c1"># user feedback:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Your model documentation has been updated. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">True</span>
-
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">return</span> <span class="kc">False</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-      
-  <div class="item">
-    <div class="name def" id="main.upload">
-    <p>def <span class="ident">upload</span>(</p><p>mod, feature_vector, docs={}, email=True, _keep=False)</p>
-    </div>
-    
-
-    
-  
-    <div class="desc"><p>Uploads a fitted model to Scailable.</p>
-<p>The upload function is the main workhorse of the sclblpy package.
-The function first checks whether the supplied model is ok (part of the list and fitted).</p>
-<p>Next, it checks whether an example row is provided and if so it creates the example
-input and output .json objects.</p>
-<p>Next, the docs are checked; if none are provided a warning is issued and a simple
-name is provided based on the model type.</p>
-<p>Subsequently, we package the whole thing, including details of the user system, into a
-gzipped file that is stored on disc.</p>
-<p>Finally the whole package is uploaded to the toolchain.</p>
-<p>Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
-    stop_print() method.</p>
-<p>Args:
-    mod: The model to be uploaded.
-    feature_vector: An example feature_vector for your model.
-        (i.e., the first row of your training data X obtained using row = X[0,:])
-    docs: A dict{} containing the fields 'name' and 'documentation'
-    email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-    _keep: Bool indicating whether the .gzipped file should be retained. Default False.</p>
-<p>Returns:
-    False if upload failed, true otherwise</p>
-<p>Raises  (in debug mode):
-    UploadModelError if unable to successfully bundle and upload the model.</p></div>
-  <div class="source_cont">
-  <p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-main.upload', this);">Show source &equiv;</a></p>
-  <div id="source-main.upload" class="source">
-    <div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">upload</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">,</span> <span class="n">docs</span><span class="o">=</span><span class="p">{},</span> <span class="n">email</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">_keep</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
-    <span class="sd">&quot;&quot;&quot;Uploads a fitted model to Scailable.</span>
-
-<span class="sd">    The upload function is the main workhorse of the sclblpy package.</span>
-<span class="sd">    The function first checks whether the supplied model is ok (part of the list and fitted).</span>
-
-<span class="sd">    Next, it checks whether an example row is provided and if so it creates the example</span>
-<span class="sd">    input and output .json objects.</span>
-
-<span class="sd">    Next, the docs are checked; if none are provided a warning is issued and a simple</span>
-<span class="sd">    name is provided based on the model type.</span>
-
-<span class="sd">    Subsequently, we package the whole thing, including details of the user system, into a</span>
-<span class="sd">    gzipped file that is stored on disc.</span>
-
-<span class="sd">    Finally the whole package is uploaded to the toolchain.</span>
-
-<span class="sd">    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the</span>
-<span class="sd">        stop_print() method.</span>
-
-<span class="sd">    Args:</span>
-<span class="sd">        mod: The model to be uploaded.</span>
-<span class="sd">        feature_vector: An example feature_vector for your model.</span>
-<span class="sd">            (i.e., the first row of your training data X obtained using row = X[0,:])</span>
-<span class="sd">        docs: A dict{} containing the fields &#39;name&#39; and &#39;documentation&#39;</span>
-<span class="sd">        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.</span>
-<span class="sd">        _keep: Bool indicating whether the .gzipped file should be retained. Default False.</span>
-
-<span class="sd">    Returns:</span>
-<span class="sd">        False if upload failed, true otherwise</span>
-
-<span class="sd">    Raises  (in debug mode):</span>
-<span class="sd">        UploadModelError if unable to successfully bundle and upload the model.</span>
-<span class="sd">    &quot;&quot;&quot;</span>
-    <span class="n">bundle</span> <span class="o">=</span> <span class="p">{}</span>
-
-    <span class="c1"># Check model:</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_check_model</span><span class="p">(</span><span class="n">mod</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: The model you are trying to upload is not (yet) supported or has not been fitted. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Please see README.md for a list of supported models. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your models has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;The uploaded model is not supported.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;fitted_model&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">mod</span>
-
-    <span class="c1"># check input vector and generate an example:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="k">if</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">any</span><span class="p">():</span>
-        <span class="c1"># try prediction</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">output</span> <span class="o">=</span> <span class="n">_predict</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span> <span class="n">feature_vector</span><span class="p">)</span>  <span class="c1"># predict raises error if unable to generate predcition</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to create an example inference. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;Unable to generate prediction: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-        <span class="c1"># format data:</span>
-        <span class="n">input_str</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s1">&#39;[[</span><span class="si">%s</span><span class="s1">]]&#39;</span> <span class="o">%</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">feature_vector</span><span class="o">.</span><span class="n">tolist</span><span class="p">()])</span>
-        <span class="n">example</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;input&#39;</span><span class="p">:</span> <span class="n">input_str</span><span class="p">,</span> <span class="s2">&quot;output&quot;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">output</span><span class="p">)}</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">example</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: You did not provide a required example instance. (see docs). </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># check the docs:</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
-    <span class="k">if</span> <span class="n">docs</span><span class="p">:</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">docs</span>
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">try</span><span class="p">:</span>  <span class="c1"># This should work, but catching the exception just in case:</span>
-            <span class="n">name</span> <span class="o">=</span> <span class="n">_get_model_name</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
-            <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;NAMELESS MODEL&quot;</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">][</span><span class="s1">&#39;name&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">name</span>
-        <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">][</span><span class="s1">&#39;documentation&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;-- EMPTY --&quot;</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;WARNING: You did not provide any documentation. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;We will simply use &quot;</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">&quot; as its name without further documentation.&quot;</span><span class="p">)</span>
-
-    <span class="c1"># check authorization:</span>
-    <span class="n">auth</span> <span class="o">=</span> <span class="n">_check_jwt</span><span class="p">()</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">auth</span><span class="p">:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to obtain JWT authorization for your account. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># get system information</span>
-    <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;system_info&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">_get_system_info</span><span class="p">()</span>
-
-    <span class="c1"># gzip the bundle</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">_gzip_save</span><span class="p">(</span><span class="n">bundle</span><span class="p">):</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We were unable to gzip your model bundle. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                  <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to save the bundle.&quot;</span><span class="p">)</span>
-        <span class="k">return</span> <span class="kc">False</span>
-
-    <span class="c1"># all ok, upload:</span>
-    <span class="k">if</span> <span class="n">auth</span><span class="p">:</span>
-
-        <span class="n">url</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">TOOLCHAIN_URL</span> <span class="o">+</span> <span class="s2">&quot;/upload/&quot;</span> <span class="o">+</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_USER_ID</span>
-
-        <span class="c1"># Map python package to the right toolchain:</span>
-        <span class="n">pkg_name</span> <span class="o">=</span> <span class="n">_get_model_package</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
-        <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
-        <span class="k">if</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;sklearn&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;statsmodels&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;xgboost&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-        <span class="k">elif</span> <span class="n">pkg_name</span> <span class="o">==</span> <span class="s2">&quot;lightgbm&quot;</span><span class="p">:</span>
-            <span class="n">toolchain_name</span> <span class="o">=</span> <span class="s2">&quot;sklearn&quot;</span>
-
-        <span class="c1"># Setup the actual request</span>
-        <span class="n">data</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;email&#39;</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span>
-            <span class="s1">&#39;package&#39;</span><span class="p">:</span> <span class="n">__version__</span><span class="p">,</span>
-            <span class="s1">&#39;toolchain&#39;</span><span class="p">:</span> <span class="n">toolchain_name</span><span class="p">,</span>
-            <span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s2">&quot;No name found.&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;docs&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;docs&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;documentation&#39;</span><span class="p">,</span> <span class="s2">&quot;No docs provided.&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;exampleInput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;input&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">),</span>
-            <span class="s1">&#39;exampleOutput&#39;</span><span class="p">:</span> <span class="n">bundle</span><span class="p">[</span><span class="s1">&#39;example&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;output&#39;</span><span class="p">,</span> <span class="s2">&quot;[]&quot;</span><span class="p">)</span>
-        <span class="p">}</span>
-        <span class="n">payload</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;data&#39;</span><span class="p">:</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
-        <span class="p">}</span>
-
-        <span class="n">files</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;bundle&#39;</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="n">glob</span><span class="o">.</span><span class="n">GZIP_BUNDLE</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">))]</span>
-        <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
-            <span class="s1">&#39;Authorization&#39;</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">JWT_TOKEN</span>
-        <span class="p">}</span>
-
-        <span class="c1"># Do the request (and make sure to delete the gzip if errors occur)</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: Unable to carry out the upload request: the toolchain is not available. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We were unable to obtain JWT authorization: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="c1"># Error handling</span>
-        <span class="k">try</span><span class="p">:</span>
-            <span class="n">response_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
-        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: We did not receive a valid JSON response from the toolchain-server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">]:</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-                <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;FATAL: An error was returned by the server. </span><span class="se">\n</span><span class="s2">&quot;</span>
-                      <span class="s2">&quot;Your model has not been uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-            <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-                <span class="n">_gzip_delete</span><span class="p">()</span>
-            <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-                <span class="k">raise</span> <span class="n">UploadModelError</span><span class="p">(</span><span class="s2">&quot;We did not receive a valid response from the server: &quot;</span> <span class="o">+</span> <span class="n">response_data</span><span class="p">[</span><span class="s1">&#39;error&#39;</span><span class="p">])</span>
-            <span class="k">return</span> <span class="kc">False</span>
-
-        <span class="k">if</span> <span class="n">glob</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;The following content has been send to the toolchain server:&quot;</span><span class="p">)</span>
-            <span class="nb">print</span><span class="p">(</span><span class="n">bundle</span><span class="p">)</span>
-
-        <span class="c1"># user feedback:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">glob</span><span class="o">.</span><span class="n">SILENT</span><span class="p">:</span>
-            <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Your model was successfully uploaded. </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
-
-        <span class="c1"># remove bundle:</span>
-        <span class="k">if</span> <span class="ow">not</span> <span class="n">_keep</span><span class="p">:</span>
-            <span class="n">_gzip_delete</span><span class="p">()</span>
-
-        <span class="k">return</span> <span class="kc">True</span>
-
-    <span class="k">else</span><span class="p">:</span>
-        <span class="k">return</span> <span class="kc">False</span>
-</pre></div>
-
-  </div>
-</div>
-
-  </div>
-  
-
-
-  </section>
-
-    </article>
-  <div class="clear"> </div>
-  <footer id="footer">
-    <p>
-      Documentation generated by
-      <a href="https://github.com/BurntSushi/pdoc">pdoc 0.3.2</a>
-    </p>
-
-    <p>pdoc is in the public domain with the
-      <a href="http://unlicense.org">UNLICENSE</a></p>
-
-    <p>Design by <a href="http://nadh.in">Kailash Nadh</a></p>
-  </footer>
-</div>
-</body>
-</html>
diff --git a/sclblpy/__init__.py b/sclblpy/__init__.py
index 45418bf..e8675e0 100644
--- a/sclblpy/__init__.py
+++ b/sclblpy/__init__.py
@@ -9,10 +9,10 @@
     sys.exit(1)
 
 from .main import welcome, \
-    upload, upload_sklearn, upload_onnx, update, update_sklearn, update_onnx, update_docs, \
+    upload_onnx, update_onnx, update_docs, \
     endpoints, delete_endpoint, models, delete_model, \
     devices, delete_device, assignments, assign, delete_assignment, \
-    run, remove_credentials, list_models, \
+    remove_credentials, \
     stop_print, start_print, \
     _set_toolchain_URL, _set_usermanager_URL, _set_taskmanager_URL
 from .version import __version__
diff --git a/sclblpy/_globals.py b/sclblpy/_globals.py
index e15fe3f..8bea03e 100644
--- a/sclblpy/_globals.py
+++ b/sclblpy/_globals.py
@@ -3,9 +3,9 @@
 from sclblpy.appdirs import AppDirs
 
 # servers:
-USER_MANAGER_URL: str = "https://usermanager.sclbl.net:8008"  # Location of the user manager.
-TOOLCHAIN_URL: str = "https://toolchain.sclbl.net:8010"  # Location of the toolchain server.
-TASK_MANAGER_URL: str = "https://taskmanager.sclbl.net:8080"  # Location of the taskmanager.
+USER_MANAGER_URL: str = "https://usermanager.sclbl.net"  # Location of the user manager.
+TOOLCHAIN_URL: str = "https://toolchain.sclbl.net"  # Location of the toolchain server.
+TASK_MANAGER_URL: str = "https://taskmanager.sclbl.net"  # Location of the taskmanager.
 
 # control printing:
 SILENT: bool = False  # Boolean indicating whether user feedback should be suppressed.
@@ -15,7 +15,6 @@
 dirs = AppDirs("sclblpy", "sclbl")
 USER_CREDENTIALS: str = dirs.user_config_dir + "/.creds.json"  # Location of json file to store user credentials
 GZIP_BUNDLE: str = dirs.user_data_dir + "/model_bundle.gzip"  # Location where a save model is (temporarily) stored
-MODELS_JSON: str = os.path.dirname(os.path.realpath(__file__)) + "/supported_models.json"  # Location of the json with supported models
 
 # JWT necessities:
 JWT_TOKEN: str = ""  # JWT token.
diff --git a/sclblpy/_jwt.py b/sclblpy/_jwt.py
index ebf7b0f..84064ac 100644
--- a/sclblpy/_jwt.py
+++ b/sclblpy/_jwt.py
@@ -20,8 +20,8 @@ def _check_jwt(seconds_refresh=120, seconds_renew=280) -> bool:
 
     Note, if no JWT string is present, or the JWT string has expired,
     the function tries to
-    a. Read username and pass from file
-    b. Prompt user for username and pass
+    a. Read email and pass from file
+    b. Prompt user for email and pass
     and subsequently sign in.
 
     Args:
@@ -41,7 +41,7 @@ def _check_jwt(seconds_refresh=120, seconds_renew=280) -> bool:
     if not glob.JWT_TOKEN or glob.JWT_TIMESTAMP < time_renew:
         user_details: dict = _get_user_details()
         try:
-            if _sign_in(user_details['username'], user_details['password']):
+            if _sign_in(user_details['email'], user_details['password']):
                 return True
             else:
                 return False
@@ -73,15 +73,15 @@ def _check_jwt(seconds_refresh=120, seconds_renew=280) -> bool:
         return False
 
 
-def _sign_in(username: str, password: str, _remove_file=True) -> bool:
+def _sign_in(email: str, password: str, _remove_file=True) -> bool:
     """Performs the sign in of a user.
 
     The function sign in performs a sign in of a user based
-    on the username (str) and password (str). It returns
+    on the email (str) and password (str). It returns
     a boolean value indicating whether the sign in was successful.
 
     Args:
-        username: A string (email) to login the user
+        email: A string (email) to login the user
         password: A string (password for login
         _remove_file: A bool indicating if the credentials should be removed on failed login. Default True.
 
@@ -91,16 +91,16 @@ def _sign_in(username: str, password: str, _remove_file=True) -> bool:
     Raises:
         LoginError: if unable to login.
     """
-    if len(username) < 1 or len(password) < 1:
+    if len(email) < 1 or len(password) < 1:
         if not glob.SILENT:
-            print("JWT error: no username and password provided.")
+            print("JWT error: no email and password provided.")
         if glob.DEBUG:
-            raise LoginError("No username or password provided.")
+            raise LoginError("No email or password provided.")
         return False
 
     url: str = glob.USER_MANAGER_URL + "/user/signin/"
     data: dict = {
-        'email': username,
+        'email': email,
         'pwd': password
     }
     headers: dict = {
@@ -161,11 +161,11 @@ def _sign_in(username: str, password: str, _remove_file=True) -> bool:
 
 
 def _get_user_details() -> dict:
-    """Gets the username and password from a user.
+    """Gets the email and password from a user.
 
     Function tries to
-    a. Retrieve username and password from .creds.json file.
-    b. Retrieve username and password by prompting the user.
+    a. Retrieve email and password from .creds.json file.
+    b. Retrieve email and password by prompting the user.
 
     If user responds 'y' to prompt to save the function we will store the user credentials.
 
@@ -173,7 +173,7 @@ def _get_user_details() -> dict:
 
     Returns:
         A dict containing the fields
-            'username' String
+            'email' String
             'password' String
 
     Raises (in debug mode):
@@ -188,12 +188,12 @@ def _get_user_details() -> dict:
     except FileNotFoundError:
         pass
 
-    username: str = input("Please provide your username: ")
+    email: str = input("Please provide your email: ")
     with warnings.catch_warnings():
         warnings.simplefilter('ignore', GetPassWarning)
         password = getpass('Please type your password: ')
 
-    details['username'] = username
+    details['email'] = email
     details['password'] = password
 
     while True:
@@ -305,7 +305,7 @@ def _remove_credentials():
             return False
         if not glob.SILENT:
             print("Your stored user credentials have been removed. \n"
-                  "You will have to re-enter your username and password next time.")
+                  "You will have to re-enter your email and password next time.")
 
         return True
     else:
diff --git a/sclblpy/_utils.py b/sclblpy/_utils.py
index fc9d0f3..939c8ea 100644
--- a/sclblpy/_utils.py
+++ b/sclblpy/_utils.py
@@ -4,244 +4,6 @@
 import socket
 import sys
 import uuid
-import inspect
-import json
-
-from sklearn.utils.validation import check_is_fitted
-from sklearn.exceptions import NotFittedError
-
-from sclblpy.errors import ModelSupportError, GeneratePredictionError
-import sclblpy._globals as glob
-
-
-def _check_model(obj) -> bool:
-    """Checks whether a model can be uploaded to Scailable.
-
-    Checks whether the model is both supported (i.e., in the supported models list)
-    and fitted. Effectively a wrapper around _model_supported() and _model_is_fitted().
-
-    Args:
-        obj: a fitted model
-
-    Returns:
-        True if passes all checks
-    """
-    if _model_supported(obj):
-        if _model_is_fitted(obj):
-            return True
-        else:
-            return False
-    else:
-        return False
-
-
-def _model_supported(obj) -> bool:
-    """Checks whether the supplied model is supported.
-
-    Checks whether a supplied model is present in the list of supported models (supported_models.json).
-
-    Args:
-        obj: The fitted model.
-
-    Returns:
-        True if it passes all checks.
-
-    Raises (in debug mode):
-        ModelSupportError.
-    """
-    # Check if supported models are loaded:
-    if not glob.SUPPORTED_MODELS:
-        if not _load_supported_models():
-            if glob.DEBUG:
-                raise ModelSupportError("Model check error: unable to load supported models.")
-            return False
-
-    try:
-        model_base: str = _get_model_package(obj)  # This returns a string OR raises an error
-        # statsmodels hack for dealing with the RegressionResultsWrapper:
-        if model_base == "statsmodels":
-            model_name: str = _get_model_name(obj.model)
-        else:
-            model_name: str = _get_model_name(obj)
-    except Exception as e:
-        if not glob.SILENT:
-            print("Model check error: Unable to retrieve model and package name.")
-        if glob.DEBUG:
-            raise ModelSupportError("Model check error: Unable to retrieve model and package name: " + str(e))
-        return False
-
-    if (model_base in glob.SUPPORTED_MODELS and
-            model_name in glob.SUPPORTED_MODELS[model_base]):
-        return True
-    else:
-        return False
-
-
-def _get_model_package(obj) -> str:
-    """Gets the package name of a model object.
-
-    Args:
-        obj: a fitted model object
-
-    Returns:
-        base: string denoting the name of the package (e.g., sklearn)
-
-    Raises (in debug mode):
-        ModelSupportError.
-    """
-    mod = inspect.getmodule(obj)
-    try:
-        base, _sep, _stem = mod.__name__.partition('.')
-    except Exception as e:
-        raise ModelSupportError("Model check error: Unable to retrieve package name: " + str(e))
-
-    return base
-
-
-def _get_model_name(obj) -> str:
-    """Get the name of a model.
-
-    Function retrieves the name of a model from a fitted model
-    by accessing the __name__ property.
-
-    Args:
-        obj: A model to be checked.
-
-    Returns:
-        name: String containing the name.
-
-    Raises (in debug mode):
-        ModelSupportError.
-    """
-
-    try:
-        name = type(obj).__name__
-    except Exception as e:
-        raise ModelSupportError("Model check error: Unable to retrieve model name: " + str(e))
-
-    return name
-
-
-def _load_supported_models() -> bool:
-    """Loads the supported model list.
-
-    Function opens and parses the file supported_models.json in the current
-    package folder to check the supported models.
-
-    Note: the supported models are loaded into the glob.SUPPORTED_MODELS
-    dictionary to make them available to the whole package.
-
-    Args:
-
-    Returns:
-        True if the supported models are loaded into the global SUPPORTED_MODELS, False otherwise.
-
-    Raises (in debug mode):
-        ModelSupportError.
-    """
-    try:
-        with open(glob.MODELS_JSON, "r") as f:
-            glob.SUPPORTED_MODELS = json.load(f)
-    except FileNotFoundError:
-        if not glob.SILENT:
-            print("Model check error: Unable to find list of supported models.")
-        if glob.DEBUG:
-            raise ModelSupportError("Model check error: Unable to find list of supported models.")
-        return False
-
-    return True
-
-
-def _model_is_fitted(obj) -> bool:
-    """Checks if a model is fitted.
-
-    Function aims to see if a passed model object has been fitted already. If not
-    it returns False.
-
-    Args:
-        obj: a model to be checked.
-
-    Returns:
-        Boolean indicating whether the model is fitted yes / no
-
-    Raises:
-    """
-    if hasattr(obj, '_is_fitted'):
-        return obj._is_fitted()
-
-    # statsmodels:
-    if hasattr(obj, 'fittedvalues'):
-        return True
-
-    # XGboost exception
-    if _get_model_package(obj) == "xgboost":
-        try:
-            obj.feature_importances_
-            return True
-        except Exception as e:  # general exception to not include xgboost
-            return False
-
-    # lightgbm exceptoin
-    if _get_model_package(obj) == "lightgbm":
-        try:
-            obj.n_features_
-            return True
-        except Exception as e:  # of not possible, not fitted
-            return False
-
-    try:
-        check_is_fitted(obj)
-        return True
-    except NotFittedError:
-        return False
-
-
-def _predict(mod, feature_vector):
-    """Generates predictions.
-
-    Function to generate predictions and have the ability to
-    deal with different model classes.
-
-    Args:
-        mod: A saved model instance
-        feature_vector: A single row used for prediction (subset of dataset)
-
-    Returns:
-        A prediction (as list)
-
-    Raises (in debug mode):
-        GeneratePredictionError if unable to generate prediction.
-    """
-    package = _get_model_package(mod)
-    if package == "sklearn":
-        try:
-            result = mod.predict(feature_vector.reshape(1, -1))
-            return result.tolist()
-        except Exception as e:
-            raise GeneratePredictionError("Model check error: Unable generate sklearn prediction: " + str(e))
-
-    elif package == "statsmodels":
-        try:
-            result = mod.predict(feature_vector.reshape(1, -1))
-            return result.tolist()
-        except Exception as e:
-            raise GeneratePredictionError("Model check error: Unable generate statsmodels prediction: " + str(e))
-
-    elif package == "xgboost":
-        try:
-            result = mod.predict(feature_vector.reshape(1, -1))
-            return result.tolist()
-        except Exception as e:
-            raise GeneratePredictionError("Model check error: Unable generate xgboost prediction: " + str(e))
-
-    else:  # whatever else:
-        try:
-            result = mod.predict(feature_vector.reshape(1, -1))
-            return result.tolist()
-        except Exception as e:
-            raise GeneratePredictionError("Model check error: Unable generate xgboost prediction: " + str(e))
-
-    raise GeneratePredictionError("Model check error: Predictions for your model are not supported.")
 
 
 def _get_system_info(_verbose=False):
diff --git a/sclblpy/main.py b/sclblpy/main.py
index 2fcf2cb..5f712a8 100644
--- a/sclblpy/main.py
+++ b/sclblpy/main.py
@@ -5,8 +5,7 @@
 import sclblpy._globals as glob
 from sclblpy._bundle import _gzip_save, _gzip_delete
 from sclblpy._jwt import _check_jwt, _remove_credentials
-from sclblpy._utils import _get_model_name, _get_system_info, _predict, _get_model_package, _load_supported_models, \
-    _check_model
+from sclblpy._utils import  _get_system_info
 from sclblpy.errors import UserManagerError, JWTError, UploadModelError, RunTaskError, CreateAssignmentError
 from sclblpy.version import __version__
 
@@ -21,74 +20,6 @@ def welcome():
     print("Check the docs at https://pypi.org/project/sclblpy/ for more info. \n")
 
 
-# upload is a wrapper for upload_onnx and upload_sklearn to provide backwards compatibility:
-def upload(mod, features, docs={}, email=True, model_type="sklearn", _keep=False) -> bool:
-    """upload uploads a trained AI/ML model to Scailable.
-
-    The upload function is the main workhorse of the sclblpy package but effectively provides a
-    wrapper to choose between the
-     - upload_sklearn(mod, feature_vector, docs={}, email=True, _keep=False)
-     - upload_onnx(path, docs={}, email=True)
-    functions.
-
-    The function checks the type, and if type = "sklearn" (default) calls the upload_sklearn() function.
-    If type = "onnx" it calls the upload_onnx() function.
-
-    Behavior:
-    If type = "onnx"
-        - The function first checks if the supplied path indeed references a .onnx file
-        - Next, the docs are checked; if none are provided a warning is issued and a simple
-        name is provided based on the model type.
-        - Finally the onnx file and the supporting docs are uploaded to the toolchain.
-
-    If type = "sklearn"
-        - The function first checks whether the supplied model is ok (part of the list and fitted).
-        - Next, it checks whether an example row is provided and if so it creates the example
-        input and output .json objects.
-        - Next, the docs are checked; if none are provided a warning is issued and a simple
-        name is provided based on the model type.
-        - Subsequently, we package the whole thing, including details of the user system, into a
-        gzipped file that is stored on disc.
-        - Finally the whole package is uploaded to the toolchain.
-
-    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
-        stop_print() method.
-
-    Args:
-        mod: The model to be uploaded (type="sklearn" OR the path to the stored ONNX file (type="onnx").
-        features:
-            - An example feature_vector for your model (type="sklearn" only).
-            (i.e., the first row of your training data X obtained using row = X[0,:])
-            - The input str (binary) to the onnx model (type="onnx" only). Can be an empty string.
-        docs: A dict{} containing the fields 'name' and 'documentation'.
-        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-        model_type: String indicating the type of model. Currently with options "sklearn" or "onnx". Default "sklearn"
-        _keep: Bool indicating whether the .gzipped file should be retained (type="sklearn" only). Default False.
-
-    Returns:
-        False if upload failed, true otherwise
-
-    Raises  (in debug mode):
-        UploadModelError if unable to successfully bundle and upload the model.
-    """
-    if model_type == "sklearn":
-        if features == "":
-            if not glob.SILENT:
-                print("FATAL: You cannot upload a sklearn model with an empty string as feature vector.")
-            if glob.DEBUG:
-                raise UploadModelError("Cannot upload sklearn model with empty string as feature vector.")
-            return False
-        if not upload_sklearn(mod, features, docs, email, _keep):
-            return False
-    elif model_type == "onnx":
-        if not upload_onnx(mod, features, docs, email):
-            return False
-    else:
-        if glob.DEBUG:
-            raise UploadModelError("Please specify a valid model type.")
-        return False
-
-    return True
 
 
 # upload_onnx uploads an onnx file to the toolchain-server
@@ -200,7 +131,7 @@ def upload_onnx(path, example="", docs={}, email=True) -> bool:
         except Exception as e:
             if not glob.SILENT:
                 print("FATAL: Unable to carry out the upload request: the toolchain is not available. \n"
-                      "Your model has not been uploaded. \n")
+                      "Your model has not been uploaded. PLACE 1 URL: {url}\n")
             if glob.DEBUG:
                 raise UploadModelError("We were unable to obtain JWT authorization: " + str(e))
             return False
@@ -241,256 +172,8 @@ def upload_onnx(path, example="", docs={}, email=True) -> bool:
         return False
 
 
-# upload_sklearn uploads a fitted sklearn model to the toolchain server
-def upload_sklearn(mod, feature_vector, docs={}, email=True, _keep=False) -> bool:
-    """upload_sklearn uploads a fitted sklearn model to Scailable.
-
-    - The function first checks whether the supplied model is ok (part of the list and fitted).
-    - Next, it checks whether an example row is provided and if so it creates the example
-    input and output .json objects.
-    - Next, the docs are checked; if none are provided a warning is issued and a simple
-    name is provided based on the model type.
-    - Subsequently, we package the whole thing, including details of the user system, into a
-    gzipped file that is stored on disc.
-    - Finally the whole package is uploaded to the toolchain.
-
-    Note: This method prints user-feedback by default. This feedback can be suppressed by calling the
-        stop_print() method.
-
-    Args:
-        mod: The model to be uploaded.
-        feature_vector: An example feature_vector for your model.
-            (i.e., the first row of your training data X obtained using row = X[0,:])
-        docs: A dict{} containing the fields 'name' and 'documentation'
-        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-        _keep: Bool indicating whether the .gzipped file should be retained. Default False.
-
-    Returns:
-        False if upload failed, true otherwise
-
-    Raises  (in debug mode):
-        UploadModelError if unable to successfully bundle and upload the model.
-    """
-    if glob.DEBUG:
-        print("We are checking your uploaded sklearn model...")
-
-    bundle = {}
-
-    # Check model:
-    if not _check_model(mod):
-        if not glob.SILENT:
-            print("FATAL: The model you are trying to upload is not (yet) supported or has not been fitted. \n"
-                  "Please see README.md for a list of supported models. \n"
-                  "Your models has not been uploaded. \n")
-        if glob.DEBUG:
-            raise UploadModelError("The uploaded model is not supported.")
-        return False
-    bundle['fitted_model'] = mod
-
-    # check input vector and generate an example:
-    bundle['example'] = {}
-    if feature_vector.any():
-        # try prediction
-        try:
-            output = _predict(mod, feature_vector)  # predict raises error if unable to generate predcition
-        except Exception as e:
-            if not glob.SILENT:
-                print("FATAL: We were unable to create an example inference. \n"
-                      "Your model has not been uploaded. \n")
-            if glob.DEBUG:
-                raise UploadModelError("Unable to generate prediction: " + str(e))
-            return False
-        # format data:
-        input_str: str = '[[%s]]' % ', '.join([str(i) for i in feature_vector.tolist()])
-        example = {'input': input_str, "output": json.dumps(output)}
-        bundle['example'] = example
-    else:
-        if not glob.SILENT:
-            print("FATAL: You did not provide a required example instance. (see docs). \n"
-                  "Your model has not been uploaded. \n")
-        return False
-
-    # check the docs:
-    bundle['docs'] = {}
-    if docs:
-        bundle['docs'] = docs
-    else:
-        try:  # This should work, but catching the exception just in case:
-            name = _get_model_name(mod)
-        except Exception:
-            name = "NAMELESS MODEL"
-        bundle['docs']['name'] = name
-        bundle['docs']['documentation'] = "-- EMPTY --"
-        if not glob.SILENT:
-            print("WARNING: You did not provide any documentation. \n"
-                  "We will simply use " + name + " as its name without further documentation.")
-
-    # check authorization:
-    auth = _check_jwt()
-    if not auth:
-        if not glob.SILENT:
-            print("FATAL: We were unable to obtain JWT authorization for your account. \n"
-                  "Your model has not been uploaded. \n")
-        if glob.DEBUG:
-            raise UploadModelError("We were unable to obtain JWT authorization.")
-        return False
-
-    # get system information
-    bundle['system_info'] = _get_system_info()
-
-    # gzip the bundle
-    if not _gzip_save(bundle):
-        if not glob.SILENT:
-            print("FATAL: We were unable to gzip your model bundle. \n"
-                  "Your model has not been uploaded. \n")
-        if glob.DEBUG:
-            raise UploadModelError("We were unable to save the bundle.")
-        return False
-
-    # all ok, upload:
-    if auth:
-
-        url = glob.TOOLCHAIN_URL + "/upload/" + glob.JWT_USER_ID
-
-        # Map python package to the right toolchain:
-        pkg_name = _get_model_package(mod)
-        toolchain_name = ""
-        if pkg_name == "sklearn":
-            toolchain_name = "sklearn"
-        elif pkg_name == "statsmodels":
-            toolchain_name = "sklearn"
-        elif pkg_name == "xgboost":
-            toolchain_name = "sklearn"
-        elif pkg_name == "lightgbm":
-            toolchain_name = "sklearn"
-
-        # Setup the actual request
-        data: dict = {
-            'email': email,
-            'package': __version__,
-            'toolchain': toolchain_name,
-            'name': bundle['docs'].get('name', "No name found."),
-            'docs': bundle['docs'].get('documentation', "No docs provided."),
-            'exampleInput': bundle['example'].get('input', "[]"),
-            'exampleOutput': bundle['example'].get('output', "[]")
-        }
-        payload: dict = {
-            'data': json.dumps(data)
-        }
-
-        files = [('bundle', open(glob.GZIP_BUNDLE, 'rb'))]
-        headers = {
-            'Authorization': glob.JWT_TOKEN,
-        }
-
-        # Do the request (and make sure to delete the gzip if errors occur)
-        try:
-            response = requests.post(url, headers=headers, data=payload, files=files)
-        except Exception as e:
-            if not glob.SILENT:
-                print("FATAL: Unable to carry out the upload request: the toolchain is not available. \n"
-                      "Your model has not been uploaded. \n")
-            if not _keep:
-                _gzip_delete()
-            if glob.DEBUG:
-                raise UploadModelError("We were unable to obtain JWT authorization: " + str(e))
-            return False
-
-        # Error handling
-        try:
-            response_data = json.loads(response.text)
-        except Exception as e:
-            if not glob.SILENT:
-                print("FATAL: We did not receive a valid JSON response from the toolchain-server. \n"
-                      "Your model has not been uploaded. \n")
-            if not _keep:
-                _gzip_delete()
-            if glob.DEBUG:
-                raise UploadModelError("We did not receive a valid response from the server: " + str(e))
-            return False
-
-        if response_data['error']:
-            if not glob.SILENT:
-                print("FATAL: An error was returned by the toolchain-server. \n"
-                      "Your model has not been uploaded. \n")
-            if not _keep:
-                _gzip_delete()
-            if glob.DEBUG:
-                raise UploadModelError("We did not receive a valid response from the server: " + response_data['error'])
-            return False
-
-        if glob.DEBUG:
-            print("The following content has been send to the toolchain server:")
-            print(bundle)
-
-        # user feedback:
-        if not glob.SILENT:
-            print("Your model was successfully uploaded to Scailable!")
-            print("NOTE: After transpiling, we will send you an email and your model will be available at "
-                  "https://admin.sclbl.net.")
-            print("Or, alternatively, you can use the 'endpoints()' function to list all your uploaded models. \n")
-
-        # remove bundle:
-        if not _keep:
-            _gzip_delete()
-
-        return True
-
-    else:
-        return False
-
-
-# update updates an existing model
-def update(mod, features, cfid, docs={}, email=True, model_type="sklearn", _keep=False) -> bool:
-    """Updates an already existing model.
 
-    The update function is similar to the upload function in most respects (so, see its docs),
-    but instead of creating a new endpoint it overwrites the docs and model of an already exisitng
-    endpoint. Thus, there is an additional argument "cfid" providing the computeFunction Id
-    of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already
-    existing endpoints. Just like the upload function, update is a wrapper for:
-     - update_sklearn(mod, feature_vector, cfid, docs={}, email=True, _keep=False)
-     - update_onnx(path, cfid, example="", docs={}, email=True)
 
-    Note: If you solely want to change the documentation of an endpoint, you can either use the
-        update_docs() function or the online admin interface at https://admin.sclble.net.
-
-    Args:
-        mod: The model to be uploaded (type="sklearn" OR the path to the stored ONNX file (type="onnx").
-        features:
-            - An example feature_vector for your model (type="sklearn" only).
-            (i.e., the first row of your training data X obtained using row = X[0,:])
-            - The input str (binary) to the onnx model (type="onnx" only). Can be an empty string.
-        cfid: a string with a valid computeFunction ID.
-        docs: A dict{} containing the fields 'name' and 'documentation'.
-        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-        model_type: String indicating the type of model. Currently with options "sklearn" or "onnx". Default "sklearn"
-        _keep: Bool indicating whether the .gzipped file should be retained (type="sklearn" only). Default False.
-
-    Returns:
-        False if upload failed, true otherwise
-
-    Raises  (in debug mode):
-        UploadModelError if unable to successfully bundle and upload the model.
-    """
-    if model_type == "sklearn":
-        if features == "":
-            if not glob.SILENT:
-                print("FATAL: You cannot upload a sklearn model with an empty string as feature vector.")
-            if glob.DEBUG:
-                raise UploadModelError("Cannot upload sklearn model with empty string as feature vector.")
-            return False
-        if not update_sklearn(mod, features, cfid, docs=docs, email=email, _keep=_keep):
-            return False
-    elif model_type == "onnx":
-        if not update_onnx(mod, cfid, example=features, docs=docs, email=email):
-            return False
-    else:
-        if glob.DEBUG:
-            raise UploadModelError("Please specify a valid model type.")
-        return False
-
-    return True
 
 
 # update_onnx updates an onnx model
@@ -604,8 +287,8 @@ def update_onnx(path, cfid, example="", docs={}, email=True) -> bool:
             response = requests.put(url, headers=headers, data=payload, files=files)
         except Exception as e:
             if not glob.SILENT:
-                print("FATAL: Unable to carry out the update request: the toolchain is not available. \n"
-                      "Your model has not been updated. \n")
+                print(f"FATAL: Unable to carry out the update request: the toolchain is not available. \n"
+                      f"Your model has not been updated. {url}, user id: {glob.JWT_USER_ID}, cfid:  {cfid}\n")
             if glob.DEBUG:
                 raise UploadModelError("We were unable to obtain JWT authorization: " + str(e))
             return False
@@ -643,197 +326,6 @@ def update_onnx(path, cfid, example="", docs={}, email=True) -> bool:
         return False
 
 
-# update_sklearn updates an sklearn model
-def update_sklearn(mod, feature_vector, cfid, docs={}, email=True, _keep=False) -> bool:
-    """Updates an already existing sklearn model.
-
-    The update function is similar to the upload function in most respects (so, see its docs),
-    but instead of creating a new endpoint it overwrites the docs and model of an already existing
-    endpoint. Thus, there is an additional argument "cfid" providing the computeFunction Id
-    of the endpoint that needs to be updated. Use sp.list_models() to get a list of your already
-    existing endpoints.
-
-    Note: If you solely want to change the documentation of an endpoint, you can either use the
-        update_docs() function or the online admin interface at https://admin.sclble.net.
-
-    Args:
-        mod: The model to be uploaded.
-        feature_vector: An example feature_vector for your model.
-            (i.e., the first row of your training data X obtained using row = X[0,:])
-        cfid: a string with a valid computeFunction ID.
-        docs: A dict{} containing the fields 'name' and 'documentation'. Default {}.
-        email: Bool indicating whether a confirmation email of a successful conversion should be send. Default True.
-        _keep: Bool indicating whether the .gzipped file should be retained. Default False.
-
-    Returns:
-        False if upload failed, true otherwise
-
-    Raises  (in debug mode):
-        UploadModelError if unable to successfully bundle and upload the model.
-    """
-    if glob.DEBUG:
-        print("We are checking your updated sklearn model...")
-
-    bundle = {}
-
-    # Check model:
-    if not _check_model(mod):
-        if not glob.SILENT:
-            print("FATAL: The model you are trying to upload is not (yet) supported or has not been fitted. \n"
-                  "Please see README.md for a list of supported models. \n"
-                  "Your models has not been uploaded. \n")
-        if glob.DEBUG:
-            raise UploadModelError("The submitted model is not supported.")
-        return False
-    bundle['fitted_model'] = mod
-
-    # check input vector and generate an example:
-    bundle['example'] = {}
-    if feature_vector.any():
-        # try prediction
-        try:
-            output = _predict(mod, feature_vector)  # predict raises error if unable to generate predcition
-        except Exception as e:
-            if not glob.SILENT:
-                print("FATAL: We were unable to create an example inference. \n"
-                      "Your model has not been updated. \n")
-            if glob.DEBUG:
-                raise UploadModelError("Unable to generate prediction: " + str(e))
-            return False
-        # format data:
-        input_str: str = '[[%s]]' % ', '.join([str(i) for i in feature_vector.tolist()])
-        example = {'input': input_str, "output": json.dumps(output)}
-        bundle['example'] = example
-    else:
-        if not glob.SILENT:
-            print("FATAL: You did not provide a required example instance. (see docs). \n"
-                  "Your model has not been updated. \n")
-        return False
-
-    # check the docs:
-    bundle['docs'] = {}
-    docs_update = True
-    if docs:
-        bundle['docs'] = docs
-    else:
-        docs_update = False
-        if not glob.SILENT:
-            print("WARNING: You did not provide any documentation. \n"
-                  "We will only update the .wasm model, not the documentation.")
-
-    # check authorization:
-    auth = _check_jwt()
-    if not auth:
-        if not glob.SILENT:
-            print("FATAL: We were unable to obtain JWT authorization for your account. \n"
-                  "Your model has not been updated. \n")
-        if glob.DEBUG:
-            raise UploadModelError("We were unable to obtain JWT authorization.")
-        return False
-
-    # get system information
-    bundle['system_info'] = _get_system_info()
-
-    # gzip the bundle
-    if not _gzip_save(bundle):
-        if not glob.SILENT:
-            print("FATAL: We were unable to gzip your model bundle. \n"
-                  "Your model has not been updated. \n")
-        if glob.DEBUG:
-            raise UploadModelError("We were unable to save the bundle.")
-        return False
-
-    # all ok, upload:
-    if auth:
-
-        url = glob.TOOLCHAIN_URL + "/upload/" + glob.JWT_USER_ID + "/" + cfid
-
-        # Map python package to the right toolchain:
-        pkg_name = _get_model_package(mod)
-        toolchain_name = ""
-        if pkg_name == "sklearn":
-            toolchain_name = "sklearn"
-        elif pkg_name == "statsmodels":
-            toolchain_name = "sklearn"
-        elif pkg_name == "xgboost":
-            toolchain_name = "sklearn"
-        elif pkg_name == "lightgbm":
-            toolchain_name = "sklearn"
-
-        # Setup the actual request
-        data: dict = {
-            'email': email,
-            'package': __version__,
-            'toolchain': toolchain_name,
-            'name': bundle['docs'].get('name', ""),
-            'docs': bundle['docs'].get('documentation', ""),
-            'updateDocs': docs_update,
-            'exampleInput': bundle['example'].get('input', "[]"),
-            'exampleOutput': bundle['example'].get('output', "[]")
-        }
-        payload: dict = {
-            'data': json.dumps(data)
-        }
-
-        files = [('bundle', open(glob.GZIP_BUNDLE, 'rb'))]
-        headers = {
-            'Authorization': glob.JWT_TOKEN
-        }
-
-        # Do the request (and make sure to delete the gzip if errors occur)
-        try:
-            response = requests.put(url, headers=headers, data=payload, files=files)
-        except Exception as e:
-            if not glob.SILENT:
-                print("FATAL: Unable to carry out the upload request: the toolchain is not available. \n"
-                      "Your model has not been updated. \n")
-            if not _keep:
-                _gzip_delete()
-            if glob.DEBUG:
-                raise UploadModelError("We were unable to obtain JWT authorization: " + str(e))
-            return False
-
-        # Error handling
-        try:
-            response_data = json.loads(response.text)
-        except Exception as e:
-            if not glob.SILENT:
-                print("FATAL: We did not receive a valid JSON response from the toolchain-server. \n"
-                      "Your model has not been updated. \n")
-            if not _keep:
-                _gzip_delete()
-            if glob.DEBUG:
-                raise UploadModelError("We did not receive a valid response from the server: " + str(e))
-            return False
-
-        if response_data['error']:
-            if not glob.SILENT:
-                print("FATAL: An error was returned by the server. \n"
-                      "Your model has not been updated. \n")
-            if not _keep:
-                _gzip_delete()
-            if glob.DEBUG:
-                raise UploadModelError("We did not receive a valid response from the server: " + response_data['error'])
-            return False
-
-        if glob.DEBUG:
-            print("The following content has been send to the toolchain server:")
-            print(bundle)
-
-        # user feedback:
-        if not glob.SILENT:
-            print("Your model was successfully submitted for an update. \n")
-
-        # remove bundle:
-        if not _keep:
-            _gzip_delete()
-
-        return True
-
-    else:
-        return False
-
-
 # update_docs updates the docs of a given model (but not the model itself:
 def update_docs(cfid, docs) -> bool:
     """Updates the documentation of an already existing model
@@ -853,6 +345,7 @@ def update_docs(cfid, docs) -> bool:
     """
 
     # check the docs:
+    print(docs)
     name = docs.get('name', "")
     if name == "":
         print("FATAL: Please make sure to add a name to your documentation (using the 'name') field \n"
@@ -902,8 +395,9 @@ def update_docs(cfid, docs) -> bool:
             response = requests.put(url, headers=headers, data=payload, files=files)
         except Exception as e:
             if not glob.SILENT:
-                print("FATAL: Unable to carry out the upload request: the toolchain is not available. \n"
-                      "Your model documentation has not been updated. \n")
+                print(f"FATAL: Unable to carry out the upload request: the toolchain is not available. \n"
+                      "Your model documentation has not been updated. PLACE 2 URL: {url} \n")
+                print(url)
             if glob.DEBUG:
                 raise UploadModelError("We were unable to obtain JWT authorization: " + str(e))
             return False
@@ -1273,137 +767,6 @@ def delete_device(did) -> bool:
 
     return True
 
-
-# run generates inference for a sklearn model
-def run(cfid, feature_vector, fv_type="auto") -> dict:
-    """run a sklearn model that has previously been uploaded to Scailable.
-
-    The run function allows a user to execute a sklearn task that has been uploaded to Scailable and
-    for which a REST endpoint is thus available.
-
-    The user specifies the compute-function id, and the desired input, and receives the resulting output
-    (often the inference generated by a model)
-
-    Note: This function returns the result of the following code which can be embedded in any python project
-    to consume a Scailable REST endpoint without including the sclblpy package:
-
-    # import requests
-    #
-    # url = "https://taskmanager.sclbl.net:8080/task/" + cfid
-    #
-    # data = ",".join(map(str, feature_vector))
-    #
-    # payload = "{\"input\":
-    #   {\"content-type\":\"json\",
-    #   \"location\":\"embedded\",
-    #   \"data\":\"{
-    #       \\\"input\\\": [[" + data + "]]}\"},
-    #   \"output\":{
-    #       \"content-type\":\"json\",
-    #       \"location\":\"echo\"},
-    #       \"control\":1,
-    #       \"properties\":{\"language\":\"WASM\"}}"
-    #
-    # headers = {
-    #     'Content-Type': 'application/x-www-form-urlencoded'
-    # }
-    #
-    # response = requests.request("POST", url, headers=headers, data=payload)
-    #
-
-    Args:
-        cfid: String containing the compute-function ID of an existing Scailable endpoint
-        feature_vector: The input for the compute-function
-            (i.e., the a single row of data X obtained using row = X[0,:]).
-        fv_type: String indicating the type of input ("csv", "pb", or "raw"). Default is "auto".
-            (when set to "auto" the function will try to determine the input type).
-
-
-    Returns:
-        False if the call fails, a dict containing the server response otherwise.
-
-    Raises  (in debug mode):
-        RunTaskError if unable to run the compute function.
-    """
-
-    # Check the cfid:
-    if not cfid:
-        if not glob.SILENT:
-            print("Please provide a valid cfid. Abort.")
-        return False
-
-    # Create the ednpoint url:
-    url = glob.TASK_MANAGER_URL + "/task/" + cfid
-
-    # Determine the input vector type:
-    if fv_type == "auto":
-        fv_type = _check_input_type(feature_vector)
-
-    if not fv_type or fv_type not in ["csv", "pb", "raw"]:
-        if not glob.SILENT:
-            print("Your feature_vector input type is invalid or cannot be determined. Abort.")
-        return False
-
-    # Run:
-    response = ""
-    if fv_type == "csv":
-        try:
-            response = _run_csv(url, feature_vector)
-        except Exception as e:
-            if not glob.SILENT:
-                print("Run csv error: " + str(e))
-            if glob.DEBUG:
-                raise RunTaskError("Run csv error:" + str(e))
-            return False
-    elif fv_type == "raw":
-        try:
-            response = _run_raw(url, feature_vector)
-        except Exception as e:
-            if not glob.SILENT:
-                print("Run raw error: " + str(e))
-            if glob.DEBUG:
-                raise RunTaskError("Run raw error:" + str(e))
-            return False
-    elif fv_type == "pb":
-        try:
-            response = _run_pb(url, feature_vector)
-        except Exception as e:
-            if not glob.SILENT:
-                print("Run pb error: " + str(e))
-            if glob.DEBUG:
-                raise RunTaskError("Run pb error:" + str(e))
-            return False
-
-    # Check:
-    if response == "":
-        if not glob.SILENT:
-            print("An error occurred while running, the response is empty.")
-        if glob.DEBUG:
-            raise RunTaskError("An error occurred while running, the response is empty.")
-        return False
-
-    # Parse:
-    try:
-        json_string = response.text
-    except Exception as e:
-        if not glob.SILENT:
-            print("We were unable to parse server response to output. " + str(e))
-        if glob.DEBUG:
-            raise RunTaskError("We were unable to parse server response to output. " + str(e))
-        return False
-
-    try:
-        output = json.loads(json_string)
-    except Exception as e:
-        if not glob.SILENT:
-            print("We were unable to parse server response to json. " + str(e))
-        if glob.DEBUG:
-            raise RunTaskError("We were unable to parse server response to json. " + str(e))
-        return False
-
-    return output
-
-
 # models lists the models / endpoints for the current user.
 def models(offset=0, limit=20, _verbose=True, _return=False) -> dict:
     """ Print or return the endpoints available for the current user.
@@ -1658,22 +1021,6 @@ def start_print() -> bool:
     return True
 
 
-# list_models lists all supported sklearn models
-def list_models() -> dict:
-    """Print or return a list of all supported models.
-
-    Returns:
-        A dictionary detailing the supported models
-    """
-    if not glob.SUPPORTED_MODELS:
-        _load_supported_models()
-
-    if not glob.SILENT:
-        print("Currently supported models:")
-        print(json.dumps(glob.SUPPORTED_MODELS, sort_keys=True, indent=4))
-
-    return glob.SUPPORTED_MODELS
-
 
 # _set_toolchain_URL sets the location of the toolchain (for local testing)
 def _set_toolchain_URL(url: str) -> str:
diff --git a/sclblpy/supported_models.json b/sclblpy/supported_models.json
deleted file mode 100644
index 680b15f..0000000
--- a/sclblpy/supported_models.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
-  "sklearn" : [
-    "AdaGradClassifier",
-    "ARDRegression",
-    "BayesianRidge",
-    "DecisionTreeClassifier",
-    "DecisionTreeRegressor",
-    "ElasticNet",
-    "ElasticNetCV",
-    "ExtraTreeClassifier",
-    "ExtraTreeRegressor",
-    "ExtraTreesClassifier",
-    "ExtraTreesRegressor",
-    "HuberRegressor",
-    "Lars",
-    "LarsCV",
-    "Lasso",
-    "LassoCV",
-    "LassoLars",
-    "LassoLarsCV",
-    "LassoLarsIC",
-    "LinearRegression",
-    "LinearSVC",
-    "LinearSVR",
-    "LogisticRegression",
-    "LogisticRegressionCV",
-    "NuSVC",
-    "NuSVR",
-    "OrthogonalMatchingPursuit",
-    "OrthogonalMatchingPursuitCV",
-    "PassiveAggressiveClassifier",
-    "PassiveAggressiveRegressor",
-    "Perceptron",
-    "RandomForestClassifier",
-    "RandomForestRegressor",
-    "RANSACRegressor",
-    "Ridge",
-    "RidgeClassifier",
-    "RidgeClassifierCV",
-    "RidgeCV",
-    "SGDClassifier",
-    "SGDRegressor",
-    "SVC",
-    "SVR",
-    "TheilSenRegressor"
-  ],
-  "statsmodels" : [
-    "GLS",
-    "GLSAR",
-    "OLS",
-    "ProcessMLE",
-    "QuantReg",
-    "WLS"
-  ],
-  "xgboost" : [
-    "XGBClassifier",
-    "XGBRegressor",
-    "XGBRFClassifier",
-    "XGBRFRegressor"
-  ],
-  "lightgbm" : [
-    "LGBMClassifier",
-    "LGBMRegressor"
-  ]
-}
\ No newline at end of file
diff --git a/sclblpy/version.py b/sclblpy/version.py
index e47f949..33e4ca2 100644
--- a/sclblpy/version.py
+++ b/sclblpy/version.py
@@ -1,2 +1,2 @@
 # Central place for version numbering:
-__version__  = "0.1.7"
\ No newline at end of file
+__version__  = "0.1.8"
\ No newline at end of file
diff --git a/sclblpy_tutorial.ipynb b/sclblpy_tutorial.ipynb
new file mode 100644
index 0000000..f290d0f
--- /dev/null
+++ b/sclblpy_tutorial.ipynb
@@ -0,0 +1,751 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from sclblpy import main as sp"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Sclblpy \n",
+    "Sclblpy allows you to upload a `.onnx` model to your sclbl admin that can subsequently be assigned to a device that has previously been registered on your account.\n",
+    "\n",
+    "\n",
+    "## (preliminary) make an account\n",
+    "\n",
+    "To make an account, visit [Scailable](https://admin.sclbl.net/signup.html)\n",
+    "\n",
+    "## (preliminary) register at least one device\n",
+    "\n",
+    "To register a device, follow the tutorial [here](https://github.com/scailable/sclbl-tutorials/tree/master/solutions-manuals/sclbl-local-ai-manager). You'll be required to get a license as well - just apply for one and you'll receive a local evaluation copy (or use your previously obtained one, or get in contact with us)\n",
+    "\n",
+    "If you've read the above already and are only looking for the command, it's `wget -q -O - https://get.sclbl.net | sudo bash` or `sudo /opt/sclbl/etc/init startui` if you've already installed the manager. NOTE: obviously do not run `sudo` commands if you're not sure what you're doing! \n",
+    "\n",
+    "NOTE: the device's device manager has to be running during this tutorial, otherwise the assignment will (somehwat obviously) not work.\n",
+    "\n",
+    "## sign in\n",
+    "\n",
+    "To use the package, you'll have to sign in with the username and password you've received in the previous step\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## (optional) build a model\n",
+    "\n",
+    "While most `.onnx` files will work out of the box with sclblpy, many of you will aim to use sclblpy to deploy some kind of Neural Network trained in e.g. Pytorch. We'll show you briefly how to export a Neural Network from the torch.nn.Module ... module to `onnx`, but feel free to use your own model, as long as it can be exported to `onnx` (one caveat: Not every operator is currently supported, find a list of the ones that work [here](https://github.com/scailable/sclblonnx/blob/master/sclblonnx/supported_onnx.json).\n",
+    "\n",
+    "Our example won't even be trained, since we're only interested in the deployment part, essentially we'll be doing the first few steps from https://pytorch.org/tutorials/advanced/super_resolution_with_onnxruntime.html; feel free to do the rest of the tutorial as well!\n",
+    "\n",
+    "\n",
+    "NOTE: `pixel_shuffle()` is not yet supported by our runtime, so we have to remove it before conversion"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "SuperResolutionNet(\n",
+      "  (relu): ReLU()\n",
+      "  (conv1): Conv2d(1, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))\n",
+      "  (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
+      "  (conv3): Conv2d(64, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
+      "  (conv4): Conv2d(32, 9, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
+      ")\n"
+     ]
+    }
+   ],
+   "source": [
+    "import torch\n",
+    "import torch.nn as nn\n",
+    "import torch.nn.init as init\n",
+    "\n",
+    "\n",
+    "class SuperResolutionNet(nn.Module):\n",
+    "    def __init__(self, upscale_factor, inplace=False):\n",
+    "        super(SuperResolutionNet, self).__init__()\n",
+    "\n",
+    "        self.relu = nn.ReLU(inplace=inplace)\n",
+    "        self.conv1 = nn.Conv2d(1, 64, (5, 5), (1, 1), (2, 2))\n",
+    "        self.conv2 = nn.Conv2d(64, 64, (3, 3), (1, 1), (1, 1))\n",
+    "        self.conv3 = nn.Conv2d(64, 32, (3, 3), (1, 1), (1, 1))\n",
+    "        self.conv4 = nn.Conv2d(32, upscale_factor ** 2, (3, 3), (1, 1), (1, 1))\n",
+    "        #self.pixel_shuffle = nn.PixelShuffle(upscale_factor)\n",
+    "\n",
+    "        self._initialize_weights()\n",
+    "\n",
+    "    def forward(self, x):\n",
+    "        x = self.relu(self.conv1(x))\n",
+    "        x = self.relu(self.conv2(x))\n",
+    "        x = self.relu(self.conv3(x))\n",
+    "        #x = self.pixel_shuffle(self.conv4(x))\n",
+    "        return x\n",
+    "\n",
+    "    def _initialize_weights(self):\n",
+    "        init.orthogonal_(self.conv1.weight, init.calculate_gain('relu'))\n",
+    "        init.orthogonal_(self.conv2.weight, init.calculate_gain('relu'))\n",
+    "        init.orthogonal_(self.conv3.weight, init.calculate_gain('relu'))\n",
+    "        init.orthogonal_(self.conv4.weight)\n",
+    "\n",
+    "# Create the super-resolution model by using the above model definition.\n",
+    "torch_model = SuperResolutionNet(upscale_factor=3)\n",
+    "\n",
+    "print(torch_model)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "So now we have our model, we'll call torch.eval() before we convert it to onnx"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "SuperResolutionNet(\n",
+       "  (relu): ReLU()\n",
+       "  (conv1): Conv2d(1, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))\n",
+       "  (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
+       "  (conv3): Conv2d(64, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
+       "  (conv4): Conv2d(32, 9, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
+       ")"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "\n",
+    "batch_size = 1    # just a random number\n",
+    "\n",
+    "\n",
+    "# set the model to inference mode\n",
+    "torch_model.eval()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/thomas/anaconda3/lib/python3.7/site-packages/torch/onnx/utils.py:718: UserWarning: Provided key input for dynamic axes is not a valid input/output name\n",
+      "  warnings.warn(\"Provided key {} for dynamic axes is not a valid input/output name\".format(key))\n",
+      "/home/thomas/anaconda3/lib/python3.7/site-packages/torch/onnx/utils.py:718: UserWarning: Provided key output for dynamic axes is not a valid input/output name\n",
+      "  warnings.warn(\"Provided key {} for dynamic axes is not a valid input/output name\".format(key))\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Input to the model\n",
+    "x = torch.randn(batch_size, 1, 224, 224, requires_grad=True)\n",
+    "torch_out = torch_model(x)\n",
+    "\n",
+    "# Export the model\n",
+    "torch.onnx.export(torch_model,               # model being run\n",
+    "                  x,                         # model input (or a tuple for multiple inputs)\n",
+    "                  \"super_resolution.onnx\",   # where to save the model (can be a file or file-like object)\n",
+    "                  export_params=True,        # store the trained parameter weights inside the model file\n",
+    "                  opset_version=10,          # the ONNX version to export the model to\n",
+    "                  do_constant_folding=True,  # whether to execute constant folding for optimization\n",
+    "                  input_names = ['input'],   # the model's input names\n",
+    "                  output_names = ['output'], # the model's output names\n",
+    "                  dynamic_axes={'input' : {0 : 'batch_size'},    # variable length axes\n",
+    "                                'output' : {0 : 'batch_size'}})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## write some docs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "docs = {}\n",
+    "docs['name'] = \"Faux Superresolution ONNX\"\n",
+    "docs['documentation'] = \"A long .md thing....\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Upload the model to your admin (where we call the thing we upload stuff to?)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Your ONNX file was successfully uploaded to Scailable!\n",
+      "NOTE: After transpiling, we will send you an email and your model will be available at https://admin.sclbl.net.\n",
+      "Or, alternatively, you can use the 'models()' function to list all your uploaded models. \n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "check = sp.upload_onnx(\"super_resolution.onnx\",\"\",docs)\n",
+    "\n",
+    "\n",
+    "\n",
+    "#note: this will take a bit"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## (optional) wait for a few seconds to give the server time to convert the model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import time\n",
+    "\n",
+    "time.sleep(15)\n",
+    "\n",
+    "\n",
+    "#remove file\n",
+    "import os\n",
+    "if os.path.exists(\"super_resolution.onnx\"):\n",
+    "    os.remove(\"super_resolution.onnx\")\n",
+    "else:\n",
+    "    print(\"The file does not exist\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## (optional) check if the model has been uploaded\n",
+    "\n",
+    "Go to https://admin.sclbl.net/index.html to check if your model has been uploaded.\n",
+    "\n",
+    "Here you'll be able to check out your model's stats and assign a driver."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## get the id(s) of your device(s)\n",
+    "\n",
+    "In order to interact with your devices, you'll need the id of the model you'll want to interact with. Luckily, that's easy as a pie. The `_verbose = False` suppresses written output, the `_return=True` forces the method to return the data\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "devices = sp.devices(_return=True,_verbose=False)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'created_day': '01 Mar 2022',\n",
+       "  'created_time': '10:51:21:837',\n",
+       "  'did': '4da83a6ab04a4ff19694414f20ce4a05-172308997771235',\n",
+       "  'id': 1349,\n",
+       "  'name': 'My Device',\n",
+       "  'rid': '88356481-994d-11ec-92c8-96000113f32b',\n",
+       "  'runtime': 'srp-runtime',\n",
+       "  'type': 'CPU',\n",
+       "  'uid': '91962e67-9bda-42d8-b5b7-7529314dde5e',\n",
+       "  'updated_day': '01 Mar 2022',\n",
+       "  'updated_time': '10:51:21:837'}]"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "devices"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`devices` will be a list of dictionaries containing a bunch of information about your devices, such as the id, did, rid, name, time of creation, runtime, ... However, this tutorial only requires `did` and `rid`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "device= [x for x in devices if x['name']=='My Device'][0]\n",
+    "device_did = device['did']\n",
+    "device_rid = device['rid']"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## get the model's ID"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'agent': 'toolchain',\n",
+       "  'alias': '',\n",
+       "  'cfid': '8cc233ba-c617-11ec-a3cb-96000113f32b',\n",
+       "  'created_day': '27 Apr 2022',\n",
+       "  'created_time': '10:48:19',\n",
+       "  'cycles': '1',\n",
+       "  'docs': 'A long .md thing....',\n",
+       "  'exampleinput': '',\n",
+       "  'exampleoutput': '',\n",
+       "  'filename': '91962e67-9bda-42d8-b5b7-7529314dde5e-8974dbc3-c617-11ec-a675-96000113f588.wasm',\n",
+       "  'id': 645,\n",
+       "  'input_driver': '',\n",
+       "  'input_driver_details': '',\n",
+       "  'jwt_secured': False,\n",
+       "  'location': 'https://cdn.sclbl.net/file/8cc233ba-c617-11ec-a3cb-96000113f32b.wasm',\n",
+       "  'name': 'Faux Superresolution ONNX',\n",
+       "  'output_driver': '',\n",
+       "  'output_driver_details': '',\n",
+       "  'profit': '0.1',\n",
+       "  'updated_day': '27 Apr 2022',\n",
+       "  'updated_time': '10:48:19'}]"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "models = sp.models(_return=True, _verbose=False)\n",
+    "models"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "model = [x for x in models if x['name'] == docs['name']][0]\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "model_cfid = model['cfid']\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'agent': 'toolchain',\n",
+       " 'alias': '',\n",
+       " 'cfid': '8cc233ba-c617-11ec-a3cb-96000113f32b',\n",
+       " 'created_day': '27 Apr 2022',\n",
+       " 'created_time': '10:48:19',\n",
+       " 'cycles': '1',\n",
+       " 'docs': 'A long .md thing....',\n",
+       " 'exampleinput': '',\n",
+       " 'exampleoutput': '',\n",
+       " 'filename': '91962e67-9bda-42d8-b5b7-7529314dde5e-8974dbc3-c617-11ec-a675-96000113f588.wasm',\n",
+       " 'id': 645,\n",
+       " 'input_driver': '',\n",
+       " 'input_driver_details': '',\n",
+       " 'jwt_secured': False,\n",
+       " 'location': 'https://cdn.sclbl.net/file/8cc233ba-c617-11ec-a3cb-96000113f32b.wasm',\n",
+       " 'name': 'Faux Superresolution ONNX',\n",
+       " 'output_driver': '',\n",
+       " 'output_driver_details': '',\n",
+       " 'profit': '0.1',\n",
+       " 'updated_day': '27 Apr 2022',\n",
+       " 'updated_time': '10:48:19'}"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Assign the model to a device\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Your assignment has been added. \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sp.assign(model_cfid, device_did, device_rid, _verbose=True)\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "##  a model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "# Export the model\n",
+    "torch.onnx.export(torch_model,               # model being run\n",
+    "                  x,                         # model input (or a tuple for multiple inputs)\n",
+    "                  \"super_resolution_new.onnx\",   # where to save the model (can be a file or file-like object)\n",
+    "                  export_params=True,        # store the trained parameter weights inside the model file\n",
+    "                  opset_version=10,          # the ONNX version to export the model to\n",
+    "                  do_constant_folding=True,  # whether to execute constant folding for optimization\n",
+    "                  input_names = ['input_new'],   # the model's input names\n",
+    "                  output_names = ['output_new'], # the model's output names\n",
+    "                  dynamic_axes={'input' : {0 : 'batch_size'},    # variable length axes\n",
+    "                                'output' : {0 : 'batch_size'}})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Your model was successfully submitted for an update. \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sp.update_onnx(\"super_resolution_new.onnx\",model_cfid,\"\",docs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "time.sleep(15)\n",
+    "\n",
+    "\n",
+    "#remove file\n",
+    "import os\n",
+    "if os.path.exists(\"super_resolution_new.onnx\"):\n",
+    "    os.remove(\"super_resolution_new.onnx\")\n",
+    "else:\n",
+    "    print(\"The file does not exist\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "models = sp.models(_return=True, _verbose=False)\n",
+    "model = [x for x in models if x['name'] == docs['name']][0]\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'agent': 'toolchain',\n",
+       " 'alias': '',\n",
+       " 'cfid': '8cc233ba-c617-11ec-a3cb-96000113f32b',\n",
+       " 'created_day': '27 Apr 2022',\n",
+       " 'created_time': '10:48:19',\n",
+       " 'cycles': '1',\n",
+       " 'docs': 'A long .md thing....',\n",
+       " 'exampleinput': '',\n",
+       " 'exampleoutput': '',\n",
+       " 'filename': '91962e67-9bda-42d8-b5b7-7529314dde5e-8974dbc3-c617-11ec-a675-96000113f588.wasm',\n",
+       " 'id': 645,\n",
+       " 'input_driver': None,\n",
+       " 'input_driver_details': None,\n",
+       " 'jwt_secured': False,\n",
+       " 'location': 'https://cdn.sclbl.net/file/8cc233ba-c617-11ec-a3cb-96000113f32b.wasm',\n",
+       " 'name': 'Faux Superresolution ONNX',\n",
+       " 'output_driver': None,\n",
+       " 'output_driver_details': None,\n",
+       " 'profit': '0.1',\n",
+       " 'updated_day': '27 Apr 2022',\n",
+       " 'updated_time': '10:48:39'}"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## models a model's docs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{'name': 'a newly named Superresolution ONNX', 'documentation': 'An even longer .md thing....'}\n",
+      "Your model documentation has been updated. \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "docs = {}\n",
+    "docs['name'] = \"a newly named Superresolution ONNX\"\n",
+    "docs['documentation'] = \"An even longer .md thing....\"\n",
+    "\n",
+    "sp.update_docs(model_cfid, docs)\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## redeploy\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## delete model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Endpoint with cfid 8cc233ba-c617-11ec-a3cb-96000113f32b was successfully deleted.\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sp.delete_model(model_cfid)  # Where cfid is the compute function id\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "You currently do not own any active endpoints.\n",
+      "\n",
+      "Need help getting started?\n",
+      " - See the sclblpy docs at https://pypi.org/project/sclblpy/.\n",
+      " - See our getting started tutorial at https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-101-getting-started.\n",
+      " - Or, login to your admin at https://admin.sclbl.net. \n",
+      "\n",
+      "NOTE: if you have just uploaded a model, please check your email; we will let you know when its available!\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sp.models()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/setup.py b/setup.py
index 52d21db..5220565 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@
     version=__version__,
     author="Maurits Kaptein",
     author_email="maurits.kaptein@scailable.net",
-    description="Python package for uploading sklearn and onnx models to Scailable toolchain.",
+    description="Python package for uploading onnx models to Scailable toolchain.",
     long_description=long_description,
     long_description_content_type="text/markdown",
     include_package_data=True,
@@ -26,7 +26,6 @@
         'numpy',
         'requests',
         'uuid',
-        'sklearn',
       ],
     python_requires='>=3.7',
 )


Test patch:
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/test/test_all_models.py b/test/test_all_models.py
deleted file mode 100644
index bc4ef2e..0000000
--- a/test/test_all_models.py
+++ /dev/null
@@ -1,886 +0,0 @@
-# Testing the upload function for all supported models.
-# This might take a while..
-import time
-import statsmodels.api as sm
-import lightgbm as lgb
-# import lightning as ln
-
-from sklearn import datasets
-from sklearn import linear_model
-from sklearn import tree
-from sklearn import ensemble
-from sklearn import svm
-
-from xgboost import XGBClassifier
-from xgboost import XGBRegressor
-from xgboost import XGBRFClassifier
-from xgboost import XGBRFRegressor
-
-import numpy as np
-
-from sclblpy import upload, _set_toolchain_URL, _set_usermanager_URL
-from sclblpy import endpoints
-from sclblpy import delete_endpoint
-
-# Script settings:
-from sclblpy._utils import _get_model_package, _get_model_name, _model_is_fitted
-from sclblpy.main import _toggle_debug_mode, stop_print
-
-RUN_TESTS = False  # Prevent unintended testing
-DEBUG = True  # Set to debug mode; if true it will raise exceptions
-PRINTING = True  # Toggle printing on and off.
-TEAR_DOWN = False  # Remove all endpoints after running tests (you will be prompted)?
-ADMIN_URL = "http://localhost:8008"  # Location of admin for this test
-TOOLCHAIN_URL = "http://localhost:8010"  # Location of toolchain for this test
-SLEEPTIME = 5  # Time in between blocks of models.
-
-
-iris_data = datasets.load_iris(return_X_y=True)
-
-
-# StatsModels
-def test_sm_GLS():
-    print("Testing SM, GLS...")
-    data = sm.datasets.longley.load(as_pandas=False)
-    X = sm.add_constant(data.exog)
-    est = sm.GLS(data.endog, X, sigma=1)
-    mod = est.fit()
-    docs = {'name': "GLS test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sm_GLSAR():
-    print("Testing SM, GLSAR...")
-    X, y = iris_data
-    est = sm.GLS(y, X, rho=2)
-    mod = est.fit()
-    docs = {'name': "GLSAR test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sm_OLS():
-    print("Testing SM, OLS...")
-    X, y = iris_data
-    est = sm.OLS(y, X)
-    mod = est.fit()
-    docs = {'name': "OLS test"}
-    fv = X[0, :]
-    upload(mod, fv, docs=docs)
-
-
-# def test_sm_ProcessMLE():
-#     print("Testing SM, ProcessMLE...")
-#     X, y = iris_data
-#     est = sm.ProcessMLE(y, X)
-#     mod = est.fit()
-#     docs = {'name': "ProcessMLE test"}
-#     fv = X[0, :]
-#     upload(mod, fv, docs=docs)
-
-
-def test_sm_QuantReg():
-    print("Testing SM, QuantReg...")
-    X, y = iris_data
-    est = sm.QuantReg(y, X)
-    mod = est.fit()
-    docs = {'name': "QuantReg test"}
-    fv = X[0, :]
-    upload(mod, fv, docs=docs)
-
-
-def test_sm_WLS():
-    print("Testing SM, WLS...")
-    Y = [1, 3, 4, 5, 2, 3, 4]
-    X = range(1, 8)
-    X = sm.add_constant(X)
-    est = sm.WLS(Y, X, weights=list(range(1, 8)))
-    mod = est.fit()
-    docs = {'name': "WLS test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-# Sklearn
-def test_sk_ARDRegression():
-    print("Testing sklearn, ARDRegression...")
-    mod = linear_model.ARDRegression()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ARDRegression test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_BayesianRidge():
-    print("Testing sklearn, BayesianRidge...")
-    mod = linear_model.BayesianRidge()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "BayesianRidge test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_DecisionTreeClassifier():
-    print("Testing sklearn, DecisionTreeClassifier...")
-    mod = tree.DecisionTreeClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "DecisionTreeClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_DecisionTreeRegressor():
-    print("Testing sklearn, DecisionTreeRegressor...")
-    mod = tree.DecisionTreeRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "DecisionTreeClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_ElasticNet():
-    print("Testing sklearn, ElasticNet...")
-    mod = linear_model.ElasticNet()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ElasticNet test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_ElasticNetCV():
-    print("Testing sklearn, ElasticNetCV...")
-    mod = linear_model.ElasticNetCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ElasticNetCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_ExtraTreeClassifier():
-    print("Testing sklearn, ExtraTreeClassifier...")
-    mod = tree.ExtraTreeClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ExtraTreeClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_ExtraTreeRegressor():
-    print("Testing sklearn, ExtraTreeRegressor...")
-    mod = tree.ExtraTreeRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ExtraTreeRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_ExtraTreesClassifier():
-    print("Testing sklearn, Ensemble ExtraTreeClassifier...")
-    mod = ensemble.ExtraTreesClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ExtraTreeClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_ExtraTreesRegressor():
-    print("Testing sklearn, Ensemble ExtraTreeRegressor...")
-    mod = ensemble.ExtraTreesRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "ExtraTreeRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_HuberRegressor():
-    print("Testing sklearn, HuberRegressor...")
-    mod = linear_model.HuberRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "HuberRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_Lars():
-    print("Testing sklearn, Lars...")
-    mod = linear_model.Lars()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "Lars test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LarsCV():
-    print("Testomg sklearn, LarsCV...")
-    mod = linear_model.LarsCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LarsCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_Lasso():
-    print("Testing sklearn, Lasso...")
-    mod = linear_model.Lasso()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "Lasso test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LassoCV():
-    print("Testing sklearn, LassoCV...")
-    mod = linear_model.LassoCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LassoCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LassoLars():
-    print("Testing sklearn, LassoLars...")
-    mod = linear_model.LassoLars()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LassoLars test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LassoLarsCV():
-    print("Testing sklearn, LassoLarsCV...")
-    mod = linear_model.LassoLarsCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LassoLarsCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LassoLarsIC():
-    print("Testing sklearn, LassoLarsIC...")
-    mod = linear_model.LassoLarsIC()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LassoLarsIC test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LinearRegression():
-    print("Testing sklearn, LinearRegression...")
-    mod = linear_model.LinearRegression()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LinearRegression test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LinearSVC():
-    print("Testing sklearn, LinearSVC...")
-    mod = svm.LinearSVC(max_iter=10000)  # Needs more iterations to converge
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LinearSVC test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-
-def test_sk_LinearSVR():
-    print("Testing sklearn, LinearSVR...")
-    mod = svm.LinearSVR()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LinearSVR test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LogisticRegression():
-    print("Testing sklearn, LogisticRegression...")
-    mod = linear_model.LogisticRegression(max_iter=1000)
-    X, y = iris_data
-    ybin = np.where(y <= 1, 0, 1)
-    mod.fit(X, ybin)
-    docs = {'name': "LogisticRegression test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_LogisticRegressionCV():
-    print("Testing sklearn, LogisticRegressionCV...")
-    mod = linear_model.LogisticRegressionCV(max_iter=1000)
-    X, y = iris_data
-    ybin = np.where(y <= 1, 0, 1)
-    mod.fit(X, ybin)
-    docs = {'name': "LogisticRegressionCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_NuSCV():
-    print("Testing sklearn, NuSCV...")
-    mod = svm.NuSVC()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "NuSCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_NuSVR():
-    print("Testing sklearn, NuSVR...")
-    mod = svm.NuSVR()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "NuSVR test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_OrthogonalMatchingPursuit():
-    print("Testing sklearn, OrthogonalMatchingPursuit...")
-    mod = linear_model.OrthogonalMatchingPursuit()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "OrthogonalMatchingPursuit test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_OrthogonalMatchingPursuitCV():
-    print("Testing sklearn, OrthogonalMatchingPursuitCV...")
-    mod = linear_model.OrthogonalMatchingPursuitCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "OrthogonalMatchingPursuitCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_PassiveAggressiveClassifier():
-    print("Testing sklearn, PassiveAggressiveClassifier...")
-    mod = linear_model.PassiveAggressiveClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "PassiveAggressiveClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_PassiveAggressiveRegressor():
-    print("Testing sklearn, PassiveAggressiveRegressor...")
-    mod = linear_model.PassiveAggressiveRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "PassiveAggressiveRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_Perceptron():
-    print("Testing sklearn, Perceptron...")
-    mod = linear_model.Perceptron()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "Perceptron test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_RandomForestClassifier():
-    print("Testing sklearn, RandomForestClassifier...")
-    mod = ensemble.RandomForestClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "RandomForestClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_RandomForestRegressor():
-    print("Testing sklearn, RandomForestRegressor...")
-    mod = ensemble.RandomForestRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "RandomForestRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_RANSACRegressor():
-    print("Testing sklearn, RANSACRegressor...")
-    mod = linear_model.RANSACRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "RANSACRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_Ridge():
-    print("Testing sklearn, Ridge...")
-    mod = linear_model.Ridge()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "Ridge test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-def test_sk_RidgeClassifier():
-    print("Testing sklearn, RidgeClassifier...")
-    mod = linear_model.RidgeClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "RidgeClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_RidgeClassifierCV():
-    print("Testing sklearn, RidgeClassifierCV...")
-    mod = linear_model.RidgeClassifierCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "RidgeClassifierCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_sk_RidgeCV():
-    mod = linear_model.RidgeCV()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "RidgeCV test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-    print("Tested sklearn, RidgeCV...")
-
-
-def test_sk_SGDClassifier():
-    mod = linear_model.SGDClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SGDClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-    print("Tested sklearn, SGDClassifier...")
-
-
-def test_sk_SGDRegressor():
-    mod = linear_model.SGDRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SGDRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-    print("Tested sklearn, SGDRegressor...")
-
-
-def test_sk_SVC():
-    mod = svm.SVC()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SVC test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-    print("Tested sklearn, SVC...")
-
-
-def test_sk_SVR():
-    mod = svm.SVR()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SVR test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-    print("Tested sklearn, SVR...")
-
-
-def test_sk_TheilSenRegressor():
-    mod = linear_model.TheilSenRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "TheilSenRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-    print("Tested sklearn, TheilSenRegressor...")
-
-
-# XGBoost package
-def test_xg_XGBClassifier():
-    print("Testing xgboost, XGBClassifier...")
-    mod = XGBClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "XGBClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_xg_XGBRegressor():
-    print("Testing xgboost, XGBRegressor...")
-    mod = XGBRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "XGBRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_xg_XGBRFClassifier():
-    print("Testing xgboost, XGBRFClassifier...")
-    # Note, only works with binary outcomes!
-    mod = XGBRFClassifier()
-    X, y = iris_data
-    ybin = np.where(y <= 1, 0, 1)
-    mod.fit(X, ybin)
-    docs = {'name': "XGBRFClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_xg_XGBRFRegressor():
-    print("Testing xgboost, XGBRFRegressor...")
-    mod = XGBRFRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "XGBRFRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-# lightgbm package
-def test_lgb_LGBMClassifier():
-    print("Testing lightgbm, LGBMClassifier...")
-    mod = lgb.LGBMClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LGBMClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_LGBMRegressor():
-    print("Testing lightgbm, LGBMRegressor...")
-    mod = lgb.LGBMRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "LGBMRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-# lightning
-def test_lgb_AdaGradClassifier():
-    print("Testing lightning, AdaGradClassifier...")
-    mod = lgb.AdaGradClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "AdaGradClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_AdaGradRegressor():
-    print("Testing lightning, AdaGradRegressor...")
-    mod = lgb.AdaGradRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "AdaGradRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_CDClassifier():
-    print("Testing lightning, CDClassifier...")
-    mod = lgb.CDClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "CDClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_CDRegressor():
-    print("Testing lightning, CDRegressor...")
-    mod = lgb.CDRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "CDRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_FistaClassifier():
-    print("Testing lightning, FistaClassifier...")
-    mod = lgb.FistaClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "FistaClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_FistaRegressor():
-    print("Testing lightning, FistaRegressor...")
-    mod = lgb.FistaRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "FistaRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-# lightning (not supported
-def test_lgb_KernelSVC():
-    print("Testing lightning, KernelSVC...")
-    mod = ln.KernelSVC()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "KernelSVC test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-def test_lgb_SAGAClassifier():
-    print("Testing lightning, SAGAClassifier...")
-    mod = lgb.SAGAClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SAGAClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_SAGARegressor():
-    print("Testing lightgbm, SAGARegressor...")
-    mod = lgb.SAGARegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SAGARegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_SAGClassifier():
-    print("Testing lightning, SAGClassifier...")
-    mod = lgb.SAGClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SAGClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_SAGRegressor():
-    print("Testing lightning, SAGRegressor...")
-    mod = lgb.SAGRegressor()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SAGRegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_SDCAClassifier():
-    print("Testing lightgbm, SDCAClassifier...")
-    mod = lgb.SDCAClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SDCAClassifier test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-def test_lgb_SDCARegressor():
-    print("Testing lightning, SDCARegressor...")
-    mod = lgb.SDCAClassifier()
-    X, y = iris_data
-    mod.fit(X, y)
-    docs = {'name': "SDCARegressor test"}
-    fv = X[0, :]
-    upload(mod, fv, docs)
-
-
-
-
-
-if __name__ == '__main__':
-
-    if not RUN_TESTS:
-        print("Not running tests.")
-        exit()
-
-    if not PRINTING:
-        stop_print()
-
-    if DEBUG:
-        _toggle_debug_mode()
-
-    # Remove:
-    # remove_credentials()
-
-    # Set correct endpoints
-    _set_toolchain_URL(TOOLCHAIN_URL)
-    _set_usermanager_URL(ADMIN_URL)
-
-    print("Running tests off all supported models. This might take some time")
-    print("===============================")
-
-    print("# Statsmodels:")
-    test_sm_GLS()
-    test_sm_GLSAR()
-    test_sm_OLS()
-    test_sm_QuantReg()
-    test_sm_WLS()
-
-    # time.sleep(SLEEPTIME)
-    print("# SciKit Learn:")
-    test_sk_ARDRegression()
-    test_sk_BayesianRidge()
-    test_sk_DecisionTreeClassifier()
-    test_sk_DecisionTreeRegressor()
-    test_sk_ElasticNet()
-
-    time.sleep(SLEEPTIME)
-    test_sk_ElasticNetCV()
-    test_sk_ExtraTreeClassifier()
-    test_sk_ExtraTreeRegressor()
-    test_sk_ExtraTreesClassifier()
-    test_sk_ExtraTreesRegressor()
-
-    time.sleep(SLEEPTIME)
-    test_sk_HuberRegressor()
-    test_sk_Lars()
-    test_sk_LarsCV()
-    test_sk_Lasso()
-    test_sk_LassoCV()
-
-    time.sleep(SLEEPTIME)
-    test_sk_LassoLars()
-    test_sk_LassoLarsCV()
-    test_sk_LassoLarsIC()
-    test_sk_LinearRegression()
-    test_sk_LinearSVC()
-
-    time.sleep(SLEEPTIME)
-    test_sk_LinearSVR()
-    test_sk_LogisticRegression()
-    test_sk_LogisticRegressionCV()
-    test_sk_NuSCV()
-    test_sk_NuSVR()
-    test_sk_OrthogonalMatchingPursuit()
-    test_sk_OrthogonalMatchingPursuitCV()
-
-    time.sleep(SLEEPTIME)
-    test_sk_PassiveAggressiveClassifier()
-    test_sk_PassiveAggressiveRegressor()
-    test_sk_Perceptron()
-    test_sk_RandomForestClassifier()
-    test_sk_RandomForestRegressor()
-    test_sk_RANSACRegressor()
-
-    time.sleep(SLEEPTIME)
-    test_sk_Ridge()
-    test_sk_RidgeCV()
-    test_sk_RidgeClassifier()
-    test_sk_RidgeClassifierCV()
-    test_sk_SGDClassifier()
-
-    time.sleep(SLEEPTIME)
-    test_sk_SGDRegressor()
-    test_sk_SVC()
-    test_sk_SVR()
-    test_sk_TheilSenRegressor()
-
-    time.sleep(SLEEPTIME)
-    print("# XGBoost:")
-    test_xg_XGBRegressor()
-    test_xg_XGBClassifier()
-    test_xg_XGBRFClassifier()
-    test_xg_XGBRFRegressor()
-
-    time.sleep(SLEEPTIME)
-    print("# lightgbm:")
-    test_lgb_LGBMClassifier()
-    test_lgb_LGBMRegressor()
-
-    if False:  # Lightning not supported.
-        time.sleep(SLEEPTIME)
-
-        # Add to supported_models.json
-        # "lightning": [
-        #     "AdaGradClassifier",
-        #     "AdaGradRegressor",
-        #     "CDClassifier",
-        #     "CDRegressor",
-        #     "FistaClassifier",
-        #     "FistaRegressor",
-        #     "KernelSVC",
-        #     "LGBMClassifier",
-        #     "LGBMRegressor",
-        #     "SAGAClassifier",
-        #     "SAGARegressor",
-        #     "SAGClassifier",
-        #     "SAGRegressor",
-        #     "SDCAClassifier",
-        #     "SDCARegressor"
-        # ]
-
-        print("# lightning:")
-        test_lgb_AdaGradClassifier()
-        test_lgb_AdaGradRegressor()
-        test_lgb_CDClassifier()
-        test_lgb_CDRegressor()
-        test_lgb_FistaClassifier()
-        test_lgb_FistaRegressor()
-        test_lgb_KernelSVC()
-        test_lgb_SAGAClassifier()
-        test_lgb_SAGARegressor()
-        test_lgb_SAGClassifier()
-        test_lgb_SAGRegressor()
-        test_lgb_SDCAClassifier()
-        test_lgb_SDCARegressor()
-
-
-    print("===============================")
-    print("All tests passed.")
-
-    if TEAR_DOWN:
-
-        while True:
-            query = input('Are you sure you would like to remove all endpoints? (y/n) ')
-            answ = query[0].lower()
-            if query == '' or not answ in ['y', 'n']:
-                print('Please answer with yes or no')
-            else:
-                break
-
-        if answ == 'y':
-            endpoints = endpoints()
-            # Loop with pause and remove...
-            for key in endpoints:
-                print('Delete: {}, cfid: {}.'.format(key['name'], key['cfid']))
-                delete_endpoint(key['cfid'])
-                time.sleep(.5)
-
-    print("===============================")
-    print("Done.")
diff --git a/test/test_bundle.py b/test/test_bundle.py
index d10628e..dcaf68f 100644
--- a/test/test_bundle.py
+++ b/test/test_bundle.py
@@ -4,9 +4,9 @@
 # Script settings:
 from sclblpy.main import _toggle_debug_mode, stop_print
 
-RUN_TESTS = False  # Prevent unintended testing
-DEBUG = False  # Set to debug mode; if true it will raise exceptions
-PRINTING = False  # Toggle printing on and off.
+RUN_TESTS = 1  # Prevent unintended testing
+DEBUG = 1  # Set to debug mode; if true it will raise exceptions
+PRINTING = 1  # Toggle printing on and off.
 
 def test_gzip_save():
     """Test gzip save. """
diff --git a/test/test_jwt.py b/test/test_jwt.py
index 3152ab7..eb31046 100644
--- a/test/test_jwt.py
+++ b/test/test_jwt.py
@@ -6,15 +6,15 @@
 from sclblpy.main import _toggle_debug_mode
 
 # Script settings:
-RUN_TESTS = False  # Prevent unintended testing
-DEBUG = False  # Set to debug mode; if true it will raise exceptions
-PRINTING = True  # Toggle printing on and off.
-ADMIN_URL = "http://localhost:8008"  # Location of admin for this test
-TOOLCHAIN_URL = "http://localhost:8010"  # Location of toolchain for this test
+RUN_TESTS = 1  # Prevent unintended testing
+DEBUG = 0  # Set to debug mode; if true it will raise exceptions
+PRINTING = 1  # Toggle printing on and off.
+ADMIN_URL = "https://usermanager.sclbl.net"  # Location of admin for this test
+TOOLCHAIN_URL = "https://toolchain.sclbl.net"  # Location of toolchain for this test
 
-# For the tests to pass we need a valid username and password:
-USERNAME = "maurits@mauritskaptein.com"
-PASSWORD = "test"
+# For the tests to pass we need a valid email and password:
+EMAIL = "email-here"
+PASSWORD = "password-here"
 
 
 def test_JWT():
@@ -39,19 +39,19 @@ def test_signin():
     """Test __signin() function"""
 
     # Try empty
-    username: str = ""
+    email: str = ""
     password: str = ""
-    assert _sign_in(username, password) is False, "This should not log in"
+    assert _sign_in(email, password) is False, "This should not log in"
 
     # Try invalid
-    username = "blabla@blabla.com"
+    email = "blabla@blabla.com"
     password = "not-a-valid-password"
-    assert _sign_in(username, password) is False, "This should not log in 2"
+    assert _sign_in(email, password) is False, "This should not log in 2"
 
     # Try valid
-    username = USERNAME
+    email = EMAIL
     password = PASSWORD
-    assert _sign_in(username, password) is True, "This should sign in (if the username and pass indeed exist)."
+    assert _sign_in(email, password) is True, "This should sign in (if the email and pass indeed exist)."
 
 
 def test_get_user_details():
diff --git a/test/test_main.py b/test/test_main.py
index 852d33f..f75dd75 100644
--- a/test/test_main.py
+++ b/test/test_main.py
@@ -1,91 +1,52 @@
-import os
 import time
 
-from sclblpy._bundle import _gzip_load, _gzip_delete
 from sclblpy._jwt import _get_user_details
-from sclblpy.main import remove_credentials, upload, endpoints, delete_endpoint, _set_toolchain_URL, \
-    _set_usermanager_URL, list_models, start_print, stop_print, _toggle_debug_mode, update, update_docs, run, \
+from sclblpy.main import remove_credentials, upload_onnx, endpoints, delete_endpoint, _set_toolchain_URL, \
+    _set_usermanager_URL, update_onnx, stop_print, _toggle_debug_mode, update_docs, run, \
     _set_taskmanager_URL, models, devices, delete_device, assignments, assign, delete_assignment, delete_model
 
-import sclblpy._globals as glob
 
-import numpy as np
-from sklearn import svm
-from sklearn import datasets
-
-# Script settings:
-RUN_TESTS = False  # Prevent unintended testing
+RUN_TESTS = True  # Prevent unintended testing
 DEBUG = True  # Set to debug mode; if true it will raise exceptions
 PRINTING = True  # Toggle printing on and off.
-ADMIN_URL = "http://localhost:8008"  # Location of admin for this test
-TOOLCHAIN_URL = "http://localhost:8010"  # Location of toolchain for this test
-TASKMANAGER_URL = "http://localhost:8080"
-
+ADMIN_URL = "https://usermanager.sclbl.net"  # Location of admin for this test
+TOOLCHAIN_URL = "https://toolchain.sclbl.net"  # Location of toolchain for this test
 
-def test_upload():
-    """ Test the upload function (sklearn and onnx"""
-
-    # Start fitting a simple model, no feature vecto
-    clf = svm.SVC()
-    X, y = datasets.load_iris(return_X_y=True)
-    clf.fit(X, y)
-    assert upload(clf, np.empty(0)) is False, "No valid feature vector."
 
+def test_upload_onnx():
+    """ Test the upload function (onnx)"""
     # Add docs
     docs = {}
-    docs['name'] = "Name of model"
-    docs['documentation'] = "A long .md thing...."
-    assert upload(clf, np.empty(0), docs=docs) is False, "No valid feature vector."
-
-    # Valid
-    row = X[130, :]
-    assert upload(clf, row, docs=docs) is True, "SKlearn upload test failed."
 
     # ONNX
     docs['name'] = "Name of ONNX model"
     docs['documentation'] = "A long .md thing...."
-    check = upload("../test/files/model.onnx", "", docs, model_type="onnx")
+    check = upload_onnx("../test/files/model.onnx", "", docs)
     assert check is True, "ONNX upload test failed."
 
 
 def test_update():
-    """ Test the update function (sklearn & onnx"""
-
-    # Start fitting a simple model, no feature vecto
-    clf = svm.SVC()
-    X, y = datasets.load_iris(return_X_y=True)
-    clf.fit(X, y)
+    """ Test the update function (onnx)"""
 
     # Add and feature vector
     docs = {}
     docs['name'] = "Name of model - UPDATED"
     docs['documentation'] = "A long .md thing.... UPDATED"
-    row = X[130, :]
 
     # Get an existing endpoint to update
-    try:
-        cfid = endpoints(_verbose=False, _return=True)[0]["cfid"]
-    except Exception as e:
-        print("No endpoint to overwrite found")
-        assert False is True, "No endpoint found for overwrite test."
-
-    print("Updating: " + cfid)
+    print(endpoints(_verbose=False, _return=True))
 
-    # Overwrite without docs
-    result = update(clf, row, cfid, docs={})
-    assert result is True, "Sklearn update failed."
-
-    # Get another endpoint to update
-    try:
-        cfid = endpoints(_verbose=False, _return=True)[1]["cfid"]
-    except Exception as e:
-        print("No endpoint to overwrite found 2")
-        assert False == True, "no endpoint found for overwrite test 2"
+    # try except is a bit unusual in a test (as any fail in e.g. endpoints or the indexing will lead to the same output)
+    #try:
+    cfid = endpoints(_verbose=False, _return=True)[0]["cfid"]
+    #except Exception as e:
+    #    print("No endpoint to overwrite found")
+    #    assert False is True, "No endpoint found for overwrite test."
 
     print("Updating: " + cfid)
 
     # Overwrite with valid docs:
-    result = update("../test/files/model.onnx", "", cfid, docs=docs, model_type="onnx")
+    result = update_onnx("../test/files/model.onnx", cfid=cfid,example="", docs=docs) #
     assert result is True, "ONNX update failed."
 
 
@@ -163,16 +124,6 @@ def test_endpoints_functions():
     if cfid:
         assert delete_endpoint(cfid) is True, "Should be able to delete an endpoint."
 
-    # delete model
-    ep = endpoints(_return=True)
-    try:
-        cfid = ep[0]['cfid']
-    except Exception as e:
-        # Effectively there was no model...
-        print("No endpoints to remove; test not run.")
-
-    if cfid:
-        assert delete_model(cfid) is True, "Should be able to delete a model."
 
 
 def test_devices_functions():
@@ -200,22 +151,7 @@ def test_devices_functions():
     assert (count2 == (count-1)) is True, "The deleted device count is not correct."
 
 
-# More obscure tests / please read docstrings and make sure settings are correct.
-def test_run():
-    """ Test running an endpoint
-    Note: Only works with valid existing cfid and compatible fv.
-    """
-    cfid = "e871d8e5-b2e2-11ea-a47d-9600004e79cc"
-
-    fv = [1, 2]
-
-    result = run(cfid, fv)
 
-    assert result is not False, "Error in running test; are the cfid and feature_vector ok?"
-    print(result)
-
-    if result['statusCode'] == 1:
-        print(result['result'])
 
 
 def test_remove_credentials():  # Also tested in JWT.
@@ -228,15 +164,8 @@ def test_setting_URLs():
     """ Test url setters: """
     _set_toolchain_URL(TOOLCHAIN_URL)
     _set_usermanager_URL(ADMIN_URL)
-    _set_taskmanager_URL(TASKMANAGER_URL)
 
 
-def test_user_utils():
-    start_print()
-    list_models()
-    stop_print()
-    list_models()
-    start_print()
 
 
 # Run tests
@@ -258,16 +187,31 @@ def test_user_utils():
     print("Running simple functional tests of main.py")
     print("===============================")
 
-    test_upload()  # upload sklearn and onnx test
+    test_upload_onnx()  # upload an onnx test
 
     print("Wait, toolchain needs to finish....")
-    time.sleep(10)
+    time.sleep(25)
+    print(" waited for 25 seconds")
 
-    test_update()  # update sklearn and onnx test
+    print('testing update \n\n')
+    test_update()  # update an onnx test
+    print('testing update docs \n\n')
     test_update_docs()  # update only docs test
+    print('testing assign functions \n\n')
     test_assign_functions()  # test creating and removing assignments
+
+
+    # The test below deletes the device registration, so it's commented out to keep the tests repeatable
+
+    print('testing endpoint functions \n\n')
+    print(endpoints(_return=True))
     test_endpoints_functions()  # test getting and deleting models
-    test_devices_functions()  # test device get and delete
+
+    #print('testing device functions \n\n')
+    #test_devices_functions()  # test device get and delete
+
+
+    ## MISSSING: REMOVE THE CREATED MODELS!!!
 
     # More obscure tests, not run by default / commented out
     #test_user_utils()
diff --git a/test/test_run.py b/test/test_run.py
deleted file mode 100644
index e23464f..0000000
--- a/test/test_run.py
+++ /dev/null
@@ -1,102 +0,0 @@
-from sclblpy import run
-from sclblonnx import sclbl_input
-import numpy as np
-from PIL import Image
-
-
-def test_run_inputs(_verbose=True):
-    """
-    Function testing in sp.run for various input options.
-
-    Models:
-    * Linear regression from sklearn
-        * cfid: e871d8e5-b2e2-11ea-a47d-9600004e79cc
-        * input: [[1,3]]
-
-    * XGBoost model:
-        * cfid: 007bdbaa-b093-11ea-a47d-9600004e79cc
-        * input: [[17.99, 10.38, 122.8, 1001.0, 0.1184, 0.2776, 0.3001, 0.1471, 0.2419, 0.07871, 1.095, 0.9053, 8.589, 153.4, 0.006399, 0.04904, 0.05373, 0.01587, 0.03003, 0.006193, 25.38, 17.33, 184.6, 2019.0, 0.1622, 0.6656, 0.7119, 0.2654, 0.4601, 0.1189]]
-
-    * Add model (from ONNX)
-        * cfid: 7c351fff-ad9c-11eb-af86-9600004e79cc
-        * {"input": ["CAEQAUoEmpmZPw==","CAEQAUoEAAAgQA=="], "type":"pb"}
-        * {"input": ["mpmZPw==","AAAgQA=="], "type":"raw"}
-
-    * Image empty check:
-        * cfid: 8e3a52c2-ad9c-11eb-af86-9600004e79cc
-        * Image from file  files/1.JPG
-
-    """
-
-    # Lin reg model
-    cfid = "e871d8e5-b2e2-11ea-a47d-9600004e79cc"
-    csv1 = [1, 2]
-    result = run(cfid, csv1)
-    assert result['statusCode'] == 1, "Lin reg example fails..."
-    if _verbose:
-        print(result['result'])
-
-    # XGBoost model
-    cfid = "007bdbaa-b093-11ea-a47d-9600004e79cc"
-    csv2 = [17.99, 10.38, 122.8, 1001.0, 0.1184, 0.2776, 0.3001, 0.1471, 0.2419, 0.07871, 1.095, 0.9053, 8.589, 153.4, 0.006399, 0.04904, 0.05373, 0.01587, 0.03003, 0.006193, 25.38, 17.33, 184.6, 2019.0, 0.1622, 0.6656, 0.7119, 0.2654, 0.4601, 0.1189]
-    result = run(cfid, csv2)
-    assert result['statusCode'] == 1, "XGBoots example fails..."
-    if _verbose:
-        print(result['result'])
-
-    # Add example (with pb and raw):
-    cfid = "7c351fff-ad9c-11eb-af86-9600004e79cc"
-    example = {"x1": np.array([1.2]).astype(np.float32), "x2": np.array([2.5]).astype(np.float32)}
-    pb1 = sclbl_input(example, "pb", False)
-    result = run(cfid, pb1)
-    assert result['statusCode'] == 1, "Add example w. pb example fails..."
-    if _verbose:
-        print(result['result'])
-
-    raw1 = sclbl_input(example, "raw", False)
-    result = run(cfid, raw1)
-    assert result['statusCode'] == 1, "Add example w. raw example fails..."
-    if _verbose:
-        print(result['result'])
-
-    # Image example:
-    cfid = "8e3a52c2-ad9c-11eb-af86-9600004e79cc"
-    img_data = np.array(Image.open("files/1.JPG"), dtype=np.int32)
-    example = {"in": img_data.astype(np.int32)}
-    pb = sclbl_input(example, _verbose=False)
-    result = run(cfid, pb)
-    assert result['statusCode'] == 1, "Add example w. pb example fails..."
-    if _verbose:
-        print(result['result'])
-
-    cfid = "8e3a52c2-ad9c-11eb-af86-9600004e79cc"
-    img_data = np.array(Image.open("files/3.JPG"), dtype=np.int32)
-    example = {"in": img_data.astype(np.int32)}
-    pb = sclbl_input(example, _verbose=False)
-    result = run(cfid, pb)
-    assert result['statusCode'] == 1, "Add example w. pb example fails..."
-    if _verbose:
-        print(result['result'])
-
-
-    # Image raw:
-    cfid = "8e3a52c2-ad9c-11eb-af86-9600004e79cc"
-    img_data = np.array(Image.open("files/1.JPG"), dtype=np.int32)
-    example = {"in": img_data.astype(np.int32)}
-    pb = sclbl_input(example, "raw", _verbose=False)
-    result = run(cfid, pb)
-    assert result['statusCode'] == 1, "Add example w. raw example fails..."
-    if _verbose:
-        print(result['result'])
-
-    cfid = "8e3a52c2-ad9c-11eb-af86-9600004e79cc"
-    img_data = np.array(Image.open("files/3.JPG"), dtype=np.int32)
-    example = {"in": img_data.astype(np.int32)}
-    pb = sclbl_input(example, "raw", _verbose=False)
-    result = run(cfid, pb)
-    assert result['statusCode'] == 1, "Add example w. raw example fails..."
-    if _verbose:
-        print(result['result'])
-
-
-test_run_inputs()
\ No newline at end of file
diff --git a/test/test_utils.py b/test/test_utils.py
index ac44795..2014a44 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -3,89 +3,14 @@
 # test_all_models.py.
 import sys
 
-from sclblpy._utils import _model_supported, _model_is_fitted, _get_system_info, _predict
+from sclblpy._utils import _get_system_info
 from sclblpy.main import _toggle_debug_mode, stop_print
 
-from sklearn import svm
-from sklearn import datasets
-from xgboost import XGBRegressor
-import numpy as np
-import statsmodels.api as sm
 
 # Script settings:
-RUN_TESTS = False  # Prevent unintended testing
-DEBUG = False  # Set to debug mode; if true it will raise exceptions
-PRINTING = True  # Toggle printing on and off.
-
-
-def test_supported_model():
-    """Check whether or not a model is supported."""
-
-    # First, try a sklearn svm:
-    clf = svm.SVC()
-    X, y = datasets.load_iris(return_X_y=True)
-    clf.fit(X, y)
-    assert _model_supported(clf) is True, "sklearn model should be supported."
-
-    # Try a statsmodels model:
-    nsample = 100
-    x = np.linspace(0, 10, nsample)
-    X = np.column_stack((x, x ** 2))
-    beta = np.array([1, 0.1, 10])
-    e = np.random.normal(size=nsample)
-    X = sm.add_constant(X)
-    y = np.dot(X, beta) + e
-    est = sm.OLS(y, X)
-    mod = est.fit()  # Robin wants the result object
-    assert _model_supported(mod) is True, "statsmodel model should be supported."
-
-    # Empty model
-    mod = {}
-    assert _model_supported(mod) is False, "Empty model should not be supported."
-
-    # XG boost model:
-    xgb = XGBRegressor()
-    assert _model_supported(xgb) is True, "xgboost model should be supported."
-
-
-def test_model_is_fitted():
-    """ Test model is fitted() function """
-    clf = svm.SVC()
-    X, y = datasets.load_iris(return_X_y=True)
-    assert _model_is_fitted(clf) is False, "Should not be fitted."
-    clf.fit(X, y)
-    assert _model_is_fitted(clf) is True, "Should be fitted."
-
-    est = sm.OLS(y, X)
-    assert _model_is_fitted(est) is False, "Should not be fitted."
-    mod = est.fit()
-    assert _model_is_fitted(mod) is True, "Should be fitted."
-
-    # XG boost model:
-    xgb = XGBRegressor()
-    assert _model_is_fitted(xgb) is False, "Model should not be fitted"
-    xgb.fit(X, y)
-    assert _model_is_fitted(xgb) is True, "This one should be fitted"
-
-
-def test_predict():
-
-    # sklearn
-    clf = svm.SVC()
-    X, y = datasets.load_iris(return_X_y=True)
-    clf.fit(X, y)
-    assert _predict(clf, X[0, :]) == [0], "Wrong sklearn prediction"
-
-    # statsmodels
-    est = sm.OLS(y, X)
-    mod = est.fit()
-    assert _predict(mod, X[0, :]) == [-0.07861540851180868], "Wrong statsmodels prediction"
-
-    # xgboost
-    xgb = XGBRegressor()
-    xgb.fit(X, y)
-    assert _predict(xgb, X[0, :]) == [1.1295080184936523e-05], "Wrong XGB prediction"
-
+RUN_TESTS = 1  # Prevent unintended testing
+DEBUG = 1  # Set to debug mode; if true it will raise exceptions
+PRINTING = 1  # Toggle printing on and off.
 
 def test_get_system_info():
     """ Test get system info """
@@ -108,10 +33,7 @@ def test_get_system_info():
     print("Running tests of _utils.py")
     print("===============================")
 
-    test_supported_model()
-    test_model_is_fitted()
     test_get_system_info()
-    test_predict()
 
     print("===============================")
     print("All tests passed.")