diff --git a/.aicoe-ci.yaml b/.aicoe-ci.yaml index a9be8bb..62f7b84 100644 --- a/.aicoe-ci.yaml +++ b/.aicoe-ci.yaml @@ -1,14 +1,9 @@ -# Setup and configuring aicoe-ci with configuration file `.aicoe-ci.yaml` -# Example `.aicoe-ci.yaml` with a full list of config options is available here: https://github.com/AICoE/aicoe-ci/blob/master/docs/.aicoe-ci.yaml check: - # Uncomment following line to build a public image of this repo - # - thoth-build -# Uncomment following lines to build a public image of this repo -# build: -# build-stratergy: Source -# build-source-script: "image:///opt/app-root/builder" -# base-image: quay.io/thoth-station/s2i-custom-notebook:latest -# registry: quay.io -# registry-org: aicoe -# registry-project: -# registry-secret: aicoe-pusher-secret + - thoth-build +build: + base-image: "quay.io/thoth-station/s2i-thoth-ubi8-py38:v0.28.0" + build-stratergy: Source + registry: quay.io + registry-org: thoth-station + registry-project: manage-dependencies-tutorial + registry-secret: thoth-station-thoth-pusher-secret diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1bfbf45..5d1ab21 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,7 @@ repos: - id: check-merge-conflict - id: end-of-file-fixer - id: name-tests-test + - id: check-added-large-files - id: check-byte-order-marker - id: check-case-conflict - id: check-docstring-first @@ -34,29 +35,16 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.902 - hooks: - - id: mypy - exclude: '^(docs|tasks|tests)|setup\.py' - args: [--ignore-missing-imports] - - repo: https://github.com/psf/black rev: 21.6b0 hooks: - id: black - repo: https://github.com/tomcatling/black-nb - rev: '0.5.0' + rev: "0.5.0" hooks: - id: black-nb - # Enable this in repositories with python packages. - # - repo: https://github.com/mgedmin/check-manifest - # rev: '0.39' - # hooks: - # - id: check-manifest - - repo: https://github.com/s-weigand/flake8-nb rev: v0.3.0 hooks: diff --git a/.prow.yaml b/.prow.yaml index 77dad25..eacb206 100644 --- a/.prow.yaml +++ b/.prow.yaml @@ -18,3 +18,23 @@ presubmits: limits: memory: "1Gi" cpu: "500m" + + - name: thoth-mypy-py38 + decorate: true + skip_report: false + always_run: true + context: aicoe-ci/prow/mypy + spec: + containers: + - image: quay.io/thoth-station/thoth-pytest-ubi8-py38:v0.12.5 + command: + - "/usr/local/bin/mypy" + - "." + - "--ignore-missing-imports" + resources: + requests: + memory: "1Gi" + cpu: "300m" + limits: + memory: "2Gi" + cpu: "500m" diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..b5846df --- /dev/null +++ b/Pipfile @@ -0,0 +1,11 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..e42812c --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,20 @@ +{ + "_meta": { + "hash": { + "sha256": "7f7606f08e0544d8d012ef4d097dabdd6df6843a28793eb6551245d4b2db4242" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": {}, + "develop": {} +} diff --git a/README.md b/README.md index 903fef1..cd783fa 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,79 @@ -project-template -============================== - -template for the team to use - -Project Organization ------------- - - ├── LICENSE - ├── Makefile <- Makefile with commands like `make data` or `make train` - ├── Pipfile <- Pipfile stating package configuration as used by Pipenv. - ├── Pipfile.lock <- Pipfile.lock stating a pinned down software stack with as used by Pipenv. - ├── README.md <- The top-level README for developers using this project. - ├── data - │   ├── external <- Data from third party sources. - │   ├── interim <- Intermediate data that has been transformed. - │   ├── processed <- The final, canonical data sets for modeling. - │   └── raw <- The original, immutable data dump. - │ - ├── docs <- A default Sphinx project; see sphinx-doc.org for details - │ - ├── models <- Trained and serialized models, model predictions, or model summaries - │ - ├── notebooks <- Jupyter notebooks. Naming convention is a number (for ordering), - │ the creator's initials, and a short `-` delimited description, e.g. - │ `1.0-jqp-initial-data-exploration`. - │ - ├── references <- Data dictionaries, manuals, and all other explanatory materials. - │ - ├── reports <- Generated analysis as HTML, PDF, LaTeX, etc. - │   └── figures <- Generated graphics and figures to be used in reporting - │ - ├── requirements.txt <- The requirements file stating direct dependencies if a library - │ is developed. - │ - ├── setup.py <- makes project pip installable (pip install -e .) so src can be imported - ├── src <- Source code for use in this project. - │   ├── __init__.py <- Makes src a Python module - │ │ - │   ├── data <- Scripts to download or generate data - │   │   └── make_dataset.py - │ │ - │   ├── features <- Scripts to turn raw data into features for modeling - │   │   └── build_features.py - │ │ - │   ├── models <- Scripts to train models and then use trained models to make - │ │ │ predictions - │   │   ├── predict_model.py - │   │   └── train_model.py - │ │ - │   └── visualization <- Scripts to create exploratory and results oriented visualizations - │   └── visualize.py - │ - ├── .thoth.yaml <- Thoth's configuration file - ├── .aicoe-ci.yaml <- AICoE CI configuration file (https://github.com/AICoE/aicoe-ci) - └── tox.ini <- tox file with settings for running tox; see tox.readthedocs.io - - --------- - -

Project based on the cookiecutter data science project template. #cookiecutterdatascience

+# Thoth Tutorial - manage your dependencies in Jupyter notebooks. + +This tutorial is used to show how to manage dependencies for Jupyter Notebooks using Python to allow reproducibility and shareability. + +Even though many developers (including data scientists) focus on their core problems when working on their experiments, there is one aspect that can make these projects not reusable. +One of the first steps during the development of a project is the `selection of libraries or dependencies`. When someone runs `pip install `, they might not be aware that along with the library that is going to be installed, a direct dependency, many other dependencies will be installed on your machine, so called transitive dependencies. Any change in one of those dependencies can break your experiment. It's fundamental to have a way to state all the dependencies used, including the operating system, python interpreter and hardware that was used to run a certain experiment. + +Dependency management is one of the most important requirements for reproducibility. Having dependencies clearly stated allows portability of notebooks, so they can be shared safely with others, reused in other projects or simply reproduced. If you want to know more about this issue in the data science domain, have a look at this [article](https://developers.redhat.com/blog/2021/03/19/managing-python-dependencies-with-the-thoth-jupyterlab-extension/) or this [video](https://www.youtube.com/watch?v=ifyQ2oSxjnU). + +[Project Thoth][1] keeps dependencies up to date by giving recommendations through developer's daily tools. Thanks to this service, developers (including data scientists) do not have to worry about managing the dependencies after they are selected, since conflicts can be handled by Thoth bots and automated pipelines. Having this AI support can benefit AI projects, offering improvements such as performance improvements due to optimized dependencies and additional security since insecure libraries cannot be introduced. If you want to know more, have a look at [Thoth's website](https://thoth-station.ninja/docs/developers/adviser/integration.html). + +Within the different Thoth integations, in this tutorial we are going to focus on the JupyterLab extension for dependency management, which is called [jupyterlab-requirements][2]. + +You can use this extension for each of your notebooks to guarantee they have the correct dependencies. This extension is able to add/remove dependencies, lock them and store them in the notebook metadata. In this way, all the dependencies information required to repeat the environment are shipped with the notebook. + +In particular, the following notebook metadata is created for you, when you use Thoth's dependency management tool: + +- `requirements` (Pipfile); + +- `requirements locked` with all versions and hashes of libraries (direct and transitive ones) (Pipfile.lock); + +- `dependency resolution engine` used (Thoth or Pipenv); + +- `configuration file containing runtime environment` (only for Thoth resolution engine). + +All this information can allow reproducibility and shareability of the notebook. + + +## What you will learn with this tutorial? + +At the end of this tutorial you will be able to manage dependencies for your projects in Jupyter Notebooks, enabling others to reproduce what you did and allowing them to contribute to it. The last section will teach also how to enable [Kebechet Bot][5] to keep dependencies automatically up to date for you and how you can setup and use automatic pipelines from [AICoE CI][6] to create release and images of your projects that you can easily share with others. + + +## Where you will run this tutorial? + +[Operate First][1] is an open infrastructure environment started at Red Hat's Office of the CTO. It has been selected to run this tutorial since it is an open source initiative that fulfills all the requirements stated above. Anyone with a Google account can log in and start developing. To learn more about Operate First, visit the [website](https://www.operate-first.cloud/) or [GitHub community](https://github.com/operate-first). + +[Operate First][1] hosts [Open Data Hub][3] with all the tools provided for Data Science projects (e.g. JupyterHub, Elyra, Kubeflow Pipelines, Seldon, Prometheus, Grafana, Superset) running on [Red Hat Openshift][4]. + + +## Why does the tutorial repository have this structure? + +The project template used can be found here: [project template][7]. It shows correlation between a data scientist needs (e.g. data, notebooks, models) and that of an AI DevOps engineer (e.g. manifests). Having structure in a project ensures all the pieces required for the ML and DevOps lifecycles are present and easily discoverable. + + +## Tutorial pre-requisites + +0. [Pre-requisites](./docs/pre-requisite.md) + +## Tutorial Steps + +1. [Setup your initial environment](./docs/setup-initial-environment.md) + +2. [Manage dependencies for your notebook](./docs/start-notebook-and-manage-dependencies.md) + +3. [Push changes to GitHub](./docs/push-changes.md) + +4. [Setup bots and pipelines to create releases, build images and enable automatic dependency management](./docs/thoth-aicoe-services.md) + +5. [Share your work](./docs/share-your-work.md) + + +## References + +* [Project Thoth][1] +* [jupyterlab-requirements][2] +* [Open Data Hub][3] +* [Red Hat Openshift][4] +* [Kebechet Bot][5] +* [AICoE CI][6] +* [project template][7] + +[1]: https://thoth-station.ninja/ +[2]: https://github.com/thoth-station/jupyterlab-requirements +[3]: https://opendatahub.io/ +[4]: https://www.openshift.com/ +[5]: https://github.com/marketplace/khebhut +[6]: https://github.com/AICoE/aicoe-ci +[7]: https://github.com/aicoe-aiops/project-template diff --git a/docs/images/JupyterHubNewUI.png b/docs/images/JupyterHubNewUI.png new file mode 100644 index 0000000..0707a0a Binary files /dev/null and b/docs/images/JupyterHubNewUI.png differ diff --git a/docs/images/JupyterLabCloneYourRepo.png b/docs/images/JupyterLabCloneYourRepo.png new file mode 100644 index 0000000..720be0a Binary files /dev/null and b/docs/images/JupyterLabCloneYourRepo.png differ diff --git a/docs/images/JupyterLabGitBoxPanel.png b/docs/images/JupyterLabGitBoxPanel.png new file mode 100644 index 0000000..139ccc9 Binary files /dev/null and b/docs/images/JupyterLabGitBoxPanel.png differ diff --git a/docs/images/JupyterLabGitCommitChanges.png b/docs/images/JupyterLabGitCommitChanges.png new file mode 100644 index 0000000..ee94a41 Binary files /dev/null and b/docs/images/JupyterLabGitCommitChanges.png differ diff --git a/docs/images/JupyterLabGitExtension.png b/docs/images/JupyterLabGitExtension.png new file mode 100644 index 0000000..93abb84 Binary files /dev/null and b/docs/images/JupyterLabGitExtension.png differ diff --git a/docs/images/JupyterLabGitInsertUserNameEmail.png b/docs/images/JupyterLabGitInsertUserNameEmail.png new file mode 100644 index 0000000..14d3f92 Binary files /dev/null and b/docs/images/JupyterLabGitInsertUserNameEmail.png differ diff --git a/docs/images/JupyterLabGitPush.png b/docs/images/JupyterLabGitPush.png new file mode 100644 index 0000000..6c4e06a Binary files /dev/null and b/docs/images/JupyterLabGitPush.png differ diff --git a/docs/images/JupyterLabGitStageFiles.png b/docs/images/JupyterLabGitStageFiles.png new file mode 100644 index 0000000..450d470 Binary files /dev/null and b/docs/images/JupyterLabGitStageFiles.png differ diff --git a/docs/images/JupyterLabGitUseButtonToPushChanges.png b/docs/images/JupyterLabGitUseButtonToPushChanges.png new file mode 100644 index 0000000..0bce666 Binary files /dev/null and b/docs/images/JupyterLabGitUseButtonToPushChanges.png differ diff --git a/docs/images/JupyterLabHorusAdd.png b/docs/images/JupyterLabHorusAdd.png new file mode 100644 index 0000000..a2d85f8 Binary files /dev/null and b/docs/images/JupyterLabHorusAdd.png differ diff --git a/docs/images/JupyterLabHorusCheckAfterDiscover.png b/docs/images/JupyterLabHorusCheckAfterDiscover.png new file mode 100644 index 0000000..5fc7069 Binary files /dev/null and b/docs/images/JupyterLabHorusCheckAfterDiscover.png differ diff --git a/docs/images/JupyterLabHorusCheckInitial.png b/docs/images/JupyterLabHorusCheckInitial.png new file mode 100644 index 0000000..06c7a69 Binary files /dev/null and b/docs/images/JupyterLabHorusCheckInitial.png differ diff --git a/docs/images/JupyterLabHorusCheckInitialDiscover.png b/docs/images/JupyterLabHorusCheckInitialDiscover.png new file mode 100644 index 0000000..ad64da8 Binary files /dev/null and b/docs/images/JupyterLabHorusCheckInitialDiscover.png differ diff --git a/docs/images/JupyterLabHorusCheckInitialPip.png b/docs/images/JupyterLabHorusCheckInitialPip.png new file mode 100644 index 0000000..825dc6c Binary files /dev/null and b/docs/images/JupyterLabHorusCheckInitialPip.png differ diff --git a/docs/images/JupyterLabHorusClean.png b/docs/images/JupyterLabHorusClean.png new file mode 100644 index 0000000..e260d84 Binary files /dev/null and b/docs/images/JupyterLabHorusClean.png differ diff --git a/docs/images/JupyterLabHorusShowAfterAdd.png b/docs/images/JupyterLabHorusShowAfterAdd.png new file mode 100644 index 0000000..697f8dd Binary files /dev/null and b/docs/images/JupyterLabHorusShowAfterAdd.png differ diff --git a/docs/images/JupyterLabOpenTerminal.png b/docs/images/JupyterLabOpenTerminal.png new file mode 100644 index 0000000..f2ba850 Binary files /dev/null and b/docs/images/JupyterLabOpenTerminal.png differ diff --git a/docs/images/JupyterLabRequirementsExtension.jpg b/docs/images/JupyterLabRequirementsExtension.jpg new file mode 100644 index 0000000..d37f863 Binary files /dev/null and b/docs/images/JupyterLabRequirementsExtension.jpg differ diff --git a/docs/images/JupyterLabRequirementsExtensionCLI.png b/docs/images/JupyterLabRequirementsExtensionCLI.png new file mode 100644 index 0000000..4e3f845 Binary files /dev/null and b/docs/images/JupyterLabRequirementsExtensionCLI.png differ diff --git a/docs/images/JupyterLabRequirementsExtensionMC.png b/docs/images/JupyterLabRequirementsExtensionMC.png new file mode 100644 index 0000000..e2eac0f Binary files /dev/null and b/docs/images/JupyterLabRequirementsExtensionMC.png differ diff --git a/docs/images/JupyterLabStartExistingNotebook.png b/docs/images/JupyterLabStartExistingNotebook.png new file mode 100644 index 0000000..59e0a90 Binary files /dev/null and b/docs/images/JupyterLabStartExistingNotebook.png differ diff --git a/docs/images/JupyterLabStartExistingNotebookPip.png b/docs/images/JupyterLabStartExistingNotebookPip.png new file mode 100644 index 0000000..77ca750 Binary files /dev/null and b/docs/images/JupyterLabStartExistingNotebookPip.png differ diff --git a/docs/images/JupyterLabStartExistingNotebookPipWarning.png b/docs/images/JupyterLabStartExistingNotebookPipWarning.png new file mode 100644 index 0000000..5c47ff6 Binary files /dev/null and b/docs/images/JupyterLabStartExistingNotebookPipWarning.png differ diff --git a/docs/images/JupyterLabStartNewNotebook.png b/docs/images/JupyterLabStartNewNotebook.png new file mode 100644 index 0000000..59733df Binary files /dev/null and b/docs/images/JupyterLabStartNewNotebook.png differ diff --git a/docs/images/JupyterLabTerminalFirstCommit.png b/docs/images/JupyterLabTerminalFirstCommit.png new file mode 100644 index 0000000..4b7d2a2 Binary files /dev/null and b/docs/images/JupyterLabTerminalFirstCommit.png differ diff --git a/docs/images/JupyterLabUseTerminal.png b/docs/images/JupyterLabUseTerminal.png new file mode 100644 index 0000000..d77c91d Binary files /dev/null and b/docs/images/JupyterLabUseTerminal.png differ diff --git a/docs/images/KhebutAutomaticUpdate.png b/docs/images/KhebutAutomaticUpdate.png new file mode 100644 index 0000000..48d5e17 Binary files /dev/null and b/docs/images/KhebutAutomaticUpdate.png differ diff --git a/docs/images/KhebutOpenIssueRelease.png b/docs/images/KhebutOpenIssueRelease.png new file mode 100644 index 0000000..4aac7a4 Binary files /dev/null and b/docs/images/KhebutOpenIssueRelease.png differ diff --git a/docs/images/KhebutPullRequestRelease.png b/docs/images/KhebutPullRequestRelease.png new file mode 100644 index 0000000..77ea4d2 Binary files /dev/null and b/docs/images/KhebutPullRequestRelease.png differ diff --git a/docs/images/QuayAddRobotPermissionsRepository.png b/docs/images/QuayAddRobotPermissionsRepository.png new file mode 100644 index 0000000..d70a1a3 Binary files /dev/null and b/docs/images/QuayAddRobotPermissionsRepository.png differ diff --git a/docs/images/QuayCreateNewRepository.png b/docs/images/QuayCreateNewRepository.png new file mode 100644 index 0000000..490c68c Binary files /dev/null and b/docs/images/QuayCreateNewRepository.png differ diff --git a/docs/images/QuayImageRegistry.png b/docs/images/QuayImageRegistry.png new file mode 100644 index 0000000..2928093 Binary files /dev/null and b/docs/images/QuayImageRegistry.png differ diff --git a/docs/images/QuayRepositorySettings.png b/docs/images/QuayRepositorySettings.png new file mode 100644 index 0000000..098c35c Binary files /dev/null and b/docs/images/QuayRepositorySettings.png differ diff --git a/docs/images/QuaySetPublicRepository.png b/docs/images/QuaySetPublicRepository.png new file mode 100644 index 0000000..02d9b97 Binary files /dev/null and b/docs/images/QuaySetPublicRepository.png differ diff --git a/docs/images/QuaySetRobotAccountRepository.png b/docs/images/QuaySetRobotAccountRepository.png new file mode 100644 index 0000000..1dfe150 Binary files /dev/null and b/docs/images/QuaySetRobotAccountRepository.png differ diff --git a/docs/images/QuaySetRobotPermissionsWriteRepository.png b/docs/images/QuaySetRobotPermissionsWriteRepository.png new file mode 100644 index 0000000..67e863a Binary files /dev/null and b/docs/images/QuaySetRobotPermissionsWriteRepository.png differ diff --git a/docs/images/SeshetaEnableForkIssues.png b/docs/images/SeshetaEnableForkIssues.png new file mode 100644 index 0000000..9e775e1 Binary files /dev/null and b/docs/images/SeshetaEnableForkIssues.png differ diff --git a/docs/images/SeshetaInvite.png b/docs/images/SeshetaInvite.png new file mode 100644 index 0000000..0c672c0 Binary files /dev/null and b/docs/images/SeshetaInvite.png differ diff --git a/docs/images/TakeLinkForkedRepo.png b/docs/images/TakeLinkForkedRepo.png new file mode 100644 index 0000000..52d6dcc Binary files /dev/null and b/docs/images/TakeLinkForkedRepo.png differ diff --git a/docs/pre-requisite.md b/docs/pre-requisite.md new file mode 100644 index 0000000..9699587 --- /dev/null +++ b/docs/pre-requisite.md @@ -0,0 +1,37 @@ +# Pre-requisites + +In this section, the user can find the requirements needed for the tutorial: + +- GitHub account +- GitHub token +- JupyterLab environment with [jupyterlab-requirements][1] library +- [Open Data Hub][3] +- [Red Hat Openshift][5] + + +## GitHub account + +The project is based on GitHub, if you don't have one just following this [link](https://docs.github.com/en/github/getting-started-with-github/signing-up-for-a-new-github-account). + +## GitHub token + +If you don't have a GitHub token, you can create one following GitHub docs: [create GitHub token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token). + +## Operate first environment + +In [Operate First][2] you can find all components of [Open Data Hub][3], including [JupyterHub][4] to spawn images running on [Red Hat Openshift][5]. For this tutorial you can select the image called [Experimental Elyra Notebook Image](https://github.com/operate-first/apps/blob/master/kfdefs/base/jupyterhub/notebook-images/experimental-elyra-notebook-imagestream.yaml), which has the library for dependency management already installed. + + +## References + +* [jupyterlab-requirements][1] +* [Operate First][2] +* [Open Data Hub][3] +* [JupyterHub][4] +* [Red Hat Openshift][5] + +[1]: https://github.com/thoth-station/jupyterlab-requirements +[2]: https://www.operate-first.cloud/ +[3]: https://opendatahub.io/ +[4]: https://jupyter.org/hub +[5]: https://www.openshift.com/ diff --git a/docs/push-changes.md b/docs/push-changes.md new file mode 100644 index 0000000..d0b8ac2 --- /dev/null +++ b/docs/push-changes.md @@ -0,0 +1,87 @@ +# Push your changes on your GitHub repo + +This section will show how you can push your changes to your GitHub repo directly from the [Jupyterlab Git extension][1]. +The only thing you need is a GitHub token. You can create one following GitHub docs: [create GitHub token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token). + +## Push your changes using JupyterLab Git extension + +If you are running this tutorial on Operate First your work-in-progress notebooks can be saved in your JupyterHub PVC by hitting the save button on the top panel. +Nevertheless, it is a good practice to push your changes to the GitHub repo when you finish working on your project, so that all your work can be saved. + +In order to do that from within JupyterLab using the [Jupyterlab Git extension][1]: + +1. Go to Git Box panel on the left to check what files have been changed. + +
+ Go to Git Box Panel +
+ +2. Stage the files you want to push to your GitHub repo. + +
+ Stage the files +
+ +3. Add Summary of your changes (a.k.a commit message) and select Commit. + +
+ Commit Changes +
+ + NOTE: _If you are doing this for the first time, git requires user email and user name to be set.(The extension will open a Dialog Form to insert them)_ + +
+ Insert User Name and Email +
+ + +4. Select Push Changes. + +
+ Use Button to Push Changes +
+ +5. Insert your Github account name and your GitHub token to push to the GitHub repo you cloned. + +
+ Push Changes with GitHub token +
+ +## Push your changes using the terminal in JupyterLab + +If you want to clone a repo and push changes through the Terminal, you can use the following steps. + +1. Open terminal from the icon in the Launcher. + +
+ Open Terminal +
+ +2. Start using the git commands: + +
+ Use Git Commands +
+ +- `git clone ` to clone a new repo. + +- `git add ` after you modify files to put them in stage. + +- `git commit -m ""` to commit the changes in stage. _NOTE: If you are doing this for the first time, git requires user email and user name to be set._ + +
+ First commit +
+ +- `git push origin ` to push your changes. + + +## Next Step + +[Set bots and pipelines to enable automatic dependency management and automatic build after release](./thoth-aicoe-services.md) + +## References + +* [Jupyterlab Git extension][1] + +[1]: https://github.com/jupyterlab/jupyterlab-git diff --git a/docs/setup-initial-environment.md b/docs/setup-initial-environment.md new file mode 100644 index 0000000..d3f8568 --- /dev/null +++ b/docs/setup-initial-environment.md @@ -0,0 +1,64 @@ +# Setup initial environment + +The environment that will be used for this tutorial is an open environment with open source technologies running on [Red Hat Openshift][1] on an open infrastructure with an open community that allow developers and operators to collaborate and learn from each other, called [Operate First][2]. +[Operate First][2] hosts [Open Data Hub][3] with all the tools provided for Data Science projects (e.g. JupyterHub, Elyra, Kubeflow Pipelines, Seldon, Prometheus, Grafana, Superset) running on [Red Hat Openshift][1]. + +## 1. Fork this repo from GitHub + +To begin, you'll need to fork this repository to create your own copy. If you're unsure how, look at [Fork a Repo](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) from GitHub docs. + + +## 2. Access the Elyra image in JupyterHub + +In order to access the [JupyterHub][4] from [Open Data Hub][3] deployed on the [Operate First][2] cluster: + +1. Click this [link](https://jupyterhub-opf-jupyterhub.apps.zero.massopen.cloud/) to visit the Operate First JupyterHub. + +
+ Jupyter Hub UI +
+ +2. Select the image called `Experimental Elyra Notebook Image` from the JupyterHub spawner. + +3. Select `Large` for container size. + + +## 3. Clone your repo using Jupyterlab Git Extension + +Once your image is ready and you are in the Jupyterlab UI, you can use the Git extension provided to clone this repo. + +1. Click the Git extension button from Jupyterlab UI: + +
+ Look for Git extension button +
+ +2. Take HTTPS link of the GitHub repo you want to clone, for this tutorial use your forked one from this repo: + +
+ Take link from forked repo +
+ +3. Insert the link taken from your forked repo in the JupyterLab Git Extension: e.g. `https://github.com/AICoE/manage-dependencies-tutorial.git` + +
+ Clone your repo +
+ + +## Next Step + +[Manage dependencies for your notebook](./start-notebook-and-manage-dependencies.md) + + +## References + +* [Red Hat Openshift][1] +* [Operate First][2] +* [Open Data Hub][3] +* [JupyterHub][4] + +[1]: https://www.openshift.com/ +[2]: https://www.operate-first.cloud/ +[3]: https://opendatahub.io/ +[4]: https://jupyter.org/hub diff --git a/docs/share-your-work.md b/docs/share-your-work.md new file mode 100644 index 0000000..9453f86 --- /dev/null +++ b/docs/share-your-work.md @@ -0,0 +1,31 @@ +# Share your work + +At this step of the tutorial you learned how to work on your project safely, supported by bots and pipelines that make automatic release for you and maintain the dependencies in your project. This last step of the tutorial will show you how you can share snapshots of your project, not only through container images but allowing others to repeat your experiments and interact with it by using [Project Meteor][1]. + +# Project Meteor + +[Project Meteor][1] is a combined effort across the AICoE team at Red Hat, to provide a single tool for data scientists and other users where they can interact with, explore and leverage all of our services, tools and technologies for developing intelligent applications. Project Meteor is deployed on [Operate First][2] and you can use it following this [link](http://meteor-shower-aicoe-meteor.apps.zero.massopen.cloud/) + + +1. Enter the URL to your Git repository in [Project Meteor][1]. + +
+Enter URL Project Meteor +
+ +[Project Meteor][1] on the background will create two images for you: + +- JupyterBook where you can view easily shareable, and rendered high-quality static content from experiment. + +- A live JupyterLab environment where you can interact with your project and run your experiments. + +Now you are all set and ready to show your project to others. + + +## References + +* [Project Meteor][1] +* [Operate First][2] + +[1]: https://github.com/AICoE/meteor +[2]: https://www.operate-first.cloud/ diff --git a/docs/start-notebook-and-manage-dependencies.md b/docs/start-notebook-and-manage-dependencies.md new file mode 100644 index 0000000..92a144a --- /dev/null +++ b/docs/start-notebook-and-manage-dependencies.md @@ -0,0 +1,229 @@ +# Reproducibility of Jupyter Notebooks + +Reproducibility and shareability of notebooks is very important if you want to allow others to repeat your experiments and avoid issues due to dependencies management. +When using `pip install ` is not possible to verify which software stack was used to run the notebook and therefore another user cannot repeat the same experiment. +Dependency management is one of the most important requirements for reproducibility. Having dependencies clearly stated allows portability of notebooks, so they can be shared safely with others, reused in other projects or simply reproduced. If you want to know more about this issue in the data science domain, have a look at this [article](https://developers.redhat.com/blog/2021/03/19/managing-python-dependencies-with-the-thoth-jupyterlab-extension/) or this [video](https://www.youtube.com/watch?v=ifyQ2oSxjnU). + +In order to help developers (including data scientists), dependencies for Jupyter notebooks in this tutorial are managed using the JupyterLab extension [jupyterlab-requirements][1]. + +You can use this extension for each of your notebook to guarantee they have the correct dependencies. This extension is able to add/remove dependencies, lock them and store them in the notebook metadata. In this way all the dependencies information required to repeat the environment are shipped with the notebook. + +In particular, the following notebook metadata is created for you, when you use Thoth's dependency management tool: + +- `requirements (Pipfile)`; + +- `requirements lock with all versions and hashes (Pipfile.lock)`; + +- `dependency resolution engine` used (Thoth or Pipenv); + +- `.thoth.yaml configuration file` (only for Thoth resolution engine). + +All this information can allow reproducibility and shareability of the notebook. + + +## Manage dependencies with the jupyterlab-requirements extension + +There are 3 ways to interact with [jupyterlab-requirements][1] JupyterLab extension: + +- using `%horus` magic commands directly in your notebook's cells (preferred approach). To learn more about how to use the `%horus` magic commands check out the guide [here](https://github.com/thoth-station/jupyterlab-requirements#horus-magic-command) or the video [here](https://www.youtube.com/watch?v=FjVxNTXO70I) + +
+JupyterLab Requirements Horus magic commands +
+ +- using the `horus` CLI directly from terminal or integrated in pipelines (check the [video](https://www.youtube.com/watch?v=fW0YKugL26g&t) or this [link](https://github.com/thoth-station/jupyterlab-requirements#horus-jupyterlab-requirements-cli) if you want to know more about it). + +
+JupyterLab Requirements Horus CLI +
+ +- using the `Manage Dependencies` button that appears in the notebook when it is opened (check the [link](https://github.com/thoth-station/jupyterlab-requirements#extension-button) if you want to know more about it): + +
+JupyterLab Requirements UI +
+ +NOTE:_In this tutorial we will focus on %horus magic commands._ + +### Start working on a new notebook + +1. Let's start a new notebook from JupyterLab console (or using the JupyterLab menu). + +
+Start new notebook +
+ +2. Run cell with `%horus check` to check the status of your notebook: + +
+Horus check initial command +
+ +As you can see, initially there are errors reported because no Pipfile or Pipfile.lock exist for this notebook. + +3. Run cell with `%horus requirements --add ` to add a new package. + +For example, let's add a common package used in ML projects: `%horus requirements --add boto3` + +
+Horus requirements add +
+ +4. You can check the dependencies content of your notebook by running `%horus show`: + +
+Horus show command after add +
+ +5. Run `%horus lock` to lock dependencies using Thoth resolution engine. + +If you are interested in a specific recommendation from Thoth, add `--recommendation-type `, default is `latest` ("latest", "stable", "performance", "security"). + +By default, Thoth will discover the runtime environment you are running on. If you want to receive a recommendation for a specific runtime environment, you can use the following flags: + +- `--os-name` +- `--os-version` +- `--python-version` + +6. Run cell with `%horus check` to check the status of your notebook or `%horus show` to show the content of your notebook. + +If you want to show a specific part of your dependencies information stored in the notebook metadata, you can use the following flags: + +- `--pipfile` +- `--pipfile-lock` +- `--thoth-config` (only if Thoth resolution engine was used) + + +### Bring your notebook and make it reproducible + +We will consider two use cases: + +- This is a notebook I was working on and I want to make it reproducible because I did not state any dependencies. + +- This is a notebook I was working on that uses `pip` in my cells and I want to make it reproducible. + +#### Notebook with no commands for dependency management + +1. Let's open the notebook called `discover-my-notebook`, provided in `notebooks` folder. + +
+Start my notebook +
+ +2. Run cell with `%horus check` to check the status of your notebook: + +
+Horus check initial command +
+ +As you can see, initially there are errors reported because no Pipfile or Pipfile.lock exist for this notebook. + +3. Run `%horus discover`, so that Thoth can discover the packages that you are using in your dependencies + +
+Horus discover command +
+ +As you can notice the `%horus discover` command is able to read the content of your notebook and identify packages that are actually used in the notebook. `numpy` for example is imported but never used, therefore is not added to the requirements. The library that is able to identify libraries is called `invectio`, have a look [here](https://github.com/thoth-station/invectio) if you want to know more. + +NOTE: _If you want to edit some dependencies, you can simply add them again with your specific requirements (`%horus requirement --add`)._ + +4. Run cell with `%horus check` to check the status of your notebook. + +
+Horus check after discover +
+ +5. Run `%horus lock` to lock dependencies using Thoth resolution engine. + +
+Horus lock command +
+ +If you are interested in a specific recommendation from Thoth, add `--recommendation-type `, default is `latest` ("latest", "stable", "performance", "security"). + +By default, Thoth will discover the runtime environment you are running on. If you want to receive a recommendation for a specific runtime environment, you can use the following flags: + +- `--os-name` +- `--os-version` +- `--python-version` + +6. Run cell with `%horus check` to check the status of your notebook or `%horus show` to show the content of your notebook. + +If you want to show a specific part of your dependencies information stored in the notebook metadata, you can use the following flags: + +- `--pipfile` +- `--pipfile-lock` +- `--thoth-config` (only if Thoth resolution engine was used) + + +#### Notebook with pip install cells + +1. Let's open the notebook called `make-notebook-reproducible`, provided in `notebooks` folder. + +
+Start my notebook with pip cells +
+ +NOTE: _A warning from the jupyterlab-requirements extension will appear to tell users what should be used to handle dependencies._ + +
+Start my notebook and warning +
+ +2. Run cell with `%horus check` to check the status of your notebook: + +
+Horus check initial command +
+ +As you can see, initially there are errors reported because no Pipfile or Pipfile.lock exist for this notebook. + +3. Run `%horus convert`, so that the extenstion can convert `!pip install` cells to commands that allow reproducibility. + +
+Horus convert command +
+ +4. Run the converted cells to add the requirements to your notebook. + +NOTE: _If you want to edit some dependencies, you can simply add them again with your specific requirements (`%horus requirement --add`)._ + +5. Run cell with `%horus check` to check the status of your notebook. + +
+Horus check after discover +
+ +6. Run `%horus lock` to lock dependencies using Thoth resolution engine. + +
+Horus lock command +
+ +If you are interested in a specific recommendation from Thoth, add `--recommendation-type `, default is `latest` ("latest", "stable", "performance", "security"). + +By default, Thoth will discover the runtime environment you are running on. If you want to receive a recommendation for a specific runtime environment, you can use the following flags: + +- `--os-name` +- `--os-version` +- `--python-version` + +7. Run cell with `%horus check` to check the status of your notebook or `%horus show` to show the content of your notebook. + +If you want to show a specific part of your dependencies information stored in the notebook metadata, you can use the following flags: + +- `--pipfile` +- `--pipfile-lock` +- `--thoth-config` (only if Thoth resolution engine was used) + + +## Next Step + +[Push changes to GitHub](./push-changes.md) + +## References + +* [jupyterlab-requirements][1] + +[1]: https://github.com/thoth-station/jupyterlab-requirements diff --git a/docs/thoth-aicoe-services.md b/docs/thoth-aicoe-services.md new file mode 100644 index 0000000..936cc4f --- /dev/null +++ b/docs/thoth-aicoe-services.md @@ -0,0 +1,233 @@ +# Create a first release and image of your project + +This section describes how the [AICoE CI][1] and [Thoth](https://github.com/thoth-station) bots can be used to maintain dependencies and create the images for your project. + +In particular: + +- [AICoE CI][1] is Continuous integration system used for running status checks on pull request, build releases, and python module releases. + +- [Kebechet Bot][4] is used to keep your dependencies fresh and up to date receiving recommendations and justifications using AI (Thoth service). + +These bots and pipelines exist to automate many of the manual GitOps tasks (e.g. in order to deploy your application, you may need to create a container image). [GitHub templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/about-issue-and-pull-request-templates) integrated with bots can provide you with automated pipelines triggered depending on what you need (e.g. release (patch, minor, major), deliver a container image, or update your dependencies). + +The next steps will teach you how to install and enable those tools and trigger them. + + +## Set up Thoth bots + +Adding Thoth's bots takes just a few steps! + +### 1. Install Khebut + +Start by installing the Kebechet GitHub application, called Khebut by [following this link](https://github.com/apps/khebhut). It can be configured on an organization or on a single repository. + +Once the application is installed, you will need to add Thoth's bot (Sesheta) as collaborator. Navigate to the repo where you intalled Khebut. Under the repository's **Settings**, go to **Manage Access** and click on "Invite a collaborator" and add Thoth Bot Sesheta. Sesheta is a friendly Thoth bot who is used to help automate tasks. [Follow this link](https://github.com/AICoE/aicoe-ci/issues/new?assignees=goern%2Charshad16&labels=area%2Fcyborgs%2Cbot%2Csig%2Fcyborgs&template=request_sesheta.yaml&title=Help+with+Sesheta+invite) and fill out the form to have Sesheta accept your invitation. Please note: there is sometimes a delay in Sesheta's invite acceptance. + +
+Invite Sesheta +
+ +### 2. Enable issues on your fork + +Sesheta, the bot that will assist you in this tutorial, communicates through issues. On your fork, the issues tab may not be enabled automatically. In order to enable issues, go to the **Settings** tab and check the box next to "Issues". + +
+Enable Fork Issues +
+ +### 3. Edit `.thoth.yaml` + +Thoth services require a configuration file ([.thoth.yaml](../.thoth.yaml)) at the root level of the project. This tutorial is based on [project-template][8], therefore the .thoth.yaml is already present. + +In this tutorial, the file is already present, so you will not need to add it. To configure this on your own fork, you will need to update the Kebechet [managers](https://github.com/thoth-station/kebechet/tree/master/kebechet/managers) section to include your GitHub username and push changes to your fork. Check [push changes section]((./push-changes.md)) for more details. + +An example snippet of `.thoth.yaml` highlightling the changes to be made is shown below. + +```yaml +host: khemenu.thoth-station.ninja +tls_verify: false +requirements_format: pipenv + +runtime_environments: + - name: tutorial # runtime environment name + operating_system: + name: rhel + version: "8" + python_version: "3.8" + recommendation_type: latest + +managers: + - name: pipfile-requirements + - name: update + configuration: + labels: [bot] + - name: info + - name: version + configuration: + maintainers: + - pacospace # UPDATE TO HAVE YOUR OWN USERNAME + assignees: + - sesheta + labels: [bot] + changelog_file: true +``` + +To learn more about Thoth bots and services, please check out the guide [here][2]. + +### 4. Push changes to GitHub + +Once you modify the `.thoth.yaml` push the changes to your repo. Check [push changes section]((./push-changes.md)) for more details. + + +## Set up AICoE CI + +The [AICoE CI][1](https://github.com/AICoE/aicoe-ci) can be set up in just a few steps. + +### 1. Install AICOE CI + +Start by installing the AICoE CI GitHub application by [following this link](https://github.com/apps/aicoe-ci). When installing this application, select your profile for the organization, and specify the repository you are working on (e.g. `manage-dependencies-tutorial`). + +### 2. Set up robot account + +This step is required to create credentials for the aicoe-ci to push to your container registry (e.g. Quay). + +#### Quay + +These steps are specific for users with Quay account and they will involve setting up a robot account on the image registry [Quay.io](https://quay.io/). + +First, you will need to create a robot in the organization or individual account. Under **Account Settings** on Quay, click on **Robot Accounts** tab, and "Create Robot Account" button. Enter a name for the account. The username will become namespace+accountname where namespace is the name of the user or organization. + +
+Create Robot Account +
+ +Once created, click on the robot account name. Find the "Docker Configuration" tab in the robot account popup, and copy the .json. Currently, you will have to pass it on by contacting us. You can reach us at `aicoe-thoth+devconf@redhat.com`. Once the secret is passed, it is ready to be used in the `.aicoe-ci.yaml` file in the next step. + +### 3. Login into your container registry and create new repository + +Click on `+ Create New Repository` button on the upper left part: + +
+Create New Repository +
+ + +### 4. Add the name of the repository and make it public + +
+Create Public Quay repository +
+ + +### 5. Set robot permissions for your repo + +1. Once the repository is created, go to `Setting`: + +
+Go to Setting for your Repo +
+ +2. Under `User and Robot Permissions` you can add the Robot Account created at point 2: + +
+Set Robot Account to your Repo +
+ +3. Set Robot Permission to `Write`: + +
+Set Robot Permission to Write to your Repo +
+ +4. Click `Add Permission`: + +
+Add Permission for the Robot Account +
+ +Now everything is set on your container registry and the AICoE-CI will be able to push to your container image in your registry. Last step will be configuring the AICOE-CI to know where to push. + +### 6. Edit `.aicoe-ci.yaml` + +The last step is to edit the [aicoe-ci configuration file](https://github.com/AICoE/aicoe-ci#aicoe-ci-configuration-file). This tutorial is based on [project-template][8], therefore the .thoth.yaml is already present. The `.aicoe.yaml` onfiguration file allows user to assign details about the build requirements and specify base image and registry details for build and push. For the purpose of this tutorial, the [.aicoe-ci.yaml](../.aicoe-ci.yaml) file is already present. However, you may need to edit some of the fields for your personal access, namely `registry-org`, `registry-project`, and `registry-secret`. + +```yaml +check: + - [] # Enable checks for your repo (pre-commit, build, pytest) +build: + base-image: "quay.io/thoth-station/s2i-elyra-custom-notebook:v0.3.3" + build-source-script: "image:///opt/app-root/builder" + custom-tag: latest + build-stratergy: Source # Allowed values: Source, Dockerfile, Containerfile + registry: quay.io # Image registry to be used. (default: quay.io) + registry-org: thoth-station # Organization in Image Registry. (default: thoth-station) + registry-project: manage-dependencies-tutorial # project repository in Image Registry (ie, Quay) used to push image (created in point 3.). + registry-secret: thoth-station-thoth-pusher-secret # comes from robot account (created in point 2.) +``` + +For more detailed information on the config file and robot accounts, visit the [AICoE CI documentation](https://github.com/AICoE/aicoe-ci#configuring-build-requirements). + +### 7. Push changes to GitHub + +Once you modify the `.aicoe.yaml` push the changes to your repo. Check [push changes section]((./push-changes.md)) for more details. + + +## Create new release + +Now that everything is set you can create new images. Some of the pipelines used in the Thoth project are maintained by bots. Therefore you can simply open an issue asking for a release (e.g patch, minor, major) and the bots will handle your request. Once the request is completed, the bot will also automatically close the issue, as you can see from the images below: + +
+Open Issue Release +
+ +
+Pull Request Release +
+ +Fun fact, the `CHANGELOG` in the release is also created using an AI model that clusters pull requests. You can find more information about this model in our [glyph][3] project. + +Once the issue is closed by the bot, a new tag is created in the GitHub repo. This in turn triggers the Tekton pipelines in AICoE CI to start the build process and push the image on the registry according to the configuration defined in the [.aicoe-ci.yaml](../.aicoe-ci.yaml). + +Once the image has been created by the Tekton pipelines, you can find it in your registry (e.g. Quay): + +
+Image on Registry +
+ +## Dependencies updates in the repo + +Once you install Khebut in your repo, you can benefit from different [services](https://github.com/thoth-station/kebechet#kebechet) just setting correctly the `.thoth.yaml` configuration file. + +Thoth bots regularly checks if your project is using the optimal set of dependencies in terms of CVE vulnerabilities, newer package releases, and performance changes. If it finds that the dependencies can be updated, it automatically opens a PR on your repo to make the required updates! + +An example of the Khebut bot in action can be seen below. + +
+Khebut Automatic Update +
+ + +## Next Step + +[Share your work](./share-your-work.md) + + +## References + +* [AICoE CI][1] +* [Setting AICoE CI on a GitHub repo/org][2] +* [Project Glyph][3] +* [Kebechet Bot][4] +* [Bots and CI Services Setup Instructions][5] +* [Project Meteor][6] +* [Operate First][7] +* [project-template][8] + +[1]: https://github.com/AICoE/aicoe-ci +[2]: https://github.com/AICoE/aicoe-ci#setting-aicoe-ci-on-github-organizationrepository +[3]: https://github.com/thoth-station/glyph +[4]: https://github.com/thoth-station/kebechet +[5]: https://github.com/AICoE/aicoe-ci/blob/master/docs/thoth-bots-setup.md#instructions-to-setup-bots-and-ci-services +[6]: https://github.com/AICoE/meteor +[7]: https://www.operate-first.cloud/ +[8]: https://github.com/aicoe-aiops/project-template diff --git a/manifests/.gitkeep b/manifests/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/models/.gitkeep b/models/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/notebooks/discover-my-notebook.ipynb b/notebooks/discover-my-notebook.ipynb new file mode 100644 index 0000000..ac6e61c --- /dev/null +++ b/notebooks/discover-my-notebook.ipynb @@ -0,0 +1,46 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "9b748ecc", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np # noqa" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c0c33c9", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame()" + ] + } + ], + "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.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/make-notebook-reproducible.ipynb b/notebooks/make-notebook-reproducible.ipynb new file mode 100644 index 0000000..cfc2309 --- /dev/null +++ b/notebooks/make-notebook-reproducible.ipynb @@ -0,0 +1,36 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "210ead89", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install boto3\n", + "!pip install numpy" + ] + } + ], + "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.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/references/.gitkeep b/references/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/reports/.gitkeep b/reports/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/reports/figures/.gitkeep b/reports/figures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..408f7ee --- /dev/null +++ b/src/__init__.py @@ -0,0 +1 @@ +"""Analytics compiled into python code.""" diff --git a/src/data/.gitkeep b/src/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/data/__init__.py b/src/data/__init__.py new file mode 100644 index 0000000..db5d274 --- /dev/null +++ b/src/data/__init__.py @@ -0,0 +1 @@ +"""Data collection module.""" diff --git a/src/models/.gitkeep b/src/models/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/models/__init__.py b/src/models/__init__.py new file mode 100644 index 0000000..cbd01c1 --- /dev/null +++ b/src/models/__init__.py @@ -0,0 +1 @@ +"""Module for models.""" diff --git a/src/models/predict_model.py b/src/models/predict_model.py new file mode 100644 index 0000000..d42b0c8 --- /dev/null +++ b/src/models/predict_model.py @@ -0,0 +1 @@ +"""Here goes the prediction code.""" diff --git a/src/models/train_model.py b/src/models/train_model.py new file mode 100644 index 0000000..75dae17 --- /dev/null +++ b/src/models/train_model.py @@ -0,0 +1 @@ +"""Here goes the training code.""" diff --git a/src/visualization/.gitkeep b/src/visualization/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/visualization/__init__.py b/src/visualization/__init__.py new file mode 100644 index 0000000..66e87d3 --- /dev/null +++ b/src/visualization/__init__.py @@ -0,0 +1 @@ +"""Visualizations module.""" diff --git a/src/visualization/visualize.py b/src/visualization/visualize.py new file mode 100644 index 0000000..67bb610 --- /dev/null +++ b/src/visualization/visualize.py @@ -0,0 +1 @@ +"""Visualizations code.""" diff --git a/version.py b/version.py new file mode 100644 index 0000000..10242a7 --- /dev/null +++ b/version.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# manage-dependencies-tutorial +# Copyright(C) 2021 Francesco Murdaca +# +# This program is free software: you can redistribute it and / or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""This file carries the version of the project.""" + +__version__ = "0.0.1"