Repository: fractal-analytics-platform/fractal-client (language: python)

Issue:
Implement `task delete`
Requires:
* https://github.com/fractal-analytics-platform/fractal-server/issues/738


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2df697b16..f5c77f263 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 * Align with [fractal-server 1.3.0](https://fractal-analytics-platform.github.io/fractal-server/changelog/#130), by updating all relevant endpoint path/query/body parameters (\#479).
 * Add `fractal job stop` command (\#485).
+* Add `fractal task delete` command (\#510).
 * Add task ID/name/version disambiguation to `task edit` and `workflow add-task` (\#499).
 * Specific changes to existing commands:
     * Make `project_id` a required positional argument of `fractal {workflow,dataset,job}` commands (\#479).
@@ -15,7 +16,7 @@
     * Add `--username/--new-username` to `fractal user` subcommands (\#493).
     * Remove `--private` option for `fractal task collect` (\#493).
     * Add `--version` to `fractal task {new,edit}` subcommands (\#493).
-    * Split `task-id-or-name` argument of `task edit` and `workflow add-task` into two arguments (\#504)
+    * Split `task-id-or-name` argument of `task edit` and `workflow add-task` into two arguments (\#504).
     * Add `--pinned-dependency` argument to `task collect` (\#508).
 * Package and repository:
     * Fix a bug in tests, by starting the fractal-server FastAPI app in a more standard way (\#481).
diff --git a/README.md b/README.md
index a938c0c34..77048297a 100644
--- a/README.md
+++ b/README.md
@@ -22,4 +22,4 @@ See https://fractal-analytics-platform.github.io/fractal.
 
 Unless otherwise stated in each individual module, all Fractal components are released according to a BSD 3-Clause License, and Copyright is with Friedrich Miescher Institute for Biomedical Research and University of Zurich.
 
-Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich (both in Switzerland). The project lead is with [@gusqgm](https://github.com/gusqgm) & [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](exact-lab.it).
+Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich (both in Switzerland). The project lead is with [@gusqgm](https://github.com/gusqgm) & [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://exact-lab.it).
diff --git a/fractal/cmd/_task.py b/fractal/cmd/_task.py
index 9b33cf000..73b4d2f42 100644
--- a/fractal/cmd/_task.py
+++ b/fractal/cmd/_task.py
@@ -199,4 +199,20 @@ async def delete_task(
     version: Optional[str] = None,
 ) -> PrintInterface:
 
-    raise NotImplementedError("task_delete")
+    if id:
+        if version:
+            logging.error(
+                "Too many arguments: cannot provide both `id` and `version`."
+            )
+            sys.exit(1)
+    else:
+        try:
+            id = await get_task_id_from_cache(
+                client=client, task_name=name, version=version
+            )
+        except FractalCacheError as e:
+            print(e)
+            sys.exit(1)
+    res = await client.delete(f"{settings.BASE_URL}/task/{id}")
+    check_response(res, expected_status_code=204)
+    return PrintInterface(retcode=0, data="")
diff --git a/poetry.lock b/poetry.lock
index 31196473e..01792251a 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,10 +1,9 @@
-# This file is automatically @generated by Poetry and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
 
 [[package]]
 name = "aiosqlite"
 version = "0.17.0"
 description = "asyncio bridge to the standard sqlite3 module"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -19,7 +18,6 @@ typing_extensions = ">=3.7.2"
 name = "alabaster"
 version = "0.7.13"
 description = "A configurable sidebar-enabled Sphinx theme"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -31,7 +29,6 @@ files = [
 name = "alembic"
 version = "1.11.1"
 description = "A database migration tool for SQLAlchemy."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -51,7 +48,6 @@ tz = ["python-dateutil"]
 name = "anyio"
 version = "3.7.0"
 description = "High level compatibility layer for multiple asynchronous event loop implementations"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -73,7 +69,6 @@ trio = ["trio (<0.22)"]
 name = "asttokens"
 version = "2.2.1"
 description = "Annotate AST trees with source code positions"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -91,7 +86,6 @@ test = ["astroid", "pytest"]
 name = "babel"
 version = "2.12.1"
 description = "Internationalization utilities"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -103,7 +97,6 @@ files = [
 name = "bcrypt"
 version = "4.0.1"
 description = "Modern password hashing for your software and your servers"
-category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -138,7 +131,6 @@ typecheck = ["mypy"]
 name = "bumpver"
 version = "2022.1120"
 description = "Bump version numbers in project files."
-category = "dev"
 optional = false
 python-versions = ">=2.7"
 files = [
@@ -158,7 +150,6 @@ toml = "*"
 name = "certifi"
 version = "2023.5.7"
 description = "Python package for providing Mozilla's CA Bundle."
-category = "main"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -170,7 +161,6 @@ files = [
 name = "cffi"
 version = "1.15.1"
 description = "Foreign Function Interface for Python calling C code."
-category = "main"
 optional = false
 python-versions = "*"
 files = [
@@ -247,7 +237,6 @@ pycparser = "*"
 name = "charset-normalizer"
 version = "3.1.0"
 description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "dev"
 optional = false
 python-versions = ">=3.7.0"
 files = [
@@ -332,7 +321,6 @@ files = [
 name = "click"
 version = "8.1.3"
 description = "Composable command line interface toolkit"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -347,7 +335,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
 name = "colorama"
 version = "0.4.6"
 description = "Cross-platform colored terminal text."
-category = "dev"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
 files = [
@@ -359,7 +346,6 @@ files = [
 name = "commonmark"
 version = "0.9.1"
 description = "Python parser for the CommonMark Markdown spec"
-category = "main"
 optional = false
 python-versions = "*"
 files = [
@@ -374,7 +360,6 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"]
 name = "coverage"
 version = "6.5.0"
 description = "Code coverage measurement for Python"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -440,7 +425,6 @@ toml = ["tomli"]
 name = "cryptography"
 version = "41.0.1"
 description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -482,7 +466,6 @@ test-randomorder = ["pytest-randomly"]
 name = "devtools"
 version = "0.9.0"
 description = "Python's missing debug print command, and more."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -501,7 +484,6 @@ pygments = ["pygments (>=2.2.0)"]
 name = "dnspython"
 version = "2.3.0"
 description = "DNS toolkit"
-category = "main"
 optional = false
 python-versions = ">=3.7,<4.0"
 files = [
@@ -522,7 +504,6 @@ wmi = ["wmi (>=1.5.1,<2.0.0)"]
 name = "docutils"
 version = "0.18.1"
 description = "Docutils -- Python Documentation Utilities"
-category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 files = [
@@ -534,7 +515,6 @@ files = [
 name = "email-validator"
 version = "1.3.1"
 description = "A robust email address syntax and deliverability validation library."
-category = "main"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -550,7 +530,6 @@ idna = ">=2.0.0"
 name = "exceptiongroup"
 version = "1.1.1"
 description = "Backport of PEP 654 (exception groups)"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -565,7 +544,6 @@ test = ["pytest (>=6)"]
 name = "executing"
 version = "0.10.0"
 description = "Get the currently executing AST node of a frame, and other information"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -577,7 +555,6 @@ files = [
 name = "fastapi"
 version = "0.95.2"
 description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -599,7 +576,6 @@ test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6
 name = "fastapi-users"
 version = "10.4.2"
 description = "Ready-to-use and customizable users management for FastAPI"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -624,9 +600,8 @@ sqlalchemy = ["fastapi-users-db-sqlalchemy (>=4.0.0)"]
 
 [[package]]
 name = "fractal-server"
-version = "1.3.0a3"
+version = "1.3.0a4"
 description = "Server component of the Fractal analytics platform"
-category = "dev"
 optional = false
 python-versions = "^3.9"
 files = []
@@ -653,13 +628,12 @@ slurm = ["cloudpickle (>=2.2.1,<2.3.0)", "clusterfutures (>=0.5,<0.6)"]
 type = "git"
 url = "https://github.com/fractal-analytics-platform/fractal-server.git"
 reference = "main"
-resolved_reference = "fda21d714af385dcf6ff038abab1f9594d1947ae"
+resolved_reference = "c75803db225d4058ed4e6d6a2f5d42ff70a505e1"
 
 [[package]]
 name = "greenlet"
 version = "2.0.2"
 description = "Lightweight in-process concurrent programming"
-category = "dev"
 optional = false
 python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
 files = [
@@ -733,7 +707,6 @@ test = ["objgraph", "psutil"]
 name = "h11"
 version = "0.14.0"
 description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -745,7 +718,6 @@ files = [
 name = "httpcore"
 version = "0.16.3"
 description = "A minimal low-level HTTP client."
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -757,17 +729,16 @@ files = [
 anyio = ">=3.0,<5.0"
 certifi = "*"
 h11 = ">=0.13,<0.15"
-sniffio = ">=1.0.0,<2.0.0"
+sniffio = "==1.*"
 
 [package.extras]
 http2 = ["h2 (>=3,<5)"]
-socks = ["socksio (>=1.0.0,<2.0.0)"]
+socks = ["socksio (==1.*)"]
 
 [[package]]
 name = "httpx"
 version = "0.23.3"
 description = "The next generation HTTP client."
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -783,15 +754,14 @@ sniffio = "*"
 
 [package.extras]
 brotli = ["brotli", "brotlicffi"]
-cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<13)"]
+cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<13)"]
 http2 = ["h2 (>=3,<5)"]
-socks = ["socksio (>=1.0.0,<2.0.0)"]
+socks = ["socksio (==1.*)"]
 
 [[package]]
 name = "httpx-oauth"
 version = "0.11.2"
 description = "Async OAuth client using HTTPX"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -806,7 +776,6 @@ httpx = ">=0.18,<0.24"
 name = "idna"
 version = "3.4"
 description = "Internationalized Domain Names in Applications (IDNA)"
-category = "main"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -818,7 +787,6 @@ files = [
 name = "imagesize"
 version = "1.4.1"
 description = "Getting image size from png/jpeg/jpeg2000/gif file"
-category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 files = [
@@ -830,7 +798,6 @@ files = [
 name = "importlib-metadata"
 version = "6.6.0"
 description = "Read metadata from Python packages"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -850,7 +817,6 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag
 name = "iniconfig"
 version = "2.0.0"
 description = "brain-dead simple config-ini parsing"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -862,7 +828,6 @@ files = [
 name = "jinja2"
 version = "3.1.2"
 description = "A very fast and expressive template engine."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -880,7 +845,6 @@ i18n = ["Babel (>=2.7)"]
 name = "lexid"
 version = "2021.1006"
 description = "Variable width build numbers with lexical ordering."
-category = "dev"
 optional = false
 python-versions = ">=2.7"
 files = [
@@ -892,7 +856,6 @@ files = [
 name = "makefun"
 version = "1.15.1"
 description = "Small library to dynamically create python functions."
-category = "main"
 optional = false
 python-versions = "*"
 files = [
@@ -904,7 +867,6 @@ files = [
 name = "mako"
 version = "1.2.4"
 description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -924,7 +886,6 @@ testing = ["pytest"]
 name = "markdown-it-py"
 version = "2.2.0"
 description = "Python port of markdown-it. Markdown parsing, done right!"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -949,7 +910,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
 name = "markupsafe"
 version = "2.1.3"
 description = "Safely add untrusted strings to HTML/XML markup."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1009,7 +969,6 @@ files = [
 name = "mdit-py-plugins"
 version = "0.3.5"
 description = "Collection of plugins for markdown-it-py"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1029,7 +988,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
 name = "mdurl"
 version = "0.1.2"
 description = "Markdown URL utilities"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1041,7 +999,6 @@ files = [
 name = "myst-parser"
 version = "0.18.1"
 description = "An extended commonmark compliant parser, with bridges to docutils & sphinx."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1068,7 +1025,6 @@ testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov",
 name = "packaging"
 version = "23.1"
 description = "Core utilities for Python packages"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1080,7 +1036,6 @@ files = [
 name = "passlib"
 version = "1.7.4"
 description = "comprehensive password hashing framework supporting over 30 schemes"
-category = "main"
 optional = false
 python-versions = "*"
 files = [
@@ -1101,7 +1056,6 @@ totp = ["cryptography"]
 name = "pathlib2"
 version = "2.3.7.post1"
 description = "Object-oriented filesystem paths"
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -1116,7 +1070,6 @@ six = "*"
 name = "pluggy"
 version = "1.0.0"
 description = "plugin and hook calling mechanisms for python"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -1132,7 +1085,6 @@ testing = ["pytest", "pytest-benchmark"]
 name = "pycparser"
 version = "2.21"
 description = "C parser in Python"
-category = "main"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 files = [
@@ -1144,7 +1096,6 @@ files = [
 name = "pydantic"
 version = "1.10.9"
 description = "Data validation and settings management using python type hints"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1197,7 +1148,6 @@ email = ["email-validator (>=1.0.3)"]
 name = "pygments"
 version = "2.15.1"
 description = "Pygments is a syntax highlighting package written in Python."
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1212,7 +1162,6 @@ plugins = ["importlib-metadata"]
 name = "pyjwt"
 version = "2.6.0"
 description = "JSON Web Token implementation in Python"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1233,7 +1182,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
 name = "pytest"
 version = "7.3.2"
 description = "pytest: simple powerful testing with Python"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1256,7 +1204,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no
 name = "pytest-asyncio"
 version = "0.19.0"
 description = "Pytest support for asyncio"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1274,7 +1221,6 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy
 name = "pytest-pretty"
 version = "1.2.0"
 description = "pytest plugin for printing summary data as I want it"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1290,7 +1236,6 @@ rich = ">=12"
 name = "python-dotenv"
 version = "0.20.0"
 description = "Read key-value pairs from a .env file and set them as environment variables"
-category = "main"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -1305,7 +1250,6 @@ cli = ["click (>=5.0)"]
 name = "python-multipart"
 version = "0.0.6"
 description = "A streaming multipart parser for Python"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1320,7 +1264,6 @@ dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatc
 name = "pyyaml"
 version = "6.0"
 description = "YAML parser and emitter for Python"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -1370,7 +1313,6 @@ files = [
 name = "requests"
 version = "2.31.0"
 description = "Python HTTP for Humans."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1392,7 +1334,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
 name = "rfc3986"
 version = "1.5.0"
 description = "Validating URI References per RFC 3986"
-category = "main"
 optional = false
 python-versions = "*"
 files = [
@@ -1410,7 +1351,6 @@ idna2008 = ["idna"]
 name = "rich"
 version = "12.6.0"
 description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
-category = "main"
 optional = false
 python-versions = ">=3.6.3,<4.0.0"
 files = [
@@ -1429,7 +1369,6 @@ jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
 name = "setuptools"
 version = "67.8.0"
 description = "Easily download, build, install, upgrade, and uninstall Python packages"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1446,7 +1385,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (
 name = "six"
 version = "1.16.0"
 description = "Python 2 and 3 compatibility utilities"
-category = "dev"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
 files = [
@@ -1458,7 +1396,6 @@ files = [
 name = "sniffio"
 version = "1.3.0"
 description = "Sniff out which async library your code is running under"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1470,7 +1407,6 @@ files = [
 name = "snowballstemmer"
 version = "2.2.0"
 description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
-category = "dev"
 optional = false
 python-versions = "*"
 files = [
@@ -1482,7 +1418,6 @@ files = [
 name = "sphinx"
 version = "5.3.0"
 description = "Python documentation generator"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -1518,7 +1453,6 @@ test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"]
 name = "sphinx-argparse"
 version = "0.4.0"
 description = "A sphinx extension that automatically documents argparse commands and options"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1536,7 +1470,6 @@ markdown = ["CommonMark (>=0.5.6)"]
 name = "sphinx-rtd-theme"
 version = "1.2.2"
 description = "Read the Docs theme for Sphinx"
-category = "dev"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
 files = [
@@ -1556,7 +1489,6 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client", "wheel"]
 name = "sphinxcontrib-applehelp"
 version = "1.0.4"
 description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
-category = "dev"
 optional = false
 python-versions = ">=3.8"
 files = [
@@ -1572,7 +1504,6 @@ test = ["pytest"]
 name = "sphinxcontrib-devhelp"
 version = "1.0.2"
 description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -1588,7 +1519,6 @@ test = ["pytest"]
 name = "sphinxcontrib-htmlhelp"
 version = "2.0.1"
 description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
-category = "dev"
 optional = false
 python-versions = ">=3.8"
 files = [
@@ -1604,7 +1534,6 @@ test = ["html5lib", "pytest"]
 name = "sphinxcontrib-jquery"
 version = "4.1"
 description = "Extension to include jQuery on newer Sphinx releases"
-category = "dev"
 optional = false
 python-versions = ">=2.7"
 files = [
@@ -1619,7 +1548,6 @@ Sphinx = ">=1.8"
 name = "sphinxcontrib-jsmath"
 version = "1.0.1"
 description = "A sphinx extension which renders display math in HTML via JavaScript"
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -1634,7 +1562,6 @@ test = ["flake8", "mypy", "pytest"]
 name = "sphinxcontrib-qthelp"
 version = "1.0.3"
 description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -1650,7 +1577,6 @@ test = ["pytest"]
 name = "sphinxcontrib-serializinghtml"
 version = "1.1.5"
 description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
-category = "dev"
 optional = false
 python-versions = ">=3.5"
 files = [
@@ -1666,7 +1592,6 @@ test = ["pytest"]
 name = "sqlalchemy"
 version = "1.4.41"
 description = "Database Abstraction Library"
-category = "dev"
 optional = false
 python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
 files = [
@@ -1714,7 +1639,7 @@ files = [
 ]
 
 [package.dependencies]
-greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"}
+greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\")"}
 
 [package.extras]
 aiomysql = ["aiomysql", "greenlet (!=0.4.17)"]
@@ -1741,7 +1666,6 @@ sqlcipher = ["sqlcipher3-binary"]
 name = "sqlalchemy-utils"
 version = "0.38.3"
 description = "Various utility functions for SQLAlchemy."
-category = "dev"
 optional = false
 python-versions = "~=3.6"
 files = [
@@ -1770,7 +1694,6 @@ url = ["furl (>=0.4.1)"]
 name = "sqlalchemy2-stubs"
 version = "0.0.2a34"
 description = "Typing Stubs for SQLAlchemy 1.4"
-category = "dev"
 optional = false
 python-versions = ">=3.6"
 files = [
@@ -1785,7 +1708,6 @@ typing-extensions = ">=3.7.4"
 name = "sqlmodel"
 version = "0.0.8"
 description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness."
-category = "dev"
 optional = false
 python-versions = ">=3.6.1,<4.0.0"
 files = [
@@ -1802,7 +1724,6 @@ sqlalchemy2-stubs = "*"
 name = "starlette"
 version = "0.27.0"
 description = "The little ASGI library that shines."
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1821,7 +1742,6 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam
 name = "toml"
 version = "0.10.2"
 description = "Python Library for Tom's Obvious, Minimal Language"
-category = "dev"
 optional = false
 python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 files = [
@@ -1833,7 +1753,6 @@ files = [
 name = "tomli"
 version = "2.0.1"
 description = "A lil' TOML parser"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1845,7 +1764,6 @@ files = [
 name = "typing-extensions"
 version = "4.6.3"
 description = "Backported and Experimental Type Hints for Python 3.7+"
-category = "main"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1857,7 +1775,6 @@ files = [
 name = "urllib3"
 version = "2.0.3"
 description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1875,7 +1792,6 @@ zstd = ["zstandard (>=0.18.0)"]
 name = "uvicorn"
 version = "0.20.0"
 description = "The lightning-fast ASGI server."
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [
@@ -1894,7 +1810,6 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)",
 name = "zipp"
 version = "3.15.0"
 description = "Backport of pathlib-compatible object wrapper for zip files"
-category = "dev"
 optional = false
 python-versions = ">=3.7"
 files = [


Test patch:
diff --git a/tests/test_task.py b/tests/test_task.py
index 80c8af1c5..92cac2b80 100644
--- a/tests/test_task.py
+++ b/tests/test_task.py
@@ -283,17 +283,44 @@ async def test_task_edit(
     assert res.retcode == 0
 
 
-async def test_task_delete(register_user, invoke):
+async def test_task_delete(
+    register_user, user_factory, invoke, invoke_as_superuser
+):
     """
-    This is currently a placeholder test, since task-delete is not implemented
+    Test task delete
     """
-    res = await invoke("task new _name _command _source")
-    debug(res.data)
+    NAME = "_name"
+    VERSION = "1.0.0"
+    task = await invoke(
+        f"task new {NAME} _command _source --version {VERSION}"
+    )
+    task.show()
+    assert task.retcode == 0
+    task_id = task.data["id"]
+
+    # Test access control
+    with pytest.raises(SystemExit):
+        EMAIL, PASSWORD = "foo@bar.xy", "abc"
+        await user_factory(email=EMAIL, password=PASSWORD)
+        res = await invoke(
+            f"-u {EMAIL} -p {PASSWORD} task delete --id {task_id}"
+        )
+    # Test fail "id and version"
+    with pytest.raises(SystemExit):
+        await invoke(f"task delete --id {task_id} --version {VERSION}")
+    # Test fail "name and wrong version"
+    with pytest.raises(SystemExit):
+        await invoke(f"task delete --name {NAME} --version INVALID_VERSION")
+
+    # Test sucess
+    res = await invoke("task list")
+    task_list = res.data
+    assert len(task_list) == 1
+    res = await invoke(f"task delete --name {NAME} --version {VERSION}")
     assert res.retcode == 0
-    task_id = res.data["id"]
-    with pytest.raises(NotImplementedError):
-        debug(f"task delete --id {task_id}")
-        res = await invoke(f"task delete --id {task_id}")
+    res = await invoke("task list")
+    task_list = res.data
+    assert len(task_list) == 0
 
 
 async def test_task_list(register_user, invoke, testdata_path):