# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['e2eml',
 'e2eml.classification',
 'e2eml.full_processing',
 'e2eml.model_utils',
 'e2eml.regression',
 'e2eml.test',
 'e2eml.time_series',
 'e2eml.timetravel']

package_data = \
{'': ['*']}

install_requires = \
['boostaroota>=1.3,<2.0',
 'catboost>=0.21,<0.22',
 'category_encoders==2.3.0',
 'dill>=0.3.3,<0.4.0',
 'imbalanced-learn>=0.8,<0.9',
 'lightgbm>=3.1.0,<4.0.0',
 'matplotlib==3.1.3',
 'ngboost>=0.3.1,<0.4.0',
 'nltk>=3.2.4,<4.0.0',
 'numpy>=1.19.4,<2.0.0',
 'optuna>=2.8.0,<3.0.0',
 'pandas>=1.1.5,<2.0.0',
 'plotly>=5,<6',
 'psutil==5.8.0',
 'pytorch_tabnet>=3.1.1,<4.0.0',
 'scikit-learn>=1.0.1,<2.0.0',
 'scipy>=1.5.4,<2.0.0',
 'seaborn>=0.11.1,<0.12.0',
 'shap>=0.39.0,<0.40.0',
 'spacy>=3.1.0,<4.0.0',
 'textblob>=0,<1',
 'torch>=1.7.0,<2.0.0',
 'transformers>=4,<5',
 'vowpalwabbit>=8.11.0,<9.0.0',
 'xgboost>=1.3.3,<2.0.0']

extras_require = \
{'full': ['cupy>=8.1.0,<9.0.0',
          'cython>=0.29.21,<0.30.0',
          'ipython>=7.10.0,<8.0.0',
          'notebook>=6.1.0,<7.0.0'],
 'jupyter': ['ipython>=7.10.0,<8.0.0', 'notebook>=6.1.0,<7.0.0'],
 'rapids': ['cupy>=8.1.0,<9.0.0', 'cython>=0.29.21,<0.30.0']}

setup_kwargs = {
    'name': 'e2eml',
    'version': '2.10.3',
    'description': 'An end-to-end solution for automl',
    'long_description': '# e2e ML\n\n> An end to end solution for automl.\n\nPass in your data, add some information about it and get a full pipelines in\nreturn. Data preprocessing, feature creation, modelling and evaluation with just\na few lines of code.\n\n![Header image](header.png)\n\n## Contents\n\n<!-- toc -->\n\n* [Installation](#installation)\n* [Usage example](#usage-example)\n* [Linting and Pre-Commit](#linting-and-pre-commit)\n* [Disclaimer](#disclaimer)\n* [Development](#development)\n  * [Adding or Removing Dependencies](#adding-or-removing-dependencies)\n  * [Building and Publishing](#building-and-publishing)\n  * [Documentation](#documentation)\n  * [Pull Requests](#pull-requests)\n* [Release History](#release-history)\n* [References](#references)\n* [Meta](#meta)\n\n<!-- tocstop -->\n\n## Installation\n\nFrom PyPI:\n\n```sh\npip install e2eml\n```\n\nWe highly recommend to create a new virtual environment first. Then install\ne2e-ml into it. In the environment also download the pretrained spacy model\nwith. Otherwise e2eml will do this automatically during runtime.\n\ne2eml can also be installed into a RAPIDS environment. For this we recommend to\ncreate a fresh environment following [RAPIDS](https://rapids.ai/start.html)\ninstructions. After environment installation and activation, a special\ninstallation is needed to not run into installation issues.\n\nJust run:\n\n```sh\npip install e2eml[rapids]\n```\n\nThis will additionally install cupy and cython to prevent issues. Additionally\nit is needed to run:\n\n```sh\npip3 install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html\n\n# also spacy supports GPU acceleration\npip install -U spacy[cuda112] #cuda112 depends on your actual cuda version, see: https://spacy.io/usage\n```\n\nOtherwise Pytorch will fail trying to run on GPU.\n\nIf e2eml shall be installed together with Jupyter core and ipython, please\ninstall with:\n\n```sh\npip install e2eml[full]\n```\n\ninstead.\n\n## Usage example\n\ne2e has been designed to create state-of-the-art machine learning pipelines with\na few lines of code. Basic example of usage:\n\n```python\nimport e2eml\nfrom e2eml.classification import classification_blueprints\nimport pandas as pd\n# import data\ndf = pd.read_csv("Your.csv")\n\n# split into a test/train & holdout set (holdout for prediction illustration here, but not required at all)\ntrain_df = df.head(1000).copy()\nholdout_df = df.tail(200).copy() # make sure\n# saving the holdout dataset\'s target for later and delete it from holdout dataset\ntarget = "target_column"\nholdout_target = holdout_df[target].copy()\ndel holdout_df[target]\n\n# instantiate the needed blueprints class\nfrom classification import classification_blueprints # regression bps are available with from regression import regression_blueprints\ntest_class = classification_blueprints.ClassificationBluePrint(datasource=train_df,\n                        target_variable=target,\n                        train_split_type=\'cross\',\n                        rapids_acceleration=True, # if installed into a conda environment with NVIDIA Rapids, this can be used to accelerate preprocessing with GPU\n                        preferred_training_mode=\'auto\', # Auto will automatically identify, if LGBM & Xgboost can use GPU acceleration*\n                        tune_mode=\'accurate\' # hyperparameter sets will be validated with 10-fold CV Set this to \'simple\' for 1-fold CV\n                        #categorical_columns=cat_columns # you can define categorical columns, otherwise e2e does this automatically\n                        #date_columns=date_columns # you can also define date columns (expected is YYYY-MM-DD format)\n                                                               )\n\n"""\n*\n\'Auto\' is recommended for preferred_training_mode parameter, but with \'CPU\' and \'GPU\' it can also be controlled manually.\nIf you install Xgboost & LGBM into the same environment as GPU accelerated versions, you can set preferred_training_mode=\'gpu\'.\nThis will massively improve training times and speed up SHAP feature importance for LGBM and Xgboost related tasks.\nFor Xgboost this should work out of the box, if installed into a RAPIDS environment.\n"""\n# run actual blueprint\ntest_class.ml_bp01_multiclass_full_processing_xgb_prob()\n\n"""\nWhen choosing blueprints several options are available:\n\nMulticlass blueprints can handle binary and multiclass tasks:\n- ml_bp00_train_test_binary_full_processing_log_reg_prob()\n- ml_bp01_multiclass_full_processing_xgb_prob()\n- ml_bp02_multiclass_full_processing_lgbm_prob()\n- ml_bp03_multiclass_full_processing_sklearn_stacking_ensemble()\n- ml_bp04_multiclass_full_processing_ngboost()\n- ml_bp05_multiclass_full_processing_vowpal_wabbit\n- ml_bp06_multiclass_full_processing_bert_transformer() # for NLP specifically\n- ml_bp07_multiclass_full_processing_tabnet()\n- ml_bp08_multiclass_full_processing_ridge()\n- ml_bp09_multiclass_full_processing_catboost()\n- ml_bp10_multiclass_full_processing_sgd()\n- ml_special_binary_full_processing_boosting_blender()\n- ml_special_multiclass_auto_model_exploration()\n- ml_special_multiclass_full_processing_multimodel_max_voting()\n\nThere are regression blueprints as well (in regression module):\n- ml_bp10_train_test_regression_full_processing_linear_reg()\n- ml_bp11_regression_full_processing_xgboost()\n- ml_bp12_regressions_full_processing_lgbm()\n- ml_bp13_regression_full_processing_sklearn_stacking_ensemble()\n- ml_bp14_regressions_full_processing_ngboost()\n- ml_bp15_regression_full_processing_vowpal_wabbit_reg()\n- ml_bp16_regressions_full_processing_bert_transformer()\n- ml_bp17_regression_full_processing_tabnet_reg()\n- ml_bp18_regression_full_processing_ridge_reg\n- ml_bp20_regression_full_processing_catboost()\n- ml_bp20_regression_full_processing_sgd()\n- ml_special_regression_full_processing_multimodel_avg_blender()\n- ml_special_regression_auto_model_exploration()\n\nIn ensembles algorithms can be chosen via the class attribute:\ntest_class.special_blueprint_algorithms = {"ridge": True,\n                                            "elasticnet": False,\n                                             "xgboost": True,\n                                             "ngboost": True,\n                                             "lgbm": True,\n                                             "tabnet": False,\n                                             "vowpal_wabbit": True,\n                                             "sklearn_ensemble": True,\n                                             "catboost": False\n                                             }\n\nAlso preprocessing steps can be selected:\ntest_class.blueprint_step_selection_non_nlp = {\n            "automatic_type_detection_casting": True,\n            "early_numeric_only_feature_selection": True,\n            "remove_duplicate_column_names": True,\n            "reset_dataframe_index": True,\n            "regex_clean_text_data": False,\n            "handle_target_skewness": False,\n            "holistic_null_filling": True, # slow\n            "iterative_null_imputation": False, # very slow\n            "fill_infinite_values": True,\n            "datetime_converter": True,\n            "pos_tagging_pca": False, # slow with many categories\n            "append_text_sentiment_score": False,\n            "tfidf_vectorizer_to_pca": True, # slow with many categories\n            "tfidf_vectorizer": False,\n            "rare_feature_processing": True,\n            "cardinality_remover": True,\n            "delete_high_null_cols": True,\n            "numeric_binarizer_pca": True,\n            "onehot_pca": True,\n            "category_encoding": True,\n            "fill_nulls_static": True,\n            "data_binning": True,\n            "outlier_care": True,\n            "remove_collinearity": True,\n            "skewness_removal": True,\n            "clustering_as_a_feature_dbscan": True,\n            "clustering_as_a_feature_kmeans_loop": True, # slow for big data, but can be heavily accelerated using rapids_acceleration=True during class instantiation\n            "clustering_as_a_feature_gaussian_mixture_loop": True, # slow for big data, but can be heavily accelerated using rapids_acceleration=True during class instantiation (will run a Kmeans on GPU)\n            "pca_clustering_results": True,\n            "reduce_memory_footprint": False,\n            "automated_feature_selection": True,\n            "bruteforce_random_feature_selection": False, # slow, this feature is experimental!\n            "sort_columns_alphabetically": True,\n            "synthetic_data_augmentation": False, # this feature is experimental, can be heavily accelerated using rapids_acceleration=True during class instantiation\n            "delete_unpredictable_training_rows": False, # this feature is experimental!\n            "scale_data": False,\n            "smote": False,\n            "autoencoder_based_oversampling": False, # perfect for imbalanced binary and multiclass data\n            "final_pca_dimensionality_reduction": False\n        }\n\nThe bruteforce_random_feature_selection step is experimental. It showed promising results. The number of trials can be controlled.\nThis step is useful, if the model overfitted (which should happen rarely), because too many features with too little\nfeature importance have been considered.\nlike test_class.hyperparameter_tuning_rounds["bruteforce_random"] = 400 .\n\nGenerally the class instance is a control center and gives room for plenty of customization.\nNever update the class attributes like shown below.\n\ntest_class.tabnet_settings = "batch_size": rec_batch_size,\n                                "virtual_batch_size": virtual_batch_size,\n                                # pred batch size?\n                                "num_workers": 0,\n                                "max_epochs": 1000}\n\ntest_class.hyperparameter_tuning_rounds = {"xgboost": 100,\n                                             "lgbm": 500,\n                                             "tabnet": 25,\n                                             "ngboost": 25,\n                                             "sklearn_ensemble": 10,\n                                             "ridge": 500,\n                                             "elasticnet": 100,\n                                             "catboost": 25,\n                                             "sgd": 2000,\n                                             "svm": 50,\n                                             "svm_regression": 50,\n                                             "ransac": 50,\n                                             "multinomial_nb": 100,\n                                             "bruteforce_random": 400,\n                                             "synthetic_data_augmentation": 100,\n                                             "autoencoder_based_oversampling": 200,\n                                             "final_kernel_pca_dimensionality_reduction": 50,\n                                             "final_pca_dimensionality_reduction": 50}\n\ntest_class.hyperparameter_tuning_max_runtime_secs = {"xgboost": 2*60*60,\n                                                       "lgbm": 2*60*60,\n                                                       "tabnet": 2*60*60,\n                                                       "ngboost": 2*60*60,\n                                                       "sklearn_ensemble": 2*60*60,\n                                                       "ridge": 2*60*60,\n                                                       "elasticnet": 2*60*60,\n                                                       "catboost": 2*60*60,\n                                                       "sgd": 2*60*60,\n                                                       "svm": 2*60*60,\n                                                       "svm_regression": 2*60*60,\n                                                       "ransac": 2*60*60,\n                                                       "multinomial_nb": 2*60*60,\n                                                       "bruteforce_random": 2*60*60,\n                                                       "synthetic_data_augmentation": 1*60*60,\n                                                       "autoencoder_based_oversampling": 2*60*60,\n                                                       "final_kernel_pca_dimensionality_reduction": 4*60*60,\n                                                       "final_pca_dimensionality_reduction": 2*60*60}\n\nWhen these parameters have to updated, please overwrite the keys individually to not break the blueprints eventually.\nI.e.: test_class.hyperparameter_tuning_max_runtime_secs["xgboost"] = 12*60*60 would work fine.\n\nWorking with big data can bring all hardware to it\'s needs. e2eml has been tested with:\n- Ryzen 5950x (16 cores CPU)\n- Geforce RTX 3090 (24GB VRAM)\n- 64GB RAM\ne2eml has been able to process 100k rows with 200 columns approximately using these specs stable for non-blended\nblueprints. Blended blueprints consume more resources as e2eml keep the trained models in memory as of now.\n\nFor data bigger than 100k rows it is possible to limit the amount of data for various preprocessing steps:\n- test_class.feature_selection_sample_size = 100000 # for feature selection\n- test_class.hyperparameter_tuning_sample_size = 100000 # for model hyperparameter optimization\n- test_class.brute_force_selection_sample_size = 15000 # for an experimental feature selection\n\nFor binary classification a sample size of 100k datapoints is sufficient in most cases. Hyperparameter tuning sample size can be much less,\ndepending on class imbalance.\n\nFor multiclass we recommend to start with small samples as algorithms like Xgboost and LGBM will easily grow in memory consumption\nwith growing number of classes.\n\nWhenever classes are imbalanced (binary & multiclass) we recommend to use the preprocessing step "autoencoder_based_oversampling".\n"""\n# After running the blueprint the pipeline is done. I can be saved with:\nsave_to_production(test_class, file_name=\'automl_instance\')\n\n# The blueprint can be loaded with\nloaded_test_class = load_for_production(file_name=\'automl_instance\')\n\n# predict on new data (in this case our holdout) with loaded blueprint\nloaded_test_class.ml_bp01_multiclass_full_processing_xgb_prob(holdout_df)\n\n# predictions can be accessed via a class attribute\nprint(churn_class.predicted_classes[\'xgboost\'])\n```\n\n## Linting and Pre-Commit\n\nThis project uses pre-commit to enforce style.\n\nTo install the pre-commit hooks, first install pre-commit into the project\'s\nvirtual environment:\n\n```sh\npip install pre-commit\n```\n\nThen install the project hooks:\n\n```sh\npre-commit install\n```\n\nNow, whenever you make a commit, the linting and autoformatting will\nautomatically run.\n\n## Disclaimer\n\ne2e is not designed to quickly iterate over several algorithms and suggest you\nthe best. It is made to deliver state-of-the-art performance as ready-to-go\nblueprints. e2e-ml blueprints contain:\n\n* preprocessing (outlier, rare feature, datetime, categorical and NLP handling)\n* feature creation (binning, clustering, categorical and NLP features)\n* automated feature selection\n* model training (with crossfold validation)\n* automated hyperparameter tuning\n* model evaluation\n\nThis comes at the cost of runtime. Depending on your data we recommend strong\nhardware.\n\n## Development\n\nThis project uses [poetry](https://python-poetry.org/).\n\nTo install the project for development, run:\n\n```sh\npoetry install\n```\n\nThis will install all dependencies and development dependencies into a virtual\nenvironment.\n\n### Adding or Removing Dependencies\n\nTo add or remove a dependency, use `poetry add <package>` or\n`poetry remove <package>` respectively. Use the `--dev` flag for development\ndependencies.\n\n### Building and Publishing\n\nTo build and publish the project, run\n\n```sh\npoetry publish --build\n```\n\n### Documentation\n\nThis project comes with documentation. To build the docs, run:\n\n```sh\ncd docs\nmake docs\n```\n\nYou may then browse the HTML docs at `docs/build/docs/index.html`.\n\n### Pull Requests\n\nWe welcome Pull Requests! Please make a PR against the `develop` branch.\n\n## Release History\n\n* 2.10.03\n  * Adjusted dependencies for Pandas, Spacy, Optuna, Setuptools, Transformers\n* 2.10.01\n  * Added references & citations to Readme\n  * Added is_imbalanced flag to Timewalk\n  * Removed babel from dependencies & updated some of them\n* 2.9.96\n  * Timewalk got adjustments\n  * Fixed a bug where row deletion has been incompatible with Tabnet\n* 2.9.95\n  * SHAP based feature selection increased to 20 folds (from 10)\n  * less unnecessary print outs\n* 2.9.93\n  * Added SHAP based feature selection\n  * Removed Xgboost from Timewalk as default due to computational and runtime costs\n  * Suppress all warnings of LGBM focal during multiclass tasks\n* 2.9.92\n  * e2eml uses poetry\n  * introduction of Github actions to check linting\n  * bug fix of LGBM focal failing due to missing hyperparameter tuning specifications\n  * preparation for Readthedocs implementation\n* 2.9.9\n  * Added Multinomial Bayes Classifier\n  * Added SVM for regression\n  * Refined Sklearn ensembles\n* 2.9.8\n  * Added Quadrant Discriminent Analysis\n  * Added Support Vector machines\n  * Added Ransac regressor\n* 2.9.7\n  * updated Plotly dependency to 5.4.0\n  * Improved Xgboost for imbalanced data\n* 2.9.6\n  * Added TimeTravel and timewalk: TimeTravel will save the class instance after\n    each preprocessing step, timewalk will automatically try different\n    preprocessing steps with different algorithms to find the best combination\n  * Updated dependencies to use newest versions of scikit-learn and\n    category-encoders\n* 2.9.0\n  * bug fixes with synthetic data augmentation for regression\n  * bug fix of target encoding during regression\n  * enhanced hyperparameter space for autoencoder based oversampling\n  * added final PCA dimensionality reduction as optional preprocessing step\n* 2.8.1\n  * autoencoder based oversampling will go through hyperprameter tuning first\n    (for each class individually)\n  * optimized TabNet performance\n* 2.7.5\n  * added oversampling based on variational autoencoder (experimental)\n* 2.7.4\n  * fixed target encoding for multiclass classification\n  * improved performance on multiclass tasks\n  * improved Xgboost & TabNet performance on binary classification\n  * added auto-tuned clustering as a feature\n* 2.6.3\n  * small bugfixes\n* 2.6.1\n  * Hyperparameter tuning does happen on a sample of the train data from now on\n    (sample size can be controlled)\n  * An experimental feature has been added, which tries to find unpredictable\n    training data rows to delete them from the training (this accelerates\n    training, but costs a bit model performance)\n  * Blueprints can be accelerated with Nvidia RAPIDS (works on clustering only f\n    or now)\n* 2.5.9\n  * optimized loss function for TabNet\n* 2.5.1\n  * Optimized loss function for synthetic data augmentation\n  * Adjusted library dependencies\n  * Improved target encoding\n* 2.3.1\n  * Changed feature selection backend from Xgboost to LGBM\n  * POS tagging is off on default from this version\n* 2.2.9\n  * bug fixes\n  * added an experimental feature to optimize training data with synthetic data\n  * added optional early feature selection (numeric only)\n* 2.2.2\n  * transformers can be loaded into Google Colab from Gdrive\n* 2.1.2\n  * Improved TFIDF vectorizer performance & non transformer NLP applications\n  * Improved POS tagging stability\n* 2.1.1\n  * Completely overworked preprocessing setup (changed API). Preprocessing\n    blueprints can be customized through a class attribute now\n  * Completely overworked special multimodel blueprints. The paricipating\n    algorithms can be customized through a class attribute now\n  * Improved NULL handling & regression performance\n  * Added Catboost & Elasticnet\n  * Updated Readme\n  * First unittests\n  * Added Stochastic Gradient classifier & regressor\n* 1.8.2\n  * Added Ridge classifier and regression as new blueprints\n* 1.8.1\n  * Added another layer of feature selection\n* 1.8.0\n  * Transformer padding length will be max text length + 20% instead of static\n    300\n  * Transformers use AutoModelForSequenceClassification instead of hardcoded\n    transformers now\n  * Hyperparameter tuning rounds and timeout can be controlled globally via\n    class attribute now\n* 1.7.8\n  * Instead of a global probability threshold, e2eml stores threshold for each\n    tested model\n  * Deprecated binary boosting blender due to lack of performance\n  * Added filling of inf values\n* 1.7.3\n  * Improved preprocessing\n  * Improved regression performance\n  * Deprecated regression boosting blender and replaced my multi\n    model/architecture blender\n  * Transformers can optionally discard worst models, but will keep all 5 by\n    default\n  * e2eml should be installable on Amazon Sagemaker now\n* 1.7.0\n  * Added TabNet classifier and regressor with automated hyperparameter\n    optimization\n* 1.6.5\n  * improvements of NLP transformers\n* 1.5.8\n  * Fixes bug around preprocessing_type=\'nlp\'\n  * replaced pickle with dill for saving and loading objects\n* 1.5.3\n  * Added transformer blueprints for NLP classification and regression\n  * renamed Vowpal Wabbit blueprint to fit into blueprint naming convention\n  * Created "extras" options for library installation: \'rapids\' installs extras,\n    so e2eml can be installed into into a rapids environment while \'jupyter\'\n    adds jupyter core and ipython. \'full\' installs all of them.\n* 1.3.9\n  * Fixed issue with automated GPU-acceleration detection and flagging\n  * Fixed avg regression blueprint where eval function tried to call\n    classification evaluation\n  * Moved POS tagging + PCA step into non-NLP pipeline as it showed good results\n    in general\n  * improved NLP part (more and better feature engineering and preprocessing) of\n    blueprints for better performance\n  * Added Vowpal Wabbit for classification and regression and replaced stacking\n    ensemble in automated model exploration by Vowpal Wabbit as well\n  * Set random_state for train_test splits for consistency\n  * Fixed sklearn dependency to 0.22.0 due to six import error\n* 1.0.1\n  * Optimized package requirements\n  * Pinned LGBM requirement to version 3.1.0 due to the bug "LightGBMError: bin\n    size 257 cannot run on GPU #3339"\n* 0.9.9\n  * Enabled tune_mode parameter during class instantiation.\n  * Updated docstings across all functions and changed model defaults.\n  * Multiple bug fixes (LGBM regression accurate mode, label encoding and\n    permutation tests).\n  * Enhanced user information & better ROC_AUC display\n  * Added automated GPU detection for LGBM and Xgboost.\n  * Added functions to save and load blueprints\n  * architectural changes (preprocessing organized in blueprints as well)\n* 0.9.4\n  * First release with classification and regression blueprints. (not available\n    anymore)\n\n## References\n\n* Focal loss\n  * [Focal loss for LGBM](https://maxhalford.github.io/blog/lightgbm-focal-loss/#first-order-derivative)\n  * [Focal loss for LGBM multiclass](https://towardsdatascience.com/multi-class-classification-using-focal-loss-and-lightgbm-a6a6dec28872)\n* Autoencoder\n  * [Variational Autoencoder for imbalanced data](https://github.com/lschmiddey/Autoencoder/blob/master/VAE_for_imbalanced_data.ipynb)\n* Target Encoding\n  * [Target encoding for multiclass](https://towardsdatascience.com/target-encoding-for-multi-class-classification-c9a7bcb1a53)\n* Pytorch-TabNet\n  * [Arik, S. O., & Pfister, T. (2019). TabNet: Attentive Interpretable Tabular Learning. arXiv preprint arXiv:1908.07442.](https://arxiv.org/pdf/1908.07442.pdf)\n  * [Implementing TabNet in Pytorch](https://towardsdatascience.com/implementing-tabnet-in-pytorch-fc977c383279)\n* Ngboost\n  * [NGBoost: Natural Gradient Boosting for Probabilistic Prediction, arXiv:1910.03225](https://arxiv.org/abs/1910.03225)\n* Vowpal Wabbit\n  * [Vowpal Wabbit Research overview](https://vowpalwabbit.org/research.html)\n\n## Meta\n\nCreator: Thomas Meißner – [LinkedIn](https://www.linkedin.com/in/thomas-mei%C3%9Fner-m-a-3808b346)\n\nConsultant: Gabriel Stephen Alexander – [Github](https://github.com/bitsofsteve)\n\nSpecial thanks to: Alex McKenzie - [LinkedIn](https://de.linkedin.com/in/alex-mckenzie)\n\n[e2eml Github repository](https://github.com/ThomasMeissnerDS/e2e_ml)\n',
    'author': 'Thomas Meißner',
    'author_email': 'meissnercorporation@gmx.de',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/ThomasMeissnerDS/e2e_ml',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'python_requires': '>=3.7,<3.9',
}


setup(**setup_kwargs)
