Repository: ai4os/DEEPaaS (language: python)

Issue:
Remove python six dependency



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ef85c0a1..f0fe2c47 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,7 +14,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ['3.8', '3.9', '3.10', '3.11']
+        python-version: ['3.10', '3.11', '3.12']
 
     steps:
     - uses: actions/checkout@v3
@@ -26,5 +26,6 @@ jobs:
       run: |
         python -m pip install --upgrade pip
         python -m pip install tox tox-gh-actions
+        python -m pip install poetry poetry poetry-plugin-export
     - name: Test with tox
       run: tox
diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml
index 9edd9a86..fc29fc0f 100644
--- a/.github/workflows/python-publish.yml
+++ b/.github/workflows/python-publish.yml
@@ -12,7 +12,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ["3.8", "3.9", "3.10", "3.11"]
+        python-version: ['3.10', '3.11', '3.12']
 
     steps:
     - uses: actions/checkout@v3
@@ -26,6 +26,7 @@ jobs:
       run: |
         python -m pip install --upgrade pip
         pip install tox tox-gh-actions
+        python -m pip install poetry poetry poetry-plugin-export
 
     - name: Test with tox
       run: tox
@@ -44,15 +45,13 @@ jobs:
     - name: Install dependencies
       run: |
         python -m pip install --upgrade pip
-        pip install setuptools wheel twine
+        python -m pip install poetry poetry poetry-plugin-export
 
     - name: Build and publish
       env:
         TWINE_USERNAME: "__token__"
         TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
       run: |
-        python -m pip install --upgrade pip
-        pip install build
-        python -m build
-        twine upload dist/*
+        poetry build
+        poetry publish
 
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 00000000..e74f098b
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,50 @@
+cff-version: 1.2.0
+title: DEEPaaS
+message: ' A REST API to serve machine learning and deep learning models '
+type: software
+authors:
+  - given-names: Álvaro
+    family-names: López García
+    email: aloga@ifca.unican.es
+    affiliation: 'IFCA, CSIC-UC'
+    orcid: 'https://orcid.org/0000-0002-0013-4602'
+identifiers:
+  - type: doi
+    value: 10.5281/zenodo.1544377
+    description: Zenodo record
+  - type: doi
+    value: 10.21105/joss.01517
+    description: Journal publication
+repository-code: 'https://github.com/ai4os/DEEPaaS/'
+abstract: >-
+  DEEP as a Service API (DEEPaaS API) is a REST API built on
+  aiohttp that allows to provide easy access to machine
+  learning, deep learning and artificial intelligence
+  models. By using the DEEPaaS API users can easily run a
+  REST API in front of their model, thus accessing its
+  functionality via HTTP calls. DEEPaaS API leverages the
+  OpenAPI specification.
+keywords:
+  - http
+  - http 
+  - data science 
+  - machine learning 
+  - deep learning
+  - neural network 
+  - REST api
+  - aiohttp 
+  - artificial intelligence
+  - neural networks 
+license: Apache-2.0
+preferred-citation:
+  authors:
+  - given-names: Álvaro
+    family-names: López García
+    email: aloga@ifca.unican.es
+    affiliation: 'IFCA, CSIC-UC'
+    orcid: 'https://orcid.org/0000-0002-0013-4602'
+  title: "DEEPaaS API: a REST API for Machine Learning and Deep Learning models"
+  type: article
+  year: 2019
+  journal: "Journal of Open Source Software"
+  doi: 10.21105/joss.01517
diff --git a/README.md b/README.md
index 63484d2f..9a2e2da5 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,15 @@
 # DEEPaaS
 
+[![fair-software.eu](https://img.shields.io/badge/fair--software.eu-%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F%20%20%E2%97%8F-green)](https://fair-software.eu)
+[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9063/badge)](https://www.bestpractices.dev/projects/9063)
 [![GitHub license](https://img.shields.io/github/license/indigo-dc/DEEPaaS.svg)](https://github.com/indigo-dc/DEEPaaS/blob/master/LICENSE)
 [![GitHub release](https://img.shields.io/github/release/indigo-dc/DEEPaaS.svg)](https://github.com/indigo-dc/DEEPaaS/releases)
 [![PyPI](https://img.shields.io/pypi/v/deepaas.svg)](https://pypi.python.org/pypi/deepaas)
 [![Python versions](https://img.shields.io/pypi/pyversions/deepaas.svg)](https://pypi.python.org/pypi/deepaas)
 [![Build Status](https://jenkins.services.ai4os.eu/job/AI4OS/job/DEEPaaS/job/master/badge/icon)](https://jenkins.services.ai4os.eu/job/AI4OS/job/DEEPaaS/job/master/)
+[![Documentation Status](https://readthedocs.org/projects/deepaas/badge/?version=latest)](https://deepaas.readthedocs.io/en/latest/)
 [![DOI](https://joss.theoj.org/papers/10.21105/joss.01517/status.svg)](https://doi.org/10.21105/joss.01517)
+[![Zenodo DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1544377.svg)](https://zenodo.org/doi/10.5281/zenodo.1544377)
 
 <img src="https://raw.githubusercontent.com/ai4os/.github/ai4os/profile/horizontal-transparent.png" width=200 alt="AI4EOSC logo"/>
 <img src="https://marketplace.deep-hybrid-datacloud.eu/images/logo-deep.png" width=200 alt="DEEP-Hybrid-DataCloud logo"/>
diff --git a/deepaas/__init__.py b/deepaas/__init__.py
index 0df3b22d..d37785b8 100644
--- a/deepaas/__init__.py
+++ b/deepaas/__init__.py
@@ -14,6 +14,4 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-from deepaas import version
-
-__version__ = version.release_string
+__version__ = "2.3.2"
diff --git a/deepaas/api/v2/debug.py b/deepaas/api/v2/debug.py
index 012905ef..c018b105 100644
--- a/deepaas/api/v2/debug.py
+++ b/deepaas/api/v2/debug.py
@@ -15,6 +15,7 @@
 # under the License.
 
 import datetime
+import io
 import logging
 import sys
 import warnings
@@ -23,7 +24,6 @@
 import aiohttp_apispec
 from oslo_config import cfg
 from oslo_log import log
-import six
 
 CONF = cfg.CONF
 
@@ -56,7 +56,7 @@ def setup_debug():
     global DEBUG_STREAM
 
     if CONF.debug_endpoint:
-        DEBUG_STREAM = six.StringIO()
+        DEBUG_STREAM = io.StringIO()
 
         logger = log.getLogger("deepaas").logger
         hdlr = logging.StreamHandler(DEBUG_STREAM)
@@ -71,7 +71,7 @@ def setup_debug():
             "restriction in the /debug/ endpoint. Disable it whenever "
             "you have finished debugging your application. \033[0m"
         )
-        warnings.warn(msg, RuntimeWarning)
+        warnings.warn(msg, RuntimeWarning, stacklevel=2)
 
         sys.stdout = MultiOut(DEBUG_STREAM, sys.stdout)
         sys.stderr = MultiOut(DEBUG_STREAM, sys.stderr)
diff --git a/deepaas/model/v2/__init__.py b/deepaas/model/v2/__init__.py
index 920cc01b..bb82969d 100644
--- a/deepaas/model/v2/__init__.py
+++ b/deepaas/model/v2/__init__.py
@@ -60,13 +60,14 @@ def register_models(app):
         warnings.warn(
             "Error loading models, using test model. This will be deprecated soon.",
             DeprecationWarning,
+            stacklevel=2,
         )
 
     if MODELS:
         if len(MODELS) > 1:
             # Loading several models will be deprecated in the future
             warn_msg = "Loading several models is deprecated."
-            warnings.warn(warn_msg, DeprecationWarning)
+            warnings.warn(warn_msg, DeprecationWarning, stacklevel=2)
             LOG.warning(warn_msg)
 
         MODELS_LOADED = True
@@ -79,7 +80,7 @@ def register_models(app):
             "API, please use the demo_app instead. "
             "Check https://github.com/deephdc/demo_app for more information.",
         )
-        warnings.warn(warn_msg, DeprecationWarning)
+        warnings.warn(warn_msg, DeprecationWarning, stacklevel=2)
         LOG.info("No models found in V2, loading test model")
         LOG.warning(warn_msg)
         MODELS["deepaas-test"] = wrapper.ModelWrapper(
diff --git a/deepaas/model/v2/base.py b/deepaas/model/v2/base.py
index 0c8b4424..2f89f926 100644
--- a/deepaas/model/v2/base.py
+++ b/deepaas/model/v2/base.py
@@ -16,11 +16,8 @@
 
 import abc
 
-import six
 
-
-@six.add_metaclass(abc.ABCMeta)
-class BaseModel(object):
+class BaseModel(object, metaclass=abc.ABCMeta):
     """Base class for all models to be used with DEEPaaS.
 
     Note that it is not needed for DEEPaaS to inherit from this abstract base
diff --git a/deepaas/version.py b/deepaas/version.py
deleted file mode 100644
index 1488deaa..00000000
--- a/deepaas/version.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright 2018 Spanish National Research Council (CSIC)
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import pbr.version
-
-version_info = pbr.version.VersionInfo("deepaas")
-
-version_string = version_info.version_string()
-release_string = version_info.release_string()
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 12418030..a4dae53a 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -19,7 +19,7 @@
 import os
 import sys
 
-from deepaas import version
+import deepaas
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -33,11 +33,12 @@
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 
-extensions = ['sphinx.ext.autodoc',
-              'oslo_config.sphinxconfiggen',
-              'oslo_config.sphinxext',
-              "reno.sphinxext",
-              "recommonmark",
+extensions = [
+    'sphinx.ext.autodoc',
+    'oslo_config.sphinxconfiggen',
+    'oslo_config.sphinxext',
+    "reno.sphinxext",
+    "recommonmark",
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -49,7 +50,7 @@
 todo_include_todos = True
 
 source_parsers = {
-   '.md': 'recommonmark.parser.CommonMarkParser',
+    '.md': 'recommonmark.parser.CommonMarkParser',
 }
 
 # The suffix of source filenames.
@@ -59,18 +60,21 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'DEEP-Hybrid-DataCloud'
-copyright = u'2017-present, <a href="https://deep-hybrid-datacloud.eu">DEEP-Hybrid-DataCloud</a> consortium'
-author = u"DEEP-Hybrid-DataCloud consortium"
+project = 'Ai4EOSC'
+copyright = (
+    '2017-2022, DEEP-Hybrid-DataCloud consortium'
+    '2022-present, AI4EOSC Consortium'
+)
+author = u"AI4EOSC consortium"
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The full version, including alpha/beta/rc tags.
-release = version.release_string
+release = deepaas.__version__
 # The short X.Y version.
-version = version.release_string
+version = deepaas.__version__
 
 # A list of glob-style patterns that should be excluded when looking for
 # source files. They are matched against the source file names relative to the
@@ -102,7 +106,7 @@
 ]
 
 # If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
 
 # -- Options for HTML output --------------------------------------------------
 
@@ -139,26 +143,25 @@
 
 # Custom sidebar templates, maps document names to template names.
 html_sidebars = {
-#    'index':    ['sidebar.html', 'sourcelink.html', 'searchbox.html'],
-#    '**':       ['sidebar.html', 'localtoc.html', 'relations.html',
-#                 'sourcelink.html', 'searchbox.html'],
-    'index':       ['about.html', 'navigation.html', 'relations.html',
-                 'sourcelink.html', 'searchbox.html', 'sidebarfooter.html'],
+    'index': [
+        'about.html', 'navigation.html', 'relations.html',
+        'sourcelink.html', 'searchbox.html', 'sidebarfooter.html'
+    ],
 }
 
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
 
 # If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
 
 # If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
 html_show_sourcelink = False
@@ -172,24 +175,24 @@
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
 
 # Language to be used for generating the HTML full-text search index.
 # Sphinx supports the following languages:
 #   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
 #   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
-#html_search_language = 'en'
+# html_search_language = 'en'
 
 # A dictionary with options for the search language support, empty by default.
 # Now only 'ja' uses this config value
-#html_search_options = {'type': 'default'}
+# html_search_options = {'type': 'default'}
 
 # The name of a javascript file (relative to the configuration directory) that
 # implements a search results scorer. If empty, the default will be used.
-#html_search_scorer = 'scorer.js'
+# html_search_scorer = 'scorer.js'
 
 # Output file base name for HTML help builder.
 htmlhelp_basename = 'DEEPaaSdoc'
@@ -200,8 +203,7 @@
 # (source start file, target name, title, author, documentclass
 # [howto/manual]).
 latex_documents = [
-    ('index', 'deepaas.tex', u'DEEPaaS Documentation',
-     author, 'manual'),
+    ('index', 'deepaas.tex', u'DEEPaaS Documentation', author, 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -210,16 +212,16 @@
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
 
 # If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
 
 # If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
 
 # Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
 
 # If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..4c713f24
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,107 @@
+[tool.poetry]
+name = "deepaas"
+version = "2.3.2"
+description = "DEEPaaS is a REST API to expose a machine learning model."
+authors = ["Alvaro Lopez Garcia <aloga@ifca.unican.es>"]
+license = "Apache-2"
+readme = "README.md"
+
+homepage = "https://github.com/ai4os/deepaas"
+repository = "https://github.com/ai4os/deepaas/issues"
+documentation = "https://deepaas.readthedocs.io/"
+
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Environment :: Console",
+    "Environment :: Web Environment",
+    "Framework :: AsyncIO",
+    "Intended Audience :: Developers",
+    "Intended Audience :: Information Technology",
+    "Intended Audience :: Science/Research",
+    "Intended Audience :: System Administrators",
+    "License :: OSI Approved :: Apache Software License",
+    "Operating System :: OS Independent",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.6",
+    "Programming Language :: Python :: 3.7",
+    "Programming Language :: Python :: 3.8",
+    "Programming Language :: Python :: 3.9",
+    "Programming Language :: Python :: 3.10",
+    "Topic :: Internet :: WWW/HTTP",
+    "Topic :: Scientific/Engineering :: Artificial Intelligence",
+    "Topic :: Scientific/Engineering :: Image Recognition",
+    "Topic :: Scientific/Engineering :: Information Analysis",
+    "Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator",
+]
+
+[tool.poetry.urls]
+"Bug Tracker" = "https://github.com/ai4os/deepaas/issues"
+
+[tool.poetry.scripts]
+deepaas-run = "deepaas.cmd.run:main"
+deepaas-predict = "deepaas.cmd.execute:main"
+deepaas-cli = "deepaas.cmd.cli:main"
+
+[tool.poetry.plugins] # Optional super table 
+
+[tool.poetry.plugins."oslo.config.opts"] 
+deepaas = "deepaas.opts:list_opts"
+
+[tool.poetry.dependencies]
+python = "^3.10"
+"oslo.log" = "^6.0.0"
+"oslo.config" = "^9.4.0"
+stevedore = "^5.2.0"
+aiohttp = "^3.9.5"
+aiohttp-apispec = "^2.2.3"
+Werkzeug = "^3.0.3"
+marshmallow = "^3.21.3"
+webargs = "<6.0.0"
+
+
+[tool.poetry.group.dev.dependencies]
+tox = "^4.15.1"
+
+
+[tool.poetry.group.test.dependencies]
+pytest = "^8.2.2"
+pytest-aiohttp = "^1.0.5"
+pytest-cov = "^5.0.0"
+fixtures = "^4.1.0"
+reno = "^4.1.0"
+mock = "^5.1.0"
+testtools = "^2.7.1"
+
+
+[tool.poetry.group.test-flake8.dependencies]
+flake8 = "^7.0.0"
+flake8-bugbear = "^24.4.26"
+flake8-typing-imports = "^1.15.0"
+flake8-colors = "^0.1.9"
+pep8-naming = "^0.14.1"
+pydocstyle = "^6.3.0"
+
+
+[tool.poetry.group.test-black.dependencies]
+black = "^24.4.2"
+
+
+[tool.poetry.group.test-bandit.dependencies]
+bandit = "^1.7.8"
+
+
+[tool.poetry.group.test-mypy.dependencies]
+mypy = "^1.10.0"
+
+
+[tool.poetry.group.test-pypi.dependencies]
+twine = "^5.1.0"
+
+
+[tool.poetry.group.test-pip-missing-reqs.dependencies]
+pip-check-reqs = "^2.5.3"
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 4e6cbe48..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# The order of packages is significant, because pip processes them in the order
-# of appearance. Changing the order has an impact on the overall integration
-# process, which may cause wedges in the gate later.
-pbr>=4.1.0
-six>=1.9.0 # MIT
-
-typer>=0.4.1
-
-oslo.log>=1.8.0 # Apache-2.0
-oslo.config>=2.3.0 # Apache-2.0
-
-stevedore>=1.20.0 # Apache-2.0
-
-aiohttp>=3.6.2
-aiohttp-apispec>=2.2.0 
-
-werkzeug>=0.16.0
-marshmallow>=3.2.1
-webargs>=5.5.2,<6.0.0
-
-jsonschema>=2.6.0
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 4d10e45d..00000000
--- a/setup.cfg
+++ /dev/null
@@ -1,64 +0,0 @@
-[metadata]
-name = deepaas
-summary = DEEPaaS is a REST API to expose a machine learning model.
-description_file = README.md
-description_content_type = text/markdown; charset=UTF-8
-
-author = Alvaro Lopez Garcia
-author_email = aloga@ifca.unican.es
-
-home_page = https://github.com/indigo-dc/deepaas
-project_urls =
-    Bug Tracker = https://github.com/indigo-dc/deepaas/issues
-    Documentation = https://deepaas.readthedocs.io/
-
-python_requires = >=3.6
-
-license = Apache-2
-license_files = 
-    LICENSE
-
-classifier =
-    Development Status :: 5 - Production/Stable
-    Environment :: Console
-    Environment :: Web Environment
-    Framework :: AsyncIO
-    Intended Audience :: Developers
-    Intended Audience :: Information Technology
-    Intended Audience :: Science/Research
-    Intended Audience :: System Administrators
-    License :: OSI Approved :: Apache Software License
-    Operating System :: OS Independent
-    Programming Language :: Python
-    Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.6
-    Programming Language :: Python :: 3.7
-    Programming Language :: Python :: 3.8
-    Programming Language :: Python :: 3.9
-    Programming Language :: Python :: 3.10
-    Topic :: Internet :: WWW/HTTP
-    Topic :: Scientific/Engineering :: Artificial Intelligence
-    Topic :: Scientific/Engineering :: Image Recognition
-    Topic :: Scientific/Engineering :: Information Analysis
-    Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
-
-[files]
-packages =
-    deepaas
-
-[entry_points]
-console_scripts =
-    deepaas-run = deepaas.cmd.run:main
-    deepaas-predict = deepaas.cmd.execute:main
-    deepaas-cli = deepaas.cmd.cli:main
-
-oslo.config.opts =
-    deepaas = deepaas.opts:list_opts
-
-[build_sphinx]
-source-dir = doc/source
-build-dir = doc/build
-all_files = 1
-
-[upload_sphinx]
-upload-dir = doc/build/html
diff --git a/setup.py b/setup.py
deleted file mode 100644
index f3e07093..00000000
--- a/setup.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import setuptools
-
-setuptools.setup(
-    setup_requires=['pbr>=5.3.0'],
-    pbr=True)
diff --git a/tox.ini b/tox.ini
index 4e08700d..4b13acde 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,8 @@
 [tox]
 min_version = 4.3.3
+isolated_build = true
 envlist =
-    py3{8, 9, 10, 11, 12}
+    py3{10, 11, 12}
     flake8
     black
     bandit
@@ -20,7 +21,6 @@ python =
 
 [base]
 python = python3.11
-skip_install = true
 package = deepaas
 
 [pytest]
@@ -29,16 +29,8 @@ addopts = -p no:warnings
 [testenv]
 usedevelop = True
 basepython = python3
-deps =
-    pytest>=7.2.1,<7.3
-    pytest-aiohttp
-    pytest-cov>=4.0.0,<4.1
-    fixtures
-    reno
-    mock
-    testtools
-    -r{toxinidir}/requirements.txt
 allowlist_externals =
+    poetry
     find
     rm
     mkdir
@@ -48,24 +40,36 @@ setenv =
    OS_STDOUT_CAPTURE=1
    OS_STDERR_CAPTURE=1
    OS_TEST_TIMEOUT=160
+commands_pre =                                                                             
+    poetry install --no-root --sync --with test,test-{envname} 
 commands =
     find . -type f -name "*.pyc" -delete
-    pytest {posargs}
-
-[testenv:py38]
-basepython = python3.8
-
-[testenv:py39]
-basepython = python3.9
+    poetry run pytest {posargs}
 
 [testenv:py310]
 basepython = python3.10
+commands_pre =
+    poetry install --no-root --sync --with test
 
 [testenv:py311]
 basepython = python3.11
+commands_pre =
+    poetry install --no-root --sync --with test
 
 [testenv:py312]
 basepython = python3.12
+commands_pre =
+    poetry install --no-root --sync --with test
+
+[testenv:cov]                                                                              
+basepython = python3.10                                                                    
+commands_pre =                                                                          
+    poetry install --no-root --sync --with test                                         
+commands =                                                                              
+    find . -type f -name "*.pyc" -delete                                                
+    poetry run pytest {posargs} --cov={[base]package} \                                 
+           --cov-report term \                                                          
+           --cov-report=xml       
 
 [flake8]
 # Black default line length is 88
@@ -84,7 +88,6 @@ exclude =
 
 [testenv:flake8]
 basepython = {[base]python}
-skip_install = {[base]skip_install}
 deps =
     flake8>=4.0,<4.1
     flake8-bugbear>=22.3,<22.4
@@ -94,40 +97,30 @@ deps =
     pep8-naming>=0.12,<0.13
     pydocstyle>=6.1,<6.2
 commands =
-  flake8
+    poetry run flake8 {[base]package}
 
 [testenv:black]
 basepython = {[base]python}
-skip_install = {[base]skip_install}
-deps =
-    black>=22.3,<22.4
-commands = black --check --diff {[base]package}
+commands = 
+    poetry run black --check --diff {[base]package}
 
 [testenv:bandit]
 basepython = {[base]python}
-skip_install = {[base]skip_install}
-deps = bandit
-commands = bandit -r {[base]package} -x tests -s B110,B410
-
-[testenv:bandit-report]
-basepython = {[base]python}
-deps = {[testenv:bandit]deps}
-skip_install = {[base]skip_install}
-commands =
-    - mkdir /tmp/bandit
-    - bandit -r {[base]package} -x tests -s B110,B410 -f html -o /tmp/bandit/index.html
+commands = 
+    poetry run bandit -r {[base]package} -x tests -s B110,B410
 
 [testenv:pypi]
 basepython = {[base]python}
-skip_install = {[base]skip_install}
-deps = docutils
-commands = python3 setup.py check -r -s -m
+commands = 
+     poetry publish --build --dry-run
 
 [testenv:genconfig]
 basepython = {[base]python}
+commands_pre =                                                                             
+    poetry install --no-root --sync --with test
+    pip install -U .
 commands = 
-    - pip install -U .
-    - oslo-config-generator --config-file=etc/{[base]package}-config-generator.conf
+    poetry run oslo-config-generator --config-file=etc/{[base]package}-config-generator.conf
 
 [testenv:docs]
 basepython = {[base]python}
@@ -140,12 +133,13 @@ commands =
 [testenv:mypy]
 description = Static type checks
 basepython = {[base]python}
-deps =
-    mypy
 commands =
-    mypy --config-file mypy.ini -p {[base]package}
+    poetry run mypy --config-file mypy.ini -p {[base]package} --explicit-package-bases
 
 [testenv:pip-missing-reqs]
 basepython = {[base]python}
-deps = pip_check_reqs
-commands=pip-missing-reqs -d --ignore-file={[base]package}/tests/* {[base]package}
+commands =                                                                              
+    mkdir -p tmp                                                                        
+    poetry export -o tmp/requirements.txt                                               
+    poetry run pip-missing-reqs --requirements-file tmp/requirements.txt --ignore-file=data/* --ignore-file={[base]package}/tests/* {[base]package} 
+    rm tmp/requirements.txt    


Test patch:
diff --git a/deepaas/tests/base.py b/deepaas/tests/base.py
index c6965429..2ca0c1bc 100644
--- a/deepaas/tests/base.py
+++ b/deepaas/tests/base.py
@@ -74,3 +74,7 @@ def flags(self, **kw):
         group = kw.pop("group", None)
         for k, v in kw.items():
             CONF.set_override(k, v, group)
+
+    def runTest(self):  # noqa(N802)
+        """This is due to https://github.com/pytest-dev/pytest/issues/12263"""
+        pass
diff --git a/deepaas/tests/test_v2_api.py b/deepaas/tests/test_v2_api.py
index b6cad651..b97a1948 100644
--- a/deepaas/tests/test_v2_api.py
+++ b/deepaas/tests/test_v2_api.py
@@ -14,10 +14,10 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+import io
 import uuid
 
 from aiohttp import web
-import six
 from oslo_config import cfg
 from oslo_log import log as logging
 
@@ -69,7 +69,7 @@ async def test_not_found(self):
         self.assertEqual(404, ret.status)
 
     async def test_predict_data(self):
-        f = six.BytesIO(b"foo")
+        f = io.BytesIO(b"foo")
         ret = await self.client.post(
             "/v2/models/deepaas-test/predict/",
             data={"data": (f, "foo.txt"), "parameter": 1},
@@ -187,7 +187,7 @@ def assert_ok(self, response):
         self.assertIn(response.status, [200, 201])
 
     async def test_predict_data(self):
-        f = six.BytesIO(b"foo")
+        f = io.BytesIO(b"foo")
         ret = await self.client.post(
             "/custom/v2/models/deepaas-test/predict/",
             data={"data": (f, "foo.txt"), "parameter": 1},
@@ -276,7 +276,7 @@ async def test_predict_no_parameters(self):
         self.assertEqual(422, ret.status)
 
     async def test_predict_data(self):
-        f = six.BytesIO(b"foo")
+        f = io.BytesIO(b"foo")
         ret = await self.client.post(
             "/v2/models/deepaas-test/predict/",
             data={"data": (f, "foo.txt"), "parameter": 1},