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

Issue:
Make client sync
There is no reason for this additional complexity


EDIT: note that this issue does not concern the fixture that runs fractal-server via uvicorn.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de83a62f5..bde0a151a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 # 1.4.3 (unreleased)
 
+* Make `fractal-client` a fully synchronous client, by removing all `async`/`await` (\#592).
 * Improve handling of `AuthenticationError` and `ConnectionError`, and handle uncaught `Exception` (\#587).
 * Testing:
     * Adapt `job_factory` and tests to the presence of new `timestamp_created` attributes in `fractal-server` (\#589).
diff --git a/fractal_client/__main__.py b/fractal_client/__main__.py
deleted file mode 100644
index 0a3d1fc5b..000000000
--- a/fractal_client/__main__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import asyncio
-
-from fractal_client.client import main
-
-
-def run():
-    asyncio.run(main())
-
-
-if __name__ == "__main__":
-    run()
diff --git a/fractal_client/authclient.py b/fractal_client/authclient.py
index 4aad48ff2..b2a6a6bd1 100644
--- a/fractal_client/authclient.py
+++ b/fractal_client/authclient.py
@@ -1,7 +1,7 @@
 from pathlib import Path
 
 import jwt
-from httpx import AsyncClient
+from httpx import Client
 from jwt.exceptions import ExpiredSignatureError
 
 from .config import settings
@@ -14,7 +14,7 @@ class AuthenticationError(ValueError):
 class AuthToken:
     def __init__(
         self,
-        client: AsyncClient,
+        client: Client,
         username: str,
         password: str,
     ):
@@ -28,12 +28,12 @@ def __init__(
         except FileNotFoundError:
             pass
 
-    async def _get_fresh_token(self):
+    def _get_fresh_token(self):
         data = dict(
             username=self.username,
             password=self.password,
         )
-        res = await self.client.post(
+        res = self.client.post(
             f"{settings.FRACTAL_SERVER}/auth/token/login/", data=data
         )
         if res.status_code != 200:
@@ -72,13 +72,13 @@ def expired(self):
         except ExpiredSignatureError:
             return True
 
-    async def header(self):
-        token = await self.__call__()
+    def header(self):
+        token = self.__call__()
         return dict(Authorization=f"Bearer {token}")
 
-    async def __call__(self):
+    def __call__(self):
         if self.expired:
-            await self._get_fresh_token()
+            self._get_fresh_token()
         return self.token
 
 
@@ -93,8 +93,8 @@ def __init__(
         self.username = username
         self.password = password
 
-    async def __aenter__(self):
-        self.client = AsyncClient()
+    def __enter__(self):
+        self.client = Client()
         self.auth = AuthToken(
             client=self.client,
             username=self.username,
@@ -102,25 +102,17 @@ async def __aenter__(self):
         )
         return self
 
-    async def __aexit__(self, exc_type, exc_value, traceback):
-        await self.client.aclose()
+    def __exit__(self, *args):
+        self.client.close()
 
-    async def get(self, *args, **kwargs):
-        return await self.client.get(
-            headers=await self.auth.header(), *args, **kwargs
-        )
+    def get(self, *args, **kwargs):
+        return self.client.get(headers=self.auth.header(), *args, **kwargs)
 
-    async def post(self, *args, **kwargs):
-        return await self.client.post(
-            headers=await self.auth.header(), *args, **kwargs
-        )
+    def post(self, *args, **kwargs):
+        return self.client.post(headers=self.auth.header(), *args, **kwargs)
 
-    async def patch(self, *args, **kwargs):
-        return await self.client.patch(
-            headers=await self.auth.header(), *args, **kwargs
-        )
+    def patch(self, *args, **kwargs):
+        return self.client.patch(headers=self.auth.header(), *args, **kwargs)
 
-    async def delete(self, *args, **kwargs):
-        return await self.client.delete(
-            headers=await self.auth.header(), *args, **kwargs
-        )
+    def delete(self, *args, **kwargs):
+        return self.client.delete(headers=self.auth.header(), *args, **kwargs)
diff --git a/fractal_client/client.py b/fractal_client/client.py
index 9a98407eb..aad808311 100644
--- a/fractal_client/client.py
+++ b/fractal_client/client.py
@@ -12,14 +12,13 @@
 Institute for Biomedical Research and Pelkmans Lab from the University of
 Zurich.
 """
-import asyncio
 import logging
 from sys import argv
 from typing import List
 from typing import Tuple
 from typing import Union
 
-from httpx import AsyncClient
+from httpx import Client
 from httpx import ConnectError
 
 from . import cmd
@@ -68,7 +67,7 @@ def _check_credentials(
     return (username, password)
 
 
-async def handle(cli_args: List[str] = argv):
+def handle(cli_args: List[str] = argv):
     args = parser_main.parse_args(cli_args[1:])
 
     # Set logging level
@@ -93,8 +92,8 @@ async def handle(cli_args: List[str] = argv):
         kwargs.pop("cmd")
 
         if args.cmd == "version":
-            async with AsyncClient() as client:
-                interface = await handler(client, **kwargs)
+            with Client() as client:
+                interface = handler(client, **kwargs)
         else:
             # Extract (and remove) username/password for AuthClient from kwargs
             username = kwargs.pop("user") or settings.FRACTAL_USER
@@ -102,10 +101,8 @@ async def handle(cli_args: List[str] = argv):
             username, password = _check_credentials(
                 username=username, password=password
             )
-            async with AuthClient(
-                username=username, password=password
-            ) as client:
-                interface = await handler(client, **kwargs)
+            with AuthClient(username=username, password=password) as client:
+                interface = handler(client, **kwargs)
     except AuthenticationError as e:
         return PrintInterface(retcode=1, data=e.args[0])
     except ConnectError as e:
@@ -123,11 +120,11 @@ async def handle(cli_args: List[str] = argv):
     return interface
 
 
-async def main():
-    interface = await handle()
+def main():
+    interface = handle()
     interface.show()
     exit(interface.retcode)
 
 
 if __name__ == "__main__":
-    asyncio.run(main())
+    main()
diff --git a/fractal_client/cmd/__init__.py b/fractal_client/cmd/__init__.py
index 5be6d2bf8..8fa364495 100644
--- a/fractal_client/cmd/__init__.py
+++ b/fractal_client/cmd/__init__.py
@@ -1,4 +1,4 @@
-from httpx import AsyncClient
+from httpx import Client
 
 from ..authclient import AuthClient
 from ..config import settings
@@ -54,7 +54,7 @@ def get_kwargs(_parameters, _kwargs):
     return {k: _kwargs.get(k) for k in _parameters if k in _kwargs}
 
 
-async def project(
+def project(
     client: AuthClient,
     subcmd: str,
     batch: bool = False,
@@ -64,13 +64,13 @@ async def project(
     if subcmd == "new":
         parameters = ["name"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await post_project(client, batch=batch, **function_kwargs)
+        iface = post_project(client, batch=batch, **function_kwargs)
     elif subcmd == "show":
         parameters = ["project_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_project(client, **function_kwargs)
+        iface = get_project(client, **function_kwargs)
     elif subcmd == "list":
-        iface = await get_project_list(client)
+        iface = get_project_list(client)
     elif subcmd == "edit":
         parameters = [
             "project_id",
@@ -79,7 +79,7 @@ async def project(
             "remove_read_only",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await patch_project(client, **function_kwargs)
+        iface = patch_project(client, **function_kwargs)
     elif subcmd == "add-dataset":
         parameters = [
             "project_id",
@@ -89,18 +89,18 @@ async def project(
             "make_read_only",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await post_dataset(client, batch=batch, **function_kwargs)
+        iface = post_dataset(client, batch=batch, **function_kwargs)
     elif subcmd == "delete":
         parameters = ["project_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await delete_project(client, **function_kwargs)
+        iface = delete_project(client, **function_kwargs)
     else:
         raise NoCommandError(f"Command project {subcmd} not found")
 
     return iface
 
 
-async def dataset(
+def dataset(
     client: AuthClient,
     subcmd: str,
     batch: bool = False,
@@ -109,15 +109,15 @@ async def dataset(
     if subcmd == "show":
         parameters = ["project_id", "dataset_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_dataset(client, **function_kwargs)
+        iface = get_dataset(client, **function_kwargs)
     elif subcmd == "add-resource":
         parameters = ["project_id", "dataset_id", "path"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await post_resource(client, batch=batch, **function_kwargs)
+        iface = post_resource(client, batch=batch, **function_kwargs)
     elif subcmd == "rm-resource":
         parameters = ["project_id", "dataset_id", "resource_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await delete_resource(client, **function_kwargs)
+        iface = delete_resource(client, **function_kwargs)
     elif subcmd == "edit":
         parameters = [
             "project_id",
@@ -129,25 +129,25 @@ async def dataset(
             "remove_read_only",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await patch_dataset(client, **function_kwargs)
+        iface = patch_dataset(client, **function_kwargs)
     elif subcmd == "delete":
         parameters = ["project_id", "dataset_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await delete_dataset(client, **function_kwargs)
+        iface = delete_dataset(client, **function_kwargs)
     elif subcmd == "history":
         parameters = ["project_id", "dataset_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_dataset_history(client, **function_kwargs)
+        iface = get_dataset_history(client, **function_kwargs)
     elif subcmd == "status":
         parameters = ["project_id", "dataset_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_dataset_status(client, **function_kwargs)
+        iface = get_dataset_status(client, **function_kwargs)
     else:
         raise NoCommandError(f"Command dataset {subcmd} not found")
     return iface
 
 
-async def task(
+def task(
     client: AuthClient,
     subcmd: str,
     batch: bool = False,
@@ -155,7 +155,7 @@ async def task(
 ) -> BaseInterface:
 
     if subcmd == "list":
-        iface = await get_task_list(client)
+        iface = get_task_list(client)
     elif subcmd == "collect":
         parameters = [
             "package",
@@ -165,11 +165,11 @@ async def task(
             "pinned_dependency",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await task_collect_pip(client, batch=batch, **function_kwargs)
+        iface = task_collect_pip(client, batch=batch, **function_kwargs)
     elif subcmd == "check-collection":
         parameters = ["state_id", "include_logs", "do_not_separate_logs"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await task_collection_check(client, **function_kwargs)
+        iface = task_collection_check(client, **function_kwargs)
     elif subcmd == "new":
         parameters = [
             "name",
@@ -183,7 +183,7 @@ async def task(
             "args_schema_version",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await post_task(client, batch=batch, **function_kwargs)
+        iface = post_task(client, batch=batch, **function_kwargs)
     elif subcmd == "edit":
         parameters = [
             "id",
@@ -199,17 +199,17 @@ async def task(
             "new_args_schema_version",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await patch_task(client, **function_kwargs)
+        iface = patch_task(client, **function_kwargs)
     elif subcmd == "delete":
         parameters = ["id", "name", "version"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await delete_task(client, **function_kwargs)
+        iface = delete_task(client, **function_kwargs)
     else:
         raise NoCommandError(f"Command task {subcmd} not found")
     return iface
 
 
-async def workflow(
+def workflow(
     client: AuthClient,
     subcmd: str,
     batch: bool = False,
@@ -218,23 +218,23 @@ async def workflow(
     if subcmd == "show":
         parameters = ["project_id", "workflow_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_workflow(client, **function_kwargs)
+        iface = get_workflow(client, **function_kwargs)
     elif subcmd == "new":
         parameters = ["name", "project_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await post_workflow(client, batch=batch, **function_kwargs)
+        iface = post_workflow(client, batch=batch, **function_kwargs)
     elif subcmd == "list":
         parameters = ["project_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_workflow_list(client, batch=batch, **function_kwargs)
+        iface = get_workflow_list(client, batch=batch, **function_kwargs)
     elif subcmd == "edit":
         parameters = ["project_id", "workflow_id", "new_name"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await patch_workflow(client, **function_kwargs)
+        iface = patch_workflow(client, **function_kwargs)
     elif subcmd == "delete":
         parameters = ["project_id", "workflow_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await delete_workflow(client, **function_kwargs)
+        iface = delete_workflow(client, **function_kwargs)
     elif subcmd == "add-task":
         parameters = [
             "project_id",
@@ -247,7 +247,7 @@ async def workflow(
             "meta_file",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await post_workflowtask(client, batch=batch, **function_kwargs)
+        iface = post_workflowtask(client, batch=batch, **function_kwargs)
     elif subcmd == "edit-task":
         parameters = [
             "project_id",
@@ -257,11 +257,11 @@ async def workflow(
             "meta_file",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await patch_workflowtask(client, **function_kwargs)
+        iface = patch_workflowtask(client, **function_kwargs)
     elif subcmd == "rm-task":
         parameters = ["project_id", "workflow_id", "workflow_task_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await delete_workflowtask(client, **function_kwargs)
+        iface = delete_workflowtask(client, **function_kwargs)
     elif subcmd == "apply":
         parameters = [
             "project_id",
@@ -273,21 +273,21 @@ async def workflow(
             "last_task_index",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await workflow_apply(client, batch=batch, **function_kwargs)
+        iface = workflow_apply(client, batch=batch, **function_kwargs)
     elif subcmd == "import":
         parameters = ["project_id", "json_file"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await workflow_import(client, batch=batch, **function_kwargs)
+        iface = workflow_import(client, batch=batch, **function_kwargs)
     elif subcmd == "export":
         parameters = ["project_id", "workflow_id", "json_file"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await workflow_export(client, **function_kwargs)
+        iface = workflow_export(client, **function_kwargs)
     else:
         raise NoCommandError(f"Command workflow {subcmd} not found")
     return iface
 
 
-async def job(
+def job(
     client: AuthClient,
     subcmd: str,
     batch: bool = False,
@@ -296,26 +296,26 @@ async def job(
     if subcmd == "list":
         parameters = ["project_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_job_list(client, batch=batch, **function_kwargs)
+        iface = get_job_list(client, batch=batch, **function_kwargs)
     elif subcmd == "show":
         parameters = ["project_id", "job_id", "do_not_separate_logs"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_job(client, batch=batch, **function_kwargs)
+        iface = get_job(client, batch=batch, **function_kwargs)
     elif subcmd == "download-logs":
         parameters = ["project_id", "job_id", "output_folder"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await get_job_logs(client, **function_kwargs)
+        iface = get_job_logs(client, **function_kwargs)
     elif subcmd == "stop":
         parameters = ["project_id", "job_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await stop_job(client, **function_kwargs)
+        iface = stop_job(client, **function_kwargs)
     else:
         raise NoCommandError(f"Command job {subcmd} not found")
     return iface
 
 
-async def version(client: AsyncClient, **kwargs) -> PrintInterface:
-    res = await client.get(f"{settings.FRACTAL_SERVER}/api/alive/")
+def version(client: Client, **kwargs) -> PrintInterface:
+    res = client.get(f"{settings.FRACTAL_SERVER}/api/alive/")
     data = res.json()
 
     return PrintInterface(
@@ -329,7 +329,7 @@ async def version(client: AsyncClient, **kwargs) -> PrintInterface:
     )
 
 
-async def user(
+def user(
     client: AuthClient, subcmd: str, batch: bool = False, **kwargs
 ) -> BaseInterface:
     if subcmd == "register":
@@ -342,13 +342,13 @@ async def user(
             "superuser",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await user_register(client, batch=batch, **function_kwargs)
+        iface = user_register(client, batch=batch, **function_kwargs)
     elif subcmd == "list":
-        iface = await user_list(client)
+        iface = user_list(client)
     elif subcmd == "show":
         parameters = ["user_id"]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await user_show(client, **function_kwargs)
+        iface = user_show(client, **function_kwargs)
     elif subcmd == "edit":
         parameters = [
             "user_id",
@@ -363,9 +363,9 @@ async def user(
             "remove_verified",
         ]
         function_kwargs = get_kwargs(parameters, kwargs)
-        iface = await user_edit(client, **function_kwargs)
+        iface = user_edit(client, **function_kwargs)
     elif subcmd == "whoami":
-        iface = await user_whoami(client, batch=batch)
+        iface = user_whoami(client, batch=batch)
     else:
         raise NoCommandError(f"Command user {subcmd} not found")
 
diff --git a/fractal_client/cmd/_aux_task_caching.py b/fractal_client/cmd/_aux_task_caching.py
index 642a34a81..5f634b5e2 100644
--- a/fractal_client/cmd/_aux_task_caching.py
+++ b/fractal_client/cmd/_aux_task_caching.py
@@ -45,11 +45,11 @@ class FractalCacheError(RuntimeError):
 _TaskList = list[dict[str, Any]]
 
 
-async def _fetch_task_list(client: AuthClient) -> _TaskList:
+def _fetch_task_list(client: AuthClient) -> _TaskList:
     """
     Fetch task list through an API request.
     """
-    res = await client.get(f"{settings.BASE_URL}/task/")
+    res = client.get(f"{settings.BASE_URL}/task/")
     task_list = check_response(res, expected_status_code=200)
     return task_list
 
@@ -79,11 +79,11 @@ def _write_task_list_to_cache(task_list: _TaskList) -> None:
         json.dump(task_list, f, indent=4)
 
 
-async def refresh_task_cache(client: AuthClient) -> _TaskList:
+def refresh_task_cache(client: AuthClient) -> _TaskList:
     """
     Return task list after fetching it, sorting it and writing to cache file.
     """
-    task_list = await _fetch_task_list(client)
+    task_list = _fetch_task_list(client)
     task_list = _sort_task_list(task_list)
     _write_task_list_to_cache(task_list)
     return task_list
@@ -197,7 +197,7 @@ def _search_in_task_list(
                 )
 
 
-async def get_task_id_from_cache(
+def get_task_id_from_cache(
     client: AuthClient, task_name: str, version: Optional[str] = None
 ) -> int:
     """
@@ -221,7 +221,7 @@ async def get_task_id_from_cache(
             task_list = json.load(f)
         already_refreshed_cache = False
     else:
-        task_list = await refresh_task_cache(client)
+        task_list = refresh_task_cache(client)
         already_refreshed_cache = True
 
     try:
@@ -236,7 +236,7 @@ async def get_task_id_from_cache(
             raise e
         else:
             # Cache may be out-of-date, refresh it and try again
-            task_list = await refresh_task_cache(client)
+            task_list = refresh_task_cache(client)
             task_id = _search_in_task_list(
                 task_list=task_list,
                 name=task_name,
diff --git a/fractal_client/cmd/_dataset.py b/fractal_client/cmd/_dataset.py
index 4920f5331..e3220788c 100644
--- a/fractal_client/cmd/_dataset.py
+++ b/fractal_client/cmd/_dataset.py
@@ -12,7 +12,7 @@
 from ..response import check_response
 
 
-async def post_dataset(
+def post_dataset(
     client: AuthClient,
     *,
     project_id: int,
@@ -40,7 +40,7 @@ async def post_dataset(
     if type:
         dataset["type"] = type
 
-    res = await client.post(
+    res = client.post(
         f"{settings.BASE_URL}/project/{project_id}/dataset/",
         json=dataset,
     )
@@ -51,7 +51,7 @@ async def post_dataset(
         return RichJsonInterface(retcode=0, data=new_dataset)
 
 
-async def post_resource(
+def post_resource(
     client: AuthClient,
     *,
     project_id: int,
@@ -60,7 +60,7 @@ async def post_resource(
     batch: bool = False,
 ) -> BaseInterface:
 
-    res = await client.post(
+    res = client.post(
         (
             f"{settings.BASE_URL}/project/{project_id}/"
             f"dataset/{dataset_id}/resource/"
@@ -74,14 +74,14 @@ async def post_resource(
         return RichJsonInterface(retcode=0, data=new_resource)
 
 
-async def delete_resource(
+def delete_resource(
     client: AuthClient,
     *,
     project_id: int,
     dataset_id: int,
     resource_id: int,
 ) -> BaseInterface:
-    res = await client.delete(
+    res = client.delete(
         (
             f"{settings.BASE_URL}/project/{project_id}/"
             f"dataset/{dataset_id}/resource/{resource_id}/"
@@ -91,7 +91,7 @@ async def delete_resource(
     return PrintInterface(retcode=0, data="")
 
 
-async def patch_dataset(
+def patch_dataset(
     client: AuthClient,
     *,
     project_id: int,
@@ -121,7 +121,7 @@ async def patch_dataset(
     if not dataset_update:
         return PrintInterface(retcode=1, data="Nothing to update")
 
-    res = await client.patch(
+    res = client.patch(
         (
             f"{settings.BASE_URL}/project/{project_id}/"
             f"dataset/{dataset_id}/"
@@ -132,10 +132,10 @@ async def patch_dataset(
     return RichJsonInterface(retcode=0, data=data)
 
 
-async def get_dataset(
+def get_dataset(
     client: AuthClient, *, project_id: int, dataset_id: int
 ) -> BaseInterface:
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/project/{project_id}/dataset/{dataset_id}/"
     )
     from rich.console import Group
@@ -166,21 +166,21 @@ async def get_dataset(
     return RichConsoleInterface(retcode=0, data=group)
 
 
-async def delete_dataset(
+def delete_dataset(
     client: AuthClient, *, project_id: int, dataset_id: int
 ) -> PrintInterface:
 
-    res = await client.delete(
+    res = client.delete(
         f"{settings.BASE_URL}/project/{project_id}/dataset/{dataset_id}/"
     )
     check_response(res, expected_status_code=204)
     return PrintInterface(retcode=0, data="")
 
 
-async def get_dataset_history(
+def get_dataset_history(
     client: AuthClient, *, project_id: int, dataset_id: int
 ) -> BaseInterface:
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/project/{project_id}/dataset/{dataset_id}/"
         "export_history/"
     )
@@ -188,10 +188,10 @@ async def get_dataset_history(
     return RichJsonInterface(retcode=0, data=history_workflow)
 
 
-async def get_dataset_status(
+def get_dataset_status(
     client: AuthClient, *, project_id: int, dataset_id: int
 ) -> BaseInterface:
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/project/{project_id}/dataset/{dataset_id}/"
         "status/"
     )
diff --git a/fractal_client/cmd/_job.py b/fractal_client/cmd/_job.py
index a8717785b..ea1adc265 100644
--- a/fractal_client/cmd/_job.py
+++ b/fractal_client/cmd/_job.py
@@ -14,7 +14,7 @@
 from ..response import check_response
 
 
-async def get_job(
+def get_job(
     client: AuthClient,
     *,
     project_id: int,
@@ -26,9 +26,7 @@ async def get_job(
     Query the status of a workflow-execution job
     """
 
-    res = await client.get(
-        f"{settings.BASE_URL}/project/{project_id}/job/{job_id}/"
-    )
+    res = client.get(f"{settings.BASE_URL}/project/{project_id}/job/{job_id}/")
     job = check_response(res, expected_status_code=200)
     if batch:
         return PrintInterface(retcode=0, data=job["status"])
@@ -43,11 +41,11 @@ async def get_job(
             )
 
 
-async def get_job_list(
+def get_job_list(
     client: AuthClient, *, project_id: int, batch: bool = False
 ) -> BaseInterface:
 
-    res = await client.get(f"{settings.BASE_URL}/project/{project_id}/job/")
+    res = client.get(f"{settings.BASE_URL}/project/{project_id}/job/")
     jobs = check_response(res, expected_status_code=200)
 
     if batch:
@@ -74,7 +72,7 @@ async def get_job_list(
         return RichConsoleInterface(retcode=0, data=table)
 
 
-async def get_job_logs(
+def get_job_logs(
     client: AuthClient,
     *,
     project_id: int,
@@ -89,7 +87,7 @@ async def get_job_logs(
         )
 
     # Send request to server
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/project/{project_id}/job/{job_id}/download/"
     )
 
@@ -142,14 +140,14 @@ async def get_job_logs(
     )
 
 
-async def stop_job(
+def stop_job(
     client: AuthClient, *, project_id: int, job_id: int
 ) -> BaseInterface:
     """
     Stop a workflow-execution job
     """
 
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/project/{project_id}/job/{job_id}/stop/"
     )
     check_response(res, expected_status_code=202)
diff --git a/fractal_client/cmd/_project.py b/fractal_client/cmd/_project.py
index 9d7a06074..d084290e4 100644
--- a/fractal_client/cmd/_project.py
+++ b/fractal_client/cmd/_project.py
@@ -12,7 +12,7 @@
 from ..response import check_response
 
 
-async def post_project(
+def post_project(
     client: AuthClient,
     *,
     name: str,
@@ -21,7 +21,7 @@ async def post_project(
     # Prepare a ProjectCreate request body
     payload = dict(name=name)
     # Send API request
-    res = await client.post(f"{settings.BASE_URL}/project/", json=payload)
+    res = client.post(f"{settings.BASE_URL}/project/", json=payload)
     project = check_response(res, expected_status_code=201)
     if batch:
         return PrintInterface(retcode=0, data=project["id"])
@@ -29,9 +29,9 @@ async def post_project(
         return RichJsonInterface(retcode=0, data=project)
 
 
-async def get_project_list(client: AuthClient) -> RichConsoleInterface:
+def get_project_list(client: AuthClient) -> RichConsoleInterface:
 
-    res = await client.get(f"{settings.BASE_URL}/project/")
+    res = client.get(f"{settings.BASE_URL}/project/")
     projects = check_response(res, expected_status_code=200)
 
     table = Table(title="Project List")
@@ -55,28 +55,20 @@ async def get_project_list(client: AuthClient) -> RichConsoleInterface:
     return RichConsoleInterface(retcode=0, data=table)
 
 
-async def get_project(
-    client: AuthClient, *, project_id: int
-) -> RichJsonInterface:
-    res = await client.get(
-        f"{settings.BASE_URL}/project/{project_id}/",
-    )
+def get_project(client: AuthClient, *, project_id: int) -> RichJsonInterface:
+    res = client.get(f"{settings.BASE_URL}/project/{project_id}/")
     project = check_response(res, expected_status_code=200)
     return RichJsonInterface(retcode=0, data=project)
 
 
-async def delete_project(
-    client: AuthClient, *, project_id: int
-) -> PrintInterface:
+def delete_project(client: AuthClient, *, project_id: int) -> PrintInterface:
 
-    res = await client.delete(
-        f"{settings.BASE_URL}/project/{project_id}/",
-    )
+    res = client.delete(f"{settings.BASE_URL}/project/{project_id}/")
     check_response(res, expected_status_code=204)
     return PrintInterface(retcode=0, data="")
 
 
-async def patch_project(
+def patch_project(
     client: AuthClient,
     *,
     project_id: int,
@@ -95,7 +87,7 @@ async def patch_project(
     if not project_update:
         return PrintInterface(retcode=1, data="Nothing to update")
 
-    res = await client.patch(
+    res = client.patch(
         f"{settings.BASE_URL}/project/{project_id}/", json=project_update
     )
     new_project = check_response(res, expected_status_code=200)
diff --git a/fractal_client/cmd/_task.py b/fractal_client/cmd/_task.py
index 8f0e79c03..05d102e6e 100644
--- a/fractal_client/cmd/_task.py
+++ b/fractal_client/cmd/_task.py
@@ -14,12 +14,12 @@
 from ._aux_task_caching import refresh_task_cache
 
 
-async def get_task_list(client: AuthClient) -> RichJsonInterface:
-    task_list = await refresh_task_cache(client=client)
+def get_task_list(client: AuthClient) -> RichJsonInterface:
+    task_list = refresh_task_cache(client=client)
     return RichJsonInterface(retcode=0, data=task_list)
 
 
-async def task_collect_pip(
+def task_collect_pip(
     client: AuthClient,
     *,
     package: str,
@@ -51,7 +51,7 @@ async def task_collect_pip(
             for _name, _version in (p.split("=") for p in pinned_dependency)
         }
 
-    res = await client.post(
+    res = client.post(
         f"{settings.BASE_URL}/task/collect/pip/", json=task_collect
     )
 
@@ -63,7 +63,7 @@ async def task_collect_pip(
         return RichJsonInterface(retcode=0, data=state)
 
 
-async def task_collection_check(
+def task_collection_check(
     client: AuthClient,
     *,
     state_id: int,
@@ -71,7 +71,7 @@ async def task_collection_check(
     do_not_separate_logs: bool = False,
 ) -> BaseInterface:
 
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/task/collect/{state_id}/?verbose={include_logs}"
     )
     state = check_response(res, expected_status_code=200)
@@ -89,7 +89,7 @@ async def task_collection_check(
         )
 
 
-async def post_task(
+def post_task(
     client: AuthClient,
     *,
     name: str,
@@ -121,7 +121,7 @@ async def post_task(
     if args_schema_version:
         task["args_schema_version"] = args_schema_version
 
-    res = await client.post(f"{settings.BASE_URL}/task/", json=task)
+    res = client.post(f"{settings.BASE_URL}/task/", json=task)
     new_task = check_response(res, expected_status_code=201)
 
     if batch:
@@ -130,7 +130,7 @@ async def post_task(
         return RichJsonInterface(retcode=0, data=new_task)
 
 
-async def patch_task(
+def patch_task(
     client: AuthClient,
     *,
     id: Optional[int] = None,
@@ -154,7 +154,7 @@ async def patch_task(
             sys.exit(1)
     else:
         try:
-            id = await get_task_id_from_cache(
+            id = get_task_id_from_cache(
                 client=client, task_name=name, version=version
             )
         except FractalCacheError as e:
@@ -184,14 +184,12 @@ async def patch_task(
     if not task_update:
         return PrintInterface(retcode=1, data="Nothing to update")
 
-    res = await client.patch(
-        f"{settings.BASE_URL}/task/{id}/", json=task_update
-    )
+    res = client.patch(f"{settings.BASE_URL}/task/{id}/", json=task_update)
     new_task = check_response(res, expected_status_code=200)
     return RichJsonInterface(retcode=0, data=new_task)
 
 
-async def delete_task(
+def delete_task(
     client: AuthClient,
     *,
     id: Optional[int] = None,
@@ -207,12 +205,12 @@ async def delete_task(
             sys.exit(1)
     else:
         try:
-            id = await get_task_id_from_cache(
+            id = 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}/")
+    res = client.delete(f"{settings.BASE_URL}/task/{id}/")
     check_response(res, expected_status_code=204)
     return PrintInterface(retcode=0, data="")
diff --git a/fractal_client/cmd/_user.py b/fractal_client/cmd/_user.py
index 5c130a00e..c041b05b4 100644
--- a/fractal_client/cmd/_user.py
+++ b/fractal_client/cmd/_user.py
@@ -8,7 +8,7 @@
 from ..response import check_response
 
 
-async def user_register(
+def user_register(
     client: AuthClient,
     *,
     new_email: str,
@@ -42,7 +42,7 @@ async def user_register(
         else:
             return PrintInterface(retcode=1, data="Passwords do not match.")
 
-    res = await client.post(
+    res = client.post(
         f"{settings.FRACTAL_SERVER}/auth/register/", json=new_user
     )
     data = check_response(res, expected_status_code=201)
@@ -50,7 +50,7 @@ async def user_register(
     if superuser or verified:
         patch_payload = dict(is_superuser=superuser, is_verified=verified)
         user_id = data["id"]
-        res = await client.patch(
+        res = client.patch(
             f"{settings.FRACTAL_SERVER}/auth/users/{user_id}/",
             json=patch_payload,
         )
@@ -62,19 +62,19 @@ async def user_register(
         return RichJsonInterface(retcode=0, data=data)
 
 
-async def user_list(client: AuthClient) -> RichJsonInterface:
-    res = await client.get(f"{settings.FRACTAL_SERVER}/auth/users/")
+def user_list(client: AuthClient) -> RichJsonInterface:
+    res = client.get(f"{settings.FRACTAL_SERVER}/auth/users/")
     users = check_response(res, expected_status_code=200)
     return RichJsonInterface(retcode=0, data=users)
 
 
-async def user_show(client: AuthClient, *, user_id: str) -> RichJsonInterface:
-    res = await client.get(f"{settings.FRACTAL_SERVER}/auth/users/{user_id}/")
+def user_show(client: AuthClient, *, user_id: str) -> RichJsonInterface:
+    res = client.get(f"{settings.FRACTAL_SERVER}/auth/users/{user_id}/")
     user = check_response(res, expected_status_code=200)
     return RichJsonInterface(retcode=0, data=user)
 
 
-async def user_edit(
+def user_edit(
     client: AuthClient,
     *,
     user_id: str,
@@ -111,7 +111,7 @@ async def user_edit(
 
     if not user_update:
         return PrintInterface(retcode=1, data="Nothing to update")
-    res = await client.patch(
+    res = client.patch(
         f"{settings.FRACTAL_SERVER}/auth/users/{user_id}/", json=user_update
     )
     new_user = check_response(res, expected_status_code=200)
@@ -119,10 +119,10 @@ async def user_edit(
     return RichJsonInterface(retcode=0, data=new_user)
 
 
-async def user_whoami(
+def user_whoami(
     client: AuthClient, *, batch: bool
 ) -> Union[RichJsonInterface, PrintInterface]:
-    res = await client.get(f"{settings.FRACTAL_SERVER}/auth/current-user/")
+    res = client.get(f"{settings.FRACTAL_SERVER}/auth/current-user/")
     user = check_response(res, expected_status_code=200)
     if batch:
         return PrintInterface(retcode=0, data=user["id"])
diff --git a/fractal_client/cmd/_workflow.py b/fractal_client/cmd/_workflow.py
index 81e48f2dd..214aa3207 100644
--- a/fractal_client/cmd/_workflow.py
+++ b/fractal_client/cmd/_workflow.py
@@ -14,14 +14,14 @@
 from ._aux_task_caching import get_task_id_from_cache
 
 
-async def post_workflow(
+def post_workflow(
     client: AuthClient, *, name: str, project_id: int, batch: bool = False
 ) -> BaseInterface:
     workflow = dict(
         name=name,
         project_id=project_id,
     )
-    res = await client.post(
+    res = client.post(
         f"{settings.BASE_URL}/project/{project_id}/workflow/",
         json=workflow,
     )
@@ -32,38 +32,36 @@ async def post_workflow(
         return RichJsonInterface(retcode=0, data=workflow)
 
 
-async def get_workflow_list(
+def get_workflow_list(
     client: AuthClient, *, project_id: int, batch: bool = False
 ) -> RichJsonInterface:
 
-    res = await client.get(
-        f"{settings.BASE_URL}/project/{project_id}/workflow/"
-    )
+    res = client.get(f"{settings.BASE_URL}/project/{project_id}/workflow/")
     workflow_list = check_response(res, expected_status_code=200)
     return RichJsonInterface(retcode=0, data=workflow_list)
 
 
-async def delete_workflow(
+def delete_workflow(
     client: AuthClient, *, project_id: int, workflow_id: int
 ) -> BaseInterface:
-    res = await client.delete(
+    res = client.delete(
         f"{settings.BASE_URL}/project/{project_id}/workflow/{workflow_id}/"
     )
     check_response(res, expected_status_code=204)
     return PrintInterface(retcode=0, data="")
 
 
-async def get_workflow(
+def get_workflow(
     client: AuthClient, *, project_id: int, workflow_id: int
 ) -> RichJsonInterface:
-    res = await client.get(
+    res = client.get(
         f"{settings.BASE_URL}/project/{project_id}/workflow/{workflow_id}/"
     )
     workflow = check_response(res, expected_status_code=200)
     return RichJsonInterface(retcode=0, data=workflow)
 
 
-async def post_workflowtask(
+def post_workflowtask(
     client: AuthClient,
     *,
     project_id: int,
@@ -86,7 +84,7 @@ async def post_workflowtask(
             sys.exit(1)
     else:
         try:
-            task_id = await get_task_id_from_cache(
+            task_id = get_task_id_from_cache(
                 client=client, task_name=task_name, version=task_version
             )
         except FractalCacheError as e:
@@ -106,7 +104,7 @@ async def post_workflowtask(
             meta = json.load(f)
             workflow_task["meta"] = meta
 
-    res = await client.post(
+    res = client.post(
         (
             f"{settings.BASE_URL}/project/{project_id}/"
             f"workflow/{workflow_id}/wftask/"
@@ -122,7 +120,7 @@ async def post_workflowtask(
         return RichJsonInterface(retcode=0, data=workflow_task)
 
 
-async def patch_workflowtask(
+def patch_workflowtask(
     client: AuthClient,
     *,
     project_id: int,
@@ -151,7 +149,7 @@ async def patch_workflowtask(
             meta = json.load(f)
             payload["meta"] = meta
 
-    res = await client.patch(
+    res = client.patch(
         (
             f"{settings.BASE_URL}/project/{project_id}/"
             f"workflow/{workflow_id}/wftask/{workflow_task_id}/"
@@ -163,7 +161,7 @@ async def patch_workflowtask(
     return RichJsonInterface(retcode=0, data=workflow_task)
 
 
-async def delete_workflowtask(
+def delete_workflowtask(
     client: AuthClient,
     *,
     project_id: int,
@@ -171,7 +169,7 @@ async def delete_workflowtask(
     workflow_task_id: int,
 ) -> BaseInterface:
 
-    res = await client.delete(
+    res = client.delete(
         f"{settings.BASE_URL}/project/{project_id}/"
         f"workflow/{workflow_id}/wftask/{workflow_task_id}/"
     )
@@ -179,7 +177,7 @@ async def delete_workflowtask(
     return PrintInterface(retcode=0, data="")
 
 
-async def patch_workflow(
+def patch_workflow(
     client: AuthClient,
     *,
     project_id: int,
@@ -189,7 +187,7 @@ async def patch_workflow(
 
     workflow_update = dict(name=new_name)
 
-    res = await client.patch(
+    res = client.patch(
         f"{settings.BASE_URL}/project/{project_id}/workflow/{workflow_id}/",
         json=workflow_update,
     )
@@ -197,7 +195,7 @@ async def patch_workflow(
     return RichJsonInterface(retcode=0, data=new_workflow)
 
 
-async def workflow_apply(
+def workflow_apply(
     client: AuthClient,
     *,
     project_id: int,
@@ -228,7 +226,7 @@ async def workflow_apply(
         f"&output_dataset_id={output_dataset_id}"
     )
 
-    res = await client.post(
+    res = client.post(
         (
             f"{settings.BASE_URL}/project/{project_id}/workflow/{workflow_id}/"
             f"apply/?{query_parameters}"
@@ -243,13 +241,13 @@ async def workflow_apply(
         return RichJsonInterface(retcode=0, data=apply_wf_read)
 
 
-async def workflow_import(
+def workflow_import(
     client: AuthClient, *, project_id: int, json_file: str, batch: bool = False
 ) -> BaseInterface:
     with Path(json_file).open("r") as f:
         workflow = json.load(f)
 
-    res = await client.post(
+    res = client.post(
         f"{settings.BASE_URL}/project/{project_id}/workflow/import/",
         json=workflow,
     )
@@ -277,14 +275,14 @@ async def workflow_import(
         return RichJsonInterface(retcode=0, data=wf_read)
 
 
-async def workflow_export(
+def workflow_export(
     client: AuthClient,
     *,
     project_id: int,
     workflow_id: int,
     json_file: str,
 ) -> BaseInterface:
-    res = await client.get(
+    res = client.get(
         (
             f"{settings.BASE_URL}/project/{project_id}/"
             f"workflow/{workflow_id}/export/"
diff --git a/poetry.lock b/poetry.lock
index aeac39136..01df1c8f4 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1453,23 +1453,6 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
 [package.extras]
 testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
 
-[[package]]
-name = "pytest-asyncio"
-version = "0.19.0"
-description = "Pytest support for asyncio"
-optional = false
-python-versions = ">=3.7"
-files = [
-    {file = "pytest-asyncio-0.19.0.tar.gz", hash = "sha256:ac4ebf3b6207259750bc32f4c1d8fcd7e79739edbc67ad0c58dd150b1d072fed"},
-    {file = "pytest_asyncio-0.19.0-py3-none-any.whl", hash = "sha256:7a97e37cfe1ed296e2e84941384bdd37c376453912d397ed39293e0916f521fa"},
-]
-
-[package.dependencies]
-pytest = ">=6.1.0"
-
-[package.extras]
-testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"]
-
 [[package]]
 name = "pytest-pretty"
 version = "1.2.0"
@@ -2060,4 +2043,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.9"
-content-hash = "d6254192c874f67e96f640087b3e5f2d3f72f988a0639cc9d4a75dbbd2cc409e"
+content-hash = "19a458c1991e32a56389ff79d46aabd0ec2fe6d1d89415c8312b5f5620fe453e"
diff --git a/pyproject.toml b/pyproject.toml
index c71bcf0a7..739eb0c7d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -37,7 +37,6 @@ pytest = "^7.1.2"
 bumpver = "^2022.1118"
 coverage = {extras = ["toml"], version = "^6.5.0"}
 pytest-pretty = "^1.1.0"
-pytest-asyncio = "^0.19.0"
 fractal-server = { git = "https://github.com/fractal-analytics-platform/fractal-server.git", branch = "main"}
 
 
@@ -58,9 +57,6 @@ mkdocs-include-markdown-plugin = { version = "4.0.4", python = "^3.8,<3.12" }
 requires = ["poetry-core"]
 build-backend = "poetry.core.masonry.api"
 
-[tool.pytest.ini_options]
-asyncio_mode = "auto"
-
 [tool.bumpver]
 current_version = "1.4.2"
 version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
@@ -78,7 +74,7 @@ push = true
 ]
 
 [tool.poetry.scripts]
-fractal = "fractal_client.__main__:run"
+fractal = "fractal_client.client:main"
 
 [tool.coverage.run]
 branch = true


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index 90e1af840..e12f63d93 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -4,7 +4,7 @@
 from pathlib import Path
 
 import pytest
-from httpx import AsyncClient
+from httpx import Client
 
 
 # These three variables must be defined before the first import of config.py
@@ -41,16 +41,16 @@ def testdata_path() -> Path:
 
 
 @pytest.fixture
-async def client():
-    async with AsyncClient(timeout=10) as client:
+def client():
+    with Client(timeout=10) as client:
         yield client
 
 
 @pytest.fixture
-async def client_superuser():
+def client_superuser():
     from fractal_client.authclient import AuthClient
 
-    async with AuthClient(
+    with AuthClient(
         username="admin@fractal.xy",
         password="1234",
     ) as client_superuser:
@@ -70,24 +70,24 @@ def _remove_session():
 
 
 @pytest.fixture
-async def invoke():
+def invoke():
     from fractal_client.client import handle
 
-    async def __invoke(args: str):
+    def __invoke(args: str):
         _remove_session()
-        return await handle(_clisplit(args))
+        return handle(_clisplit(args))
 
     return __invoke
 
 
 @pytest.fixture
-async def invoke_as_superuser():
+def invoke_as_superuser():
     from fractal_client.client import handle
 
-    async def __invoke(args: str):
+    def __invoke(args: str):
         _remove_session()
         new_args = f"--user admin@fractal.xy --password 1234 {args}"
-        return await handle(_clisplit(new_args))
+        return handle(_clisplit(new_args))
 
     return __invoke
 
diff --git a/tests/fixtures_testserver.py b/tests/fixtures_testserver.py
index cfaf413a6..eb96b5745 100644
--- a/tests/fixtures_testserver.py
+++ b/tests/fixtures_testserver.py
@@ -1,4 +1,3 @@
-import asyncio
 import logging
 from os import environ
 from typing import Optional
@@ -45,7 +44,7 @@ def _get_settings():
 
 
 @pytest.fixture(scope="function", autouse=True)
-async def testserver(override_server_settings):
+def testserver(override_server_settings):
     import uvicorn
     from multiprocessing import Process
     from fractal_server.app.db import DB
@@ -61,13 +60,11 @@ async def testserver(override_server_settings):
     # cf. https://stackoverflow.com/a/57816608/283972
 
     def run_server():
-        asyncio.run(
-            uvicorn.run(
-                "fractal_server.main:app",
-                port=PORT,
-                log_level="debug",
-                timeout_keep_alive=10,
-            )
+        uvicorn.run(
+            "fractal_server.main:app",
+            port=PORT,
+            log_level="debug",
+            timeout_keep_alive=10,
         )
 
     proc = Process(target=run_server, args=(), daemon=True)
@@ -97,21 +94,21 @@ def run_server():
 
 
 @pytest.fixture
-async def db(testserver):
+def db(testserver):
     """
     NOTE: Only use this fixture within other fixtures!!!
     """
-    from fractal_server.app.db import get_db
+    from fractal_server.app.db import get_sync_db
 
-    async for db in get_db():
+    for db in get_sync_db():
         yield db
 
 
 @pytest.fixture
-async def task_factory(db):
+def task_factory(db):
     from fractal_server.app.models.task import Task
 
-    async def _task_factory(**task_args_override):
+    def _task_factory(**task_args_override):
         task_args = dict(
             name="test_task",
             command="cmd",
@@ -122,56 +119,56 @@ async def _task_factory(**task_args_override):
         task_args.update(task_args_override)
         t = Task(**task_args)
         db.add(t)
-        await db.commit()
-        await db.refresh(t)
+        db.commit()
+        db.refresh(t)
         return t
 
     return _task_factory
 
 
 @pytest.fixture
-async def project_factory(db):
+def project_factory(db):
     from fractal_server.app.models.project import Project
 
-    async def _project_factory(user_id=None, **project_args_override):
+    def _project_factory(user_id=None, **project_args_override):
         project_args = dict(name="name")
         project_args.update(project_args_override)
         p = Project(**project_args)
         if user_id:
             from fractal_server.app.security import User
 
-            user = await db.get(User, user_id)
+            user = db.get(User, user_id)
             p.user_list.append(user)
         db.add(p)
-        await db.commit()
-        await db.refresh(p)
+        db.commit()
+        db.refresh(p)
         return p
 
     return _project_factory
 
 
 @pytest.fixture
-async def workflow_factory(db, project_factory):
+def workflow_factory(db, project_factory):
     from fractal_server.app.models.workflow import Workflow
 
-    async def _workflow_factory(**wf_args_override):
+    def _workflow_factory(**wf_args_override):
         wf_args = dict(name="name")
         wf_args.update(wf_args_override)
         wf = Workflow(**wf_args)
         db.add(wf)
-        await db.commit()
-        await db.refresh(wf)
+        db.commit()
+        db.refresh(wf)
         return wf
 
     return _workflow_factory
 
 
 @pytest.fixture
-async def job_factory(db):
+def job_factory(db):
     from fractal_server.app.models.job import ApplyWorkflow
     from fractal_server.utils import get_timestamp
 
-    async def _job_factory(**job_args_override):
+    def _job_factory(**job_args_override):
         job_args = dict(
             project_id=1,
             input_dataset_id=1,
@@ -209,16 +206,16 @@ async def _job_factory(**job_args_override):
         job_args.update(job_args_override)
         j = ApplyWorkflow(**job_args)
         db.add(j)
-        await db.commit()
-        await db.refresh(j)
+        db.commit()
+        db.refresh(j)
         return j
 
     return _job_factory
 
 
 @pytest.fixture
-async def user_factory(testserver, db, client_superuser):
-    async def __register_user(
+def user_factory(testserver, db, client_superuser):
+    def __register_user(
         email: str,
         password: str,
         slurm_user: Optional[str] = None,
@@ -231,14 +228,14 @@ async def __register_user(
         if username:
             new_user["username"] = username
         # Register user via API call
-        res = await client_superuser.post(
+        res = client_superuser.post(
             f"http://localhost:{PORT}/auth/register/",
             json=new_user,
         )
         assert res.status_code == 201
         user_id = res.json()["id"]
         # Make user verified via API call
-        res = await client_superuser.patch(
+        res = client_superuser.patch(
             f"http://localhost:{PORT}/auth/users/{user_id}/",
             json=dict(is_verified=True),
         )
@@ -249,10 +246,10 @@ async def __register_user(
 
 
 @pytest.fixture
-async def register_user(user_factory, db):
+def register_user(user_factory, db):
     from fractal_server.app.models import UserOAuth
 
-    created_user = await user_factory(
+    created_user = user_factory(
         email=environ["FRACTAL_USER"],
         password=environ["FRACTAL_PASSWORD"],
         username=environ["FRACTAL_USERNAME"],
@@ -260,6 +257,6 @@ async def register_user(user_factory, db):
 
     yield created_user
 
-    db_user = await db.get(UserOAuth, created_user["id"])
-    await db.delete(db_user)
-    await db.commit()
+    db_user = db.get(UserOAuth, created_user["id"])
+    db.delete(db_user)
+    db.commit()
diff --git a/tests/test_auth.py b/tests/test_auth.py
index 1f9b4856b..09f3eec59 100644
--- a/tests/test_auth.py
+++ b/tests/test_auth.py
@@ -7,7 +7,7 @@
 from fractal_client.authclient import AuthToken
 
 
-async def test_auth_registered(client, register_user):
+def test_auth_registered(client, register_user):
     """
     GIVEN an existing user
     WHEN fetching a token
@@ -18,11 +18,11 @@ async def test_auth_registered(client, register_user):
         username=environ.get("FRACTAL_USER"),
         password=environ.get("FRACTAL_PASSWORD"),
     )
-    token = await auth()
+    token = auth()
     assert token
 
 
-async def test_auth_fail(client):
+def test_auth_fail(client):
     """
     GIVEN no user registered
     WHEN fetching a token
@@ -30,5 +30,5 @@ async def test_auth_fail(client):
     """
     with pytest.raises(AuthenticationError) as err:
         auth = AuthToken(client, username="foo", password="bar")
-        await auth()
+        auth()
     debug(err.value)
diff --git a/tests/test_client.py b/tests/test_client.py
index bd34b7873..44af3dfb9 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -12,14 +12,14 @@
 DEFAULT_TEST_EMAIL = environ["FRACTAL_USER"]
 
 
-async def test_version(invoke):
-    iface = await invoke("version")
+def test_version(invoke):
+    iface = invoke("version")
     debug(iface.data)
     assert f"version: {__VERSION__}" in iface.data
     assert iface.retcode == 0
 
 
-async def test_server():
+def test_server():
     """
     GIVEN a testserver
     WHEN it gets called
@@ -30,15 +30,15 @@ async def test_server():
     assert res.status_code == 200
 
 
-async def test_register_user(register_user, invoke):
-    res = await invoke("user whoami")
+def test_register_user(register_user, invoke):
+    res = invoke("user whoami")
     user = res.data
     debug(user)
     assert res.retcode == 0
     assert user["email"] == DEFAULT_TEST_EMAIL
 
 
-async def test_user_override(user_factory, invoke):
+def test_user_override(user_factory, invoke):
     """
     GIVEN a user whose credentials differ from those of the environment
     WHEN the client is invoked with -u and -p
@@ -46,25 +46,25 @@ async def test_user_override(user_factory, invoke):
     """
     EMAIL = "other_user@exact-lab.it"
     PASSWORD = "other_password"
-    await user_factory(email=EMAIL, password=PASSWORD)
+    user_factory(email=EMAIL, password=PASSWORD)
 
-    res = await invoke(f"-u {EMAIL} -p {PASSWORD} project list")
+    res = invoke(f"-u {EMAIL} -p {PASSWORD} project list")
     assert res.retcode == 0
 
 
-async def test_bad_credentials(invoke):
+def test_bad_credentials(invoke):
     """
     GIVEN a registered user
     WHEN wrong credentials are passed
     THEN the client returns an error
     """
-    res = await invoke("-u nouser@exact-lab.it -p nopassword project list")
+    res = invoke("-u nouser@exact-lab.it -p nopassword project list")
     res.show()
     assert res.retcode != 0
     assert "BAD_CREDENTIALS" in res.data
 
 
-async def test_missing_credentials(override_settings):
+def test_missing_credentials(override_settings):
     """
     GIVEN an invocation with missing credentials
     THEN the client raises a MissingCredentialsError
@@ -73,24 +73,24 @@ async def test_missing_credentials(override_settings):
     # Remove credentials from settings
     override_settings(FRACTAL_USER=None, FRACTAL_PASSWORD=None)
 
-    res = await handle(shlex.split("fractal user whoami"))
+    res = handle(shlex.split("fractal user whoami"))
     debug(res.data)
     assert res.retcode == 1
 
 
-async def test_connecterror(client, override_settings):
+def test_connecterror(client, override_settings):
     override_settings(
         FRACTAL_USER="admin@fractal.xy",
         FRACTAL_PASSWORD="1234",
         FRACTAL_SERVER="http://localhost:12345",
     )
-    res = await handle(shlex.split("fractal user whoami"))
+    res = handle(shlex.split("fractal user whoami"))
     debug(res.data)
     assert "ConnectError" in res.data
     assert "Hint: is http://localhost:12345 alive?" in res.data
 
 
-async def test_argparse_abbreviation(invoke_as_superuser):
+def test_argparse_abbreviation(invoke_as_superuser):
     """
     Check that argparse abbreviations are disabled on at least one command.
 
@@ -100,14 +100,10 @@ async def test_argparse_abbreviation(invoke_as_superuser):
     """
 
     # Successful invoke
-    res = await invoke_as_superuser(
-        "user register test@mail.com secret --superuser"
-    )
+    res = invoke_as_superuser("user register test@mail.com secret --superuser")
     res.show()
     assert res.retcode == 0
 
     # Failed (abbreviation-based) invoke
     with pytest.raises(SystemExit):
-        await invoke_as_superuser(
-            "user register test2@mail.com secret2 --super"
-        )
+        invoke_as_superuser("user register test2@mail.com secret2 --super")
diff --git a/tests/test_dataset.py b/tests/test_dataset.py
index 92d438636..5106afebb 100644
--- a/tests/test_dataset.py
+++ b/tests/test_dataset.py
@@ -4,12 +4,12 @@
 from devtools import debug
 
 
-async def test_create_dataset(register_user, invoke, tmp_path):
+def test_create_dataset(register_user, invoke, tmp_path):
     """
     Test some specific branches of the post_dataset function and parser.
     """
 
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
 
     METADATA = {"some": "value"}
@@ -19,7 +19,7 @@ async def test_create_dataset(register_user, invoke, tmp_path):
     with open(file_metadata, "w") as f:
         json.dump(METADATA, f)
 
-    res = await invoke(
+    res = invoke(
         (
             f"project add-dataset {project_id} MyDS "
             f"--metadata {file_metadata} "
@@ -31,58 +31,52 @@ async def test_create_dataset(register_user, invoke, tmp_path):
     assert res.data["meta"] == METADATA
     assert res.data["type"] == TYPE
 
-    res = await invoke(f"--batch project add-dataset {project_id} MyNewDS")
+    res = invoke(f"--batch project add-dataset {project_id} MyNewDS")
     debug(res.data)
     assert res.retcode == 0
 
 
-async def test_add_resource(register_user, invoke):
+def test_add_resource(register_user, invoke):
 
     # Create a project with its default dataset
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
 
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
     assert res.data["resource_list"] == []
 
     # Add a resource
     PATH = "/some/path"
-    res = await invoke(
-        f"dataset add-resource {project_id} {dataset_id} {PATH}"
-    )
+    res = invoke(f"dataset add-resource {project_id} {dataset_id} {PATH}")
     res.show()
     assert res.retcode == 0
     assert res.data["path"] == PATH
     assert res.data["dataset_id"] == dataset_id
 
 
-async def test_add_resource_relative_path(register_user, invoke):
-    res = await invoke("project new prj0")
+def test_add_resource_relative_path(register_user, invoke):
+    res = invoke("project new prj0")
     project_id = res.data["id"]
 
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
     assert res.data["resource_list"] == []
 
     PATH = "../new/resource/path"
     with pytest.raises(SystemExit):
-        res = await invoke(
-            f"dataset add-resource {project_id} {dataset_id} {PATH}"
-        )
+        res = invoke(f"dataset add-resource {project_id} {dataset_id} {PATH}")
 
     PATH = "local-folder/new/resource/path"
     with pytest.raises(SystemExit):
-        res = await invoke(
-            f"dataset add-resource {project_id} {dataset_id} {PATH}"
-        )
+        res = invoke(f"dataset add-resource {project_id} {dataset_id} {PATH}")
 
 
-async def test_edit_dataset(register_user, invoke, tmp_path):
-    res = await invoke("project new prj0")
+def test_edit_dataset(register_user, invoke, tmp_path):
+    res = invoke("project new prj0")
     project_id = res.data["id"]
 
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
 
     TYPE = "this_new_type"
@@ -92,40 +86,32 @@ async def test_edit_dataset(register_user, invoke, tmp_path):
     with open(META_FILE, "w") as f:
         json.dump(META, f)
 
-    res = await invoke(
-        f"dataset edit {project_id} {dataset_id} --new-name {NAME}"
-    )
+    res = invoke(f"dataset edit {project_id} {dataset_id} --new-name {NAME}")
     res.show()
     assert res.data["name"] == NAME
     assert res.retcode == 0
 
-    res = await invoke(
-        f"dataset edit {project_id} {dataset_id} --new-type {TYPE}"
-    )
+    res = invoke(f"dataset edit {project_id} {dataset_id} --new-type {TYPE}")
     res.show()
     assert res.data["name"] == NAME
     assert res.data["type"] == TYPE
     assert res.retcode == 0
 
-    res = await invoke(
-        f"dataset edit {project_id} {dataset_id} --make-read-only"
-    )
+    res = invoke(f"dataset edit {project_id} {dataset_id} --make-read-only")
     res.show()
     assert res.data["name"] == NAME
     assert res.data["type"] == TYPE
     assert res.data["read_only"]
     assert res.retcode == 0
 
-    res = await invoke(
-        f"dataset edit {project_id} {dataset_id} --remove-read-only"
-    )
+    res = invoke(f"dataset edit {project_id} {dataset_id} --remove-read-only")
     res.show()
     assert res.data["name"] == NAME
     assert res.data["type"] == TYPE
     assert not res.data["read_only"]
     assert res.retcode == 0
 
-    res = await invoke(
+    res = invoke(
         f"dataset edit {project_id} {dataset_id} --meta-file {META_FILE}"
     )
     res.show()
@@ -136,53 +122,51 @@ async def test_edit_dataset(register_user, invoke, tmp_path):
     assert res.retcode == 0
 
     with pytest.raises(SystemExit):
-        res = await invoke(
+        res = invoke(
             f"dataset edit {project_id} {dataset_id} "
             "--make-read-only --remove-read-only"
         )
 
 
-async def test_delete_dataset(register_user, invoke):
+def test_delete_dataset(register_user, invoke):
     # Create a project with its default dataset
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
 
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
 
     # Delete dataset
-    res = await invoke(f"dataset delete {project_id} {dataset_id}")
+    res = invoke(f"dataset delete {project_id} {dataset_id}")
 
     # Check that dataset show fails
     with pytest.raises(SystemExit):
-        res = await invoke(f"dataset show {project_id} {dataset_id}")
+        res = invoke(f"dataset show {project_id} {dataset_id}")
 
 
-async def test_show_dataset(register_user, invoke):
+def test_show_dataset(register_user, invoke):
     # Create a project with its default dataset
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
 
-    res = await invoke(f"dataset show {project_id} {dataset_id}")
+    res = invoke(f"dataset show {project_id} {dataset_id}")
     res.show()
     assert res.retcode == 0
 
 
-async def test_delete_resource(register_user, invoke):
+def test_delete_resource(register_user, invoke):
     # Create a project with its default dataset
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
     assert res.data["resource_list"] == []
 
     # Add a resource
     PATH = "/some/path"
-    res = await invoke(
-        f"dataset add-resource {project_id} {dataset_id} {PATH}"
-    )
+    res = invoke(f"dataset add-resource {project_id} {dataset_id} {PATH}")
     res.show()
     assert res.retcode == 0
     assert res.data["path"] == PATH
@@ -190,52 +174,52 @@ async def test_delete_resource(register_user, invoke):
     resource_id = res.data["id"]
 
     # Show dataset
-    res = await invoke(f"dataset show {project_id} {dataset_id}")
+    res = invoke(f"dataset show {project_id} {dataset_id}")
     res.show()
 
     # Remove a resource
-    res = await invoke(
+    res = invoke(
         f"dataset rm-resource {project_id} {dataset_id} {resource_id}"
     )
     assert res.retcode == 0
 
     # Check that the resource was removed
-    res = await invoke(f"dataset show {project_id} {dataset_id}")
+    res = invoke(f"dataset show {project_id} {dataset_id}")
     res.show()
 
     # Add a new resource, and check that it has the same id as the one that was
     # removed
-    res = await invoke(
+    res = invoke(
         f"--batch dataset add-resource {project_id} {dataset_id} {PATH}"
     )
     assert res.retcode == 0
     assert res.data == resource_id
 
 
-async def test_dataset_history_command(register_user, invoke):
+def test_dataset_history_command(register_user, invoke):
     """
     Only test the client interface, not the fractal-server business logic.
     """
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
 
     debug(f"dataset history {project_id} {dataset_id}")
-    res = await invoke(f"dataset history {project_id} {dataset_id}")
+    res = invoke(f"dataset history {project_id} {dataset_id}")
     res.show()
     assert res.retcode == 0
 
 
-async def test_dataset_status_command(register_user, invoke):
+def test_dataset_status_command(register_user, invoke):
     """
     Only test the client interface, not the fractal-server business logic.
     """
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    res = await invoke(f"project add-dataset {project_id} test_name")
+    res = invoke(f"project add-dataset {project_id} test_name")
     dataset_id = res.data["id"]
 
-    res = await invoke(f"dataset status {project_id} {dataset_id}")
+    res = invoke(f"dataset status {project_id} {dataset_id}")
     res.show()
     assert res.retcode == 0
diff --git a/tests/test_job.py b/tests/test_job.py
index acf47cbdc..5451054d5 100644
--- a/tests/test_job.py
+++ b/tests/test_job.py
@@ -9,7 +9,7 @@
 
 
 @pytest.mark.parametrize("status", ["done", "failed"])
-async def test_job_show(
+def test_job_show(
     register_user,
     invoke,
     tmp_path: Path,
@@ -25,14 +25,14 @@ async def test_job_show(
     """
 
     # Create mock Workflow/ApplyWorkflow objects
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
+    wf = workflow_factory(project_id=project_id)
     debug(wf)
     log = LOG
     workflow_path = tmp_path / f"workflow_{wf.id}"
     workflow_path.mkdir()
-    job = await job_factory(
+    job = job_factory(
         working_dir=workflow_path.as_posix(),
         worfklow_id=wf.id,
         status=status,
@@ -50,7 +50,7 @@ async def test_job_show(
     # Check `job show` output
     cmd = f"job show {project_id} {job.id}"
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     assert res.data["status"] == status
     debug(res.data)
@@ -60,13 +60,13 @@ async def test_job_show(
 
     # Check `job show` output with --batch
     cmd = f"--batch job show {project_id} {job.id}"
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     assert res.data == status
 
     # Check `job show` output with `--do-not-separate-logs`
     cmd = f"job show {project_id} {job.id} --do-not-separate-logs"
-    res = await invoke(cmd)
+    res = invoke(cmd)
     debug(res.data)
     assert res.retcode == 0
     assert res.data["status"] == status
@@ -74,7 +74,7 @@ async def test_job_show(
     assert res.data["log"] == LOG
 
 
-async def test_job_list(
+def test_job_list(
     register_user,
     invoke,
     tmp_path: Path,
@@ -89,13 +89,13 @@ async def test_job_list(
     """
 
     # Create mock Project/Workflow/ApplyWorkflow objects
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    wf_1 = await workflow_factory(project_id=project_id)
-    wf_2 = await workflow_factory(project_id=project_id)
+    wf_1 = workflow_factory(project_id=project_id)
+    wf_2 = workflow_factory(project_id=project_id)
     wd_1 = tmp_path / f"workflow_{wf_1.id}"
     wd_2 = tmp_path / f"workflow_{wf_2.id}"
-    job1 = await job_factory(
+    job1 = job_factory(
         working_dir=wd_1.as_posix(),
         worfklow_id=wf_1.id,
         status="running",
@@ -107,7 +107,7 @@ async def test_job_list(
             "timestamp_created": str(get_timestamp()),
         },
     )
-    job2 = await job_factory(
+    job2 = job_factory(
         working_dir=wd_2.as_posix(),
         worfklow_id=wf_2.id,
         status="done",
@@ -125,7 +125,7 @@ async def test_job_list(
     # Check `job list` output with --batch option
     cmd = f"--batch job list {project_id}"
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     debug(res.data)
     assert res.retcode == 0
     job_ids = [int(i) for i in res.data.split()]
@@ -135,7 +135,7 @@ async def test_job_list(
     # Check `job list` output
     cmd = f"job list {project_id}"
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     debug(res.data)
     # There is not much to assert here, apart from successful invocation of the
@@ -143,7 +143,7 @@ async def test_job_list(
     res.show()
 
 
-async def test_job_download_logs(
+def test_job_download_logs(
     register_user,
     invoke,
     tmp_path: Path,
@@ -155,11 +155,11 @@ async def test_job_download_logs(
     """
 
     # Create mock Workflow/ApplyWorkflow objects
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
+    wf = workflow_factory(project_id=project_id)
     wd = tmp_path / f"workflow_{wf.id}"
-    job = await job_factory(
+    job = job_factory(
         working_dir=wd.as_posix(),
         worfklow_id=wf.id,
         status="running",
@@ -179,7 +179,7 @@ async def test_job_download_logs(
         f"--output {str(output_fail)}"
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 1
 
     # Check standard `job download-logs` output
@@ -189,7 +189,7 @@ async def test_job_download_logs(
         f"--output {str(output)}"
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     debug(res.data)
 
@@ -201,7 +201,7 @@ async def test_job_download_logs(
     assert contents == LOG
 
 
-async def test_job_stop(
+def test_job_stop(
     register_user,
     invoke,
     tmp_path: Path,
@@ -224,12 +224,12 @@ async def test_job_stop(
     """
 
     # Create mock Workflow/ApplyWorkflow objects
-    res = await invoke("project new prj0")
+    res = invoke("project new prj0")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
+    wf = workflow_factory(project_id=project_id)
     workflow_path = tmp_path / f"workflow_{wf.id}"
     workflow_path.mkdir()
-    job = await job_factory(
+    job = job_factory(
         working_dir=workflow_path.as_posix(),
         worfklow_id=wf.id,
     )
@@ -239,7 +239,7 @@ async def test_job_stop(
     cmd = f"job stop {project_id} {job.id}"
     debug(cmd)
     with pytest.raises(SystemExit):
-        res = await invoke(cmd)
+        res = invoke(cmd)
     debug(caplog.text)
     assert "Stopping a job execution is not implemented" in caplog.text
     caplog.clear()
diff --git a/tests/test_project.py b/tests/test_project.py
index 846ccaed9..266e90a52 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -2,76 +2,76 @@
 from devtools import debug
 
 
-async def test_project_create(register_user, invoke):
+def test_project_create(register_user, invoke):
     PROJECT_NAME = "project_name"
-    res = await invoke(f"project new {PROJECT_NAME}")
+    res = invoke(f"project new {PROJECT_NAME}")
     debug(res)
     assert res.data["name"] == PROJECT_NAME
 
 
-async def test_project_delete(register_user, invoke):
+def test_project_delete(register_user, invoke):
 
     # Create project
-    res = await invoke("project new MyProj1")
+    res = invoke("project new MyProj1")
     res.show()
     project_id_1 = res.data["id"]
 
     # Show project
-    res = await invoke(f"project show {project_id_1}")
+    res = invoke(f"project show {project_id_1}")
     res.show()
 
     # Delete project
-    res = await invoke(f"project delete {project_id_1}")
+    res = invoke(f"project delete {project_id_1}")
     assert res.retcode == 0
 
     # Try to show deleted project, and fail
     with pytest.raises(SystemExit):
-        res = await invoke(f"project show {project_id_1}")
+        res = invoke(f"project show {project_id_1}")
 
 
-async def test_project_create_batch(register_user, invoke):
-    res = await invoke("--batch project new MyProj1")
+def test_project_create_batch(register_user, invoke):
+    res = invoke("--batch project new MyProj1")
     debug(res)
     debug(res.data)
     project_id = int(res.data)
     assert project_id == 1
 
 
-async def test_project_list(register_user, invoke):
-    res = await invoke("project list")
+def test_project_list(register_user, invoke):
+    res = invoke("project list")
     debug(res)
     debug(vars(res.data))
     assert len(res.data.rows) == 0
 
     res.show()
 
-    res = await invoke("--batch project new proj0")
+    res = invoke("--batch project new proj0")
     project0_id = res.data
-    res = await invoke(f"--batch project add-dataset {project0_id} NAME")
-    res = await invoke("--batch project new proj1")
+    res = invoke(f"--batch project add-dataset {project0_id} NAME")
+    res = invoke("--batch project new proj1")
 
-    res = await invoke("project list")
+    res = invoke("project list")
     debug(res)
     debug(vars(res.data))
     res.show()
     assert len(res.data.rows) == 2
 
 
-async def test_add_dataset(register_user, invoke):
+def test_add_dataset(register_user, invoke):
     DATASET_NAME = "new_ds_name"
 
-    res = await invoke("--batch project new proj0")
+    res = invoke("--batch project new proj0")
     assert res.retcode == 0
     debug(res.data)
     project_id = int(res.data)
 
-    res = await invoke(f"project add-dataset {project_id} {DATASET_NAME}")
+    res = invoke(f"project add-dataset {project_id} {DATASET_NAME}")
     assert res.retcode == 0
     res.show()
     assert res.data["name"] == DATASET_NAME
     assert not res.data["read_only"]
 
-    res = await invoke(
+    res = invoke(
         f"project add-dataset {project_id} new_{DATASET_NAME} --make-read-only"
     )
     assert res.retcode == 0
@@ -82,7 +82,7 @@ async def test_add_dataset(register_user, invoke):
 
 @pytest.mark.parametrize("new_name", ["new_name", None])
 @pytest.mark.parametrize("read_only", [True, False, None])
-async def test_edit_project(
+def test_edit_project(
     register_user,
     invoke,
     new_name,
@@ -90,7 +90,7 @@ async def test_edit_project(
     tmp_path,
 ):
     name = "name"
-    res = await invoke(f"project new {name}")
+    res = invoke(f"project new {name}")
     project = res.data
     project_id = project["id"]
 
@@ -102,7 +102,7 @@ async def test_edit_project(
     elif read_only is False:
         cmd += " --remove-read-only"
 
-    res = await invoke(cmd)
+    res = invoke(cmd)
     debug(res)
 
     if (not new_name) and (read_only is None):
diff --git a/tests/test_task.py b/tests/test_task.py
index fa82cce62..a1adab33a 100644
--- a/tests/test_task.py
+++ b/tests/test_task.py
@@ -12,7 +12,7 @@
 COLLECTION_TIMEOUT = 15.0
 
 
-async def test_task_collection_command(register_user, invoke, caplog):
+def test_task_collection_command(register_user, invoke, caplog):
     """
     Test that all `task collect` options are correctly parsed and included in
     the the payload for the API request.
@@ -22,7 +22,7 @@ async def test_task_collection_command(register_user, invoke, caplog):
     PYTHON_VERSION = "1.2"
     PACKAGE_EXTRAS = "a,b,c"
     with pytest.raises(SystemExit):
-        await invoke(
+        invoke(
             (
                 "task collect "
                 f"{PACKAGE} "
@@ -47,7 +47,7 @@ async def test_task_collection_command(register_user, invoke, caplog):
     assert payload["python_version"] == PYTHON_VERSION
 
 
-async def test_task_collection(register_user, invoke, testdata_path):
+def test_task_collection(register_user, invoke, testdata_path):
     """
     GIVEN a pip installable package containing fractal-compatible tasks
     WHEN the collection subcommand is called
@@ -57,7 +57,7 @@ async def test_task_collection(register_user, invoke, testdata_path):
     """
     PACKAGE = testdata_path / "fractal_tasks_dummy-0.1.0-py3-none-any.whl"
 
-    res0 = await invoke(f"task collect {PACKAGE}")
+    res0 = invoke(f"task collect {PACKAGE}")
     debug(res0)
     res0.show()
 
@@ -71,7 +71,7 @@ async def test_task_collection(register_user, invoke, testdata_path):
     # Wait until collection is complete
     starting_time = time.perf_counter()
     while True:
-        res1 = await invoke(f"task check-collection {state_id}")
+        res1 = invoke(f"task check-collection {state_id}")
         assert res1.retcode == 0
         res1.show()
         time.sleep(1)
@@ -80,7 +80,7 @@ async def test_task_collection(register_user, invoke, testdata_path):
         assert time.perf_counter() - starting_time < COLLECTION_TIMEOUT
 
     # Add --include-logs and --do-not-separate-logs flags
-    res2 = await invoke(
+    res2 = invoke(
         f"task check-collection {state_id}"
         " --include-logs"
         " --do-not-separate-logs"
@@ -92,11 +92,11 @@ async def test_task_collection(register_user, invoke, testdata_path):
 
     # Show again the check-collection output, without --do-not-separate-logs,
     # for visual inspection
-    res = await invoke(f"task check-collection {state_id} --include-logs")
+    res = invoke(f"task check-collection {state_id} --include-logs")
     res.show()
 
 
-async def test_repeated_task_collection(register_user, invoke, testdata_path):
+def test_repeated_task_collection(register_user, invoke, testdata_path):
     """
     GIVEN
         * a pip installable package containing fractal-compatible tasks
@@ -107,7 +107,7 @@ async def test_repeated_task_collection(register_user, invoke, testdata_path):
     """
     PACKAGE = testdata_path / "fractal_tasks_dummy-0.1.0-py3-none-any.whl"
 
-    res0 = await invoke(f"task collect {PACKAGE}")
+    res0 = invoke(f"task collect {PACKAGE}")
     debug(res0)
     res0.show()
 
@@ -121,19 +121,19 @@ async def test_repeated_task_collection(register_user, invoke, testdata_path):
     # Wait until collection is complete
     starting_time = time.perf_counter()
     while True:
-        res1 = await invoke(f"task check-collection {state_id}")
+        res1 = invoke(f"task check-collection {state_id}")
         time.sleep(1)
         if res1.data["data"]["status"] == "OK":
             break
         assert time.perf_counter() - starting_time < COLLECTION_TIMEOUT
 
     # Second collection
-    res0 = await invoke(f"task collect {PACKAGE}")
+    res0 = invoke(f"task collect {PACKAGE}")
     res0.show()
     assert res0.data["data"]["info"] == "Already installed"
 
 
-async def test_task_new(register_user, invoke, tmp_path):
+def test_task_new(register_user, invoke, tmp_path):
 
     # create a new task with just positional required args
 
@@ -142,7 +142,7 @@ async def test_task_new(register_user, invoke, tmp_path):
     with open(schema_path, "w") as f:
         json.dump(schema, f)
 
-    res = await invoke(
+    res = invoke(
         "task new _name _command _source --version _version "
         f"--args-schema {schema_path} --args-schema-version 1.0.0"
     )
@@ -161,7 +161,7 @@ async def test_task_new(register_user, invoke, tmp_path):
     first_task_id = int(res.data["id"])
 
     # create a new task with batch option
-    res = await invoke("--batch task new _name2 _command2 _source2")
+    res = invoke("--batch task new _name2 _command2 _source2")
     res.show()
     assert res.retcode == 0
     assert res.data == str(first_task_id + 1)
@@ -169,16 +169,16 @@ async def test_task_new(register_user, invoke, tmp_path):
     # create a new task with same source as before. Note that in check_response
     # we have sys.exit(1) when status code is not the expecte one
     with pytest.raises(SystemExit) as e:
-        await invoke("task new _name2 _command2 _source")
+        invoke("task new _name2 _command2 _source")
     assert e.value.code == 1
 
     # create a new task passing not existing file
-    res = await invoke("task new _name _command _source --meta-file ./foo.pdf")
+    res = invoke("task new _name _command _source --meta-file ./foo.pdf")
     debug(res.data)
     assert res.retcode == 1
 
 
-async def test_task_edit(
+def test_task_edit(
     caplog,
     register_user,
     invoke,
@@ -191,7 +191,7 @@ async def test_task_edit(
     with open(schema_path, "w") as f:
         json.dump(schema, f)
 
-    task = await invoke(
+    task = invoke(
         "task new _name _command _source "
         f"--args-schema {schema_path} --args-schema-version 1.0.0"
     )
@@ -202,17 +202,17 @@ async def test_task_edit(
 
     # Test that regular user is not authorized
     with pytest.raises(SystemExit):
-        res = await invoke(f"task edit {task_id} --new-name {NEW_NAME}")
+        res = invoke(f"task edit {task_id} --new-name {NEW_NAME}")
 
     # Test successful edit of string attributes
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --new-name {NEW_NAME}"
     )
     assert res.data["name"] == NEW_NAME
     assert res.retcode == 0
 
     NEW_COMMAND = "run"
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --new-command {NEW_COMMAND}"
     )
     assert res.data["command"] == NEW_COMMAND
@@ -220,15 +220,15 @@ async def test_task_edit(
 
     # Test fail with no task_id nor task_name
     with pytest.raises(SystemExit):
-        res = await invoke_as_superuser("task edit")
+        res = invoke_as_superuser("task edit")
     # Test fail with both task_id and task_name
     with pytest.raises(SystemExit):
-        res = await invoke_as_superuser(
+        res = invoke_as_superuser(
             f"task edit --id {task_id} --name {task.data['name']}"
         )
     # Test fail with both task_id and task_version
     with pytest.raises(SystemExit):
-        res = await invoke_as_superuser(
+        res = invoke_as_superuser(
             f"task edit --id {task_id} --version 1.2.3.4.5.6"
         )
     assert caplog.records[-1].msg == (
@@ -237,19 +237,19 @@ async def test_task_edit(
 
     NEW_TYPE = "zip"
     # Test regular updates (both by id and name)
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --new-input-type {NEW_TYPE}"
     )
     assert res.data["input_type"] == NEW_TYPE
     assert res.retcode == 0
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --name {NEW_NAME} --new-output-type {NEW_TYPE}"
     )
     assert res.data["output_type"] == NEW_TYPE
     assert res.retcode == 0
 
     NEW_VERSION = "3.14"
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --new-version {NEW_VERSION}"
     )
     assert res.data["version"] == NEW_VERSION
@@ -260,7 +260,7 @@ async def test_task_edit(
     cache_file = cache_dir / TASKS_CACHE_FILENAME
     cache_file.unlink(missing_ok=True)
     NEW_TYPE = "something"
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --name {NEW_NAME} --new-output-type {NEW_TYPE}"
     )
     assert res.data["output_type"] == NEW_TYPE
@@ -270,7 +270,7 @@ async def test_task_edit(
     cache_file.unlink(missing_ok=True)
     NEW_TYPE = "something-here"
     with pytest.raises(SystemExit):
-        res = await invoke_as_superuser(
+        res = invoke_as_superuser(
             f"task edit --name INVALID_NAME --new-output-type {NEW_TYPE}"
         )
 
@@ -279,7 +279,7 @@ async def test_task_edit(
         json.dump([], f)
     NEW_TYPE = "something-else"
     debug(f"task edit --name {NEW_NAME} --new-output-type {NEW_TYPE}")
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --name {NEW_NAME} --new-output-type {NEW_TYPE}"
     )
     assert res.data["output_type"] == NEW_TYPE
@@ -287,7 +287,7 @@ async def test_task_edit(
 
     # Test `file not found` errors
     NEW_FILE = "foo.json"
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --meta-file {NEW_FILE}"
     )
     debug(res.data)
@@ -295,7 +295,7 @@ async def test_task_edit(
 
     # Test successful edit of dictionary attributes
     meta_file = str(testdata_path / "task_edit_json/meta.json")
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --meta-file {meta_file}"
     )
     debug(res)
@@ -307,7 +307,7 @@ async def test_task_edit(
     new_schema = dict(key1=159, key3=None)
     with open(new_schema_path, "w") as f:
         json.dump(new_schema, f)
-    res = await invoke_as_superuser(
+    res = invoke_as_superuser(
         f"task edit --id {task_id} --new-args-schema {new_schema_path} "
         "--new-args-schema-version 1.2.3"
     )
@@ -316,7 +316,7 @@ async def test_task_edit(
     assert res.data["args_schema_version"] == "1.2.3"
 
 
-async def test_task_delete(
+def test_task_delete(
     register_user,
     user_factory,
     invoke,
@@ -327,9 +327,7 @@ async def test_task_delete(
     """
     NAME = "_name"
     VERSION = "1.0.0"
-    task = await invoke(
-        f"task new {NAME} _command _source --version {VERSION}"
-    )
+    task = invoke(f"task new {NAME} _command _source --version {VERSION}")
     task.show()
     assert task.retcode == 0
     task_id = task.data["id"]
@@ -338,29 +336,27 @@ async def test_task_delete(
     with pytest.raises(SystemExit):
         EMAIL = "someone@example.org"
         PASSWORD = "123123"
-        await user_factory(email=EMAIL, password=PASSWORD)
-        res = await invoke(
-            f"-u {EMAIL} -p {PASSWORD} task delete --id {task_id}"
-        )
+        user_factory(email=EMAIL, password=PASSWORD)
+        res = 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}")
+        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")
+        invoke(f"task delete --name {NAME} --version INVALID_VERSION")
 
     # Test sucess
-    res = await invoke("task list")
+    res = invoke("task list")
     task_list = res.data
     assert len(task_list) == 1
-    res = await invoke(f"task delete --name {NAME} --version {VERSION}")
+    res = invoke(f"task delete --name {NAME} --version {VERSION}")
     assert res.retcode == 0
-    res = await invoke("task list")
+    res = invoke("task list")
     task_list = res.data
     assert len(task_list) == 0
 
 
-async def test_task_list(register_user, invoke, testdata_path):
+def test_task_list(register_user, invoke, testdata_path):
     """
     Install tasks from a package
     Add a custom task with an owner
@@ -373,7 +369,7 @@ async def test_task_list(register_user, invoke, testdata_path):
             testdata_path / f"fractal_tasks_dummy-{version}-py3-none-any.whl"
         )
 
-        res = await invoke(f"--batch task collect {PACKAGE}")
+        res = invoke(f"--batch task collect {PACKAGE}")
         assert res.retcode == 0
 
         state_id = res.data.split(" ")[0]
@@ -382,7 +378,7 @@ async def test_task_list(register_user, invoke, testdata_path):
         time.sleep(1)
         starting_time = time.perf_counter()
         while True:
-            res = await invoke(f"task check-collection {state_id}")
+            res = invoke(f"task check-collection {state_id}")
             assert res.retcode == 0
             if res.data["data"]["status"] == "OK":
                 break
@@ -395,7 +391,7 @@ async def test_task_list(register_user, invoke, testdata_path):
     custom_task_source = "custom_task_source"
     custom_task_version = "9.9"
     custom_task_meta = testdata_path / "task_edit_json/meta.json"
-    res = await invoke(
+    res = invoke(
         f"task new {custom_task_name} {custom_task_command} "
         f"{custom_task_source} --meta-file {custom_task_meta} "
         f"--version {custom_task_version}"
@@ -404,7 +400,7 @@ async def test_task_list(register_user, invoke, testdata_path):
     assert res.retcode == 0
 
     # List tasks
-    res = await invoke("task list")
+    res = invoke("task list")
     assert res.retcode == 0
     task_list = res.data
 
@@ -438,32 +434,32 @@ async def test_task_list(register_user, invoke, testdata_path):
     assert task_list[4]["owner"] is not None
 
 
-async def test_pin(register_user, invoke, testdata_path, caplog):
+def test_pin(register_user, invoke, testdata_path, caplog):
 
     PACKAGE = "fractal_tasks_core_alpha-0.0.1a0-py3-none-any.whl"
     PIN = "pydantic=1.10.3"
 
     with pytest.raises(SystemExit):
-        await invoke(
+        invoke(
             f"task collect {testdata_path / PACKAGE} "
             f"--pinned-dependency {PIN.replace('=','~')}"
         )
     assert "Pins must be written as" in caplog.records[-1].msg
 
-    res = await invoke(
+    res = invoke(
         f"task collect {testdata_path / PACKAGE} --pinned-dependency {PIN}"
     )
     assert res.retcode == 0
     state_id = res.data["id"]
     starting_time = time.perf_counter()
     while True:
-        res = await invoke(f"task check-collection {state_id}")
+        res = invoke(f"task check-collection {state_id}")
         time.sleep(1)
         if res.data["data"]["status"] == "OK":
             break
         assert time.perf_counter() - starting_time < COLLECTION_TIMEOUT
 
-    res = await invoke(f"task check-collection {state_id}")
+    res = invoke(f"task check-collection {state_id}")
     assert res.retcode == 0
     assert (
         f"Currently installed version of {PIN.split('=')[0]}"
diff --git a/tests/test_unit_task_cache.py b/tests/test_unit_task_cache.py
index 04e43e9af..f39557f5e 100644
--- a/tests/test_unit_task_cache.py
+++ b/tests/test_unit_task_cache.py
@@ -32,7 +32,7 @@ def test_get_matching_tasks():
     assert res == []
 
 
-async def test_search_in_task_list():
+def test_search_in_task_list():
     """Test all possible cases for function `_search_in_task_list`"""
 
     TASK_LIST = [
diff --git a/tests/test_user.py b/tests/test_user.py
index dc56bcf59..ca6d99581 100644
--- a/tests/test_user.py
+++ b/tests/test_user.py
@@ -7,24 +7,24 @@
 PWD_USER = "testpassword"
 
 
-async def test_register_as_user(invoke, register_user, caplog):
+def test_register_as_user(invoke, register_user, caplog):
     with pytest.raises(SystemExit):
-        await invoke(f"user register {EMAIL_USER} {PWD_USER}")
+        invoke(f"user register {EMAIL_USER} {PWD_USER}")
     debug(caplog.text)
     assert "403" in caplog.text
 
 
 @pytest.mark.parametrize("is_superuser", [True, False])
-async def test_register_as_superuser(invoke_as_superuser, is_superuser: bool):
+def test_register_as_superuser(invoke_as_superuser, is_superuser: bool):
     if is_superuser:
-        res = await invoke_as_superuser(
+        res = invoke_as_superuser(
             f"user register {EMAIL_USER} {PWD_USER} --superuser"
         )
         debug(res.data)
         assert res.retcode == 0
         assert res.data["is_superuser"]
     else:
-        res = await invoke_as_superuser(
+        res = invoke_as_superuser(
             f"user register {EMAIL_USER} {PWD_USER} "
             "--slurm-user SOMETHING --cache-dir /absolute --username X"
         )
@@ -38,30 +38,28 @@ async def test_register_as_superuser(invoke_as_superuser, is_superuser: bool):
     assert res.data["is_verified"]
 
 
-async def test_register_as_superuser_with_batch(invoke_as_superuser):
+def test_register_as_superuser_with_batch(invoke_as_superuser):
     # Register a user with the --batch flag
-    res = await invoke_as_superuser(
-        f"--batch user register {EMAIL_USER} {PWD_USER}"
-    )
+    res = invoke_as_superuser(f"--batch user register {EMAIL_USER} {PWD_USER}")
     user_id = res.data
     debug(user_id)
     assert res.retcode == 0
     # Check that the user exists
-    res = await invoke_as_superuser(f"user show {user_id}")
+    res = invoke_as_superuser(f"user show {user_id}")
     debug(res.data)
     assert res.data["email"] == EMAIL_USER
     assert res.retcode == 0
 
 
-async def test_list_as_user(invoke, register_user, caplog):
+def test_list_as_user(invoke, register_user, caplog):
     with pytest.raises(SystemExit):
-        await invoke("user list")
+        invoke("user list")
     debug(caplog.text)
     assert "403" in caplog.text
 
 
-async def test_list_as_superuser(invoke_as_superuser, register_user):
-    res = await invoke_as_superuser("user list")
+def test_list_as_superuser(invoke_as_superuser, register_user):
+    res = invoke_as_superuser("user list")
     debug(res.data)
     assert res.retcode == 0
     list_emails = [user["email"] for user in res.data]
@@ -70,50 +68,46 @@ async def test_list_as_superuser(invoke_as_superuser, register_user):
     assert environ["FRACTAL_USER"] in list_emails
 
 
-async def test_show_as_user(
-    invoke, invoke_as_superuser, register_user, caplog
-):
+def test_show_as_user(invoke, invoke_as_superuser, register_user, caplog):
     # Register a new user
-    res = await invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
+    res = invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
     user_id = res.data["id"]
     # Call fractal user show
     with pytest.raises(SystemExit):
-        await invoke(f"user show {user_id}")
+        invoke(f"user show {user_id}")
     debug(caplog.text)
     assert "403" in caplog.text
 
 
-async def test_show_as_superuser(invoke_as_superuser):
+def test_show_as_superuser(invoke_as_superuser):
     # Register a new user
-    res = await invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
+    res = invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
     user_id = res.data["id"]
     # Call fractal user show
-    await invoke_as_superuser(f"user show {user_id}")
+    invoke_as_superuser(f"user show {user_id}")
     debug(res.data)
     assert res.retcode == 0
     assert res.data["email"] == EMAIL_USER
 
 
-async def test_edit_as_user(
-    invoke, invoke_as_superuser, register_user, caplog
-):
+def test_edit_as_user(invoke, invoke_as_superuser, register_user, caplog):
     # Register a new user
-    res = await invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
+    res = invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
     user_id = res.data["id"]
     # Call fractal user edit
     with pytest.raises(SystemExit):
-        await invoke(f"user edit {user_id} --new-email email@something.xy")
+        invoke(f"user edit {user_id} --new-email email@something.xy")
     debug(caplog.text)
     assert "403" in caplog.text
 
 
 @pytest.mark.parametrize("new_is_superuser", [True, False])
 @pytest.mark.parametrize("new_is_non_verified", [True, False])
-async def test_edit_as_superuser(
+def test_edit_as_superuser(
     invoke_as_superuser, new_is_superuser, new_is_non_verified
 ):
     # Register a new user
-    res = await invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
+    res = invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
     assert res.retcode == 0
     user_id = res.data["id"]
     # Call fractal user edit
@@ -134,7 +128,7 @@ async def test_edit_as_superuser(
     if new_is_non_verified:
         cmd = f"{cmd} --remove-verified"
     debug(cmd)
-    res = await invoke_as_superuser(cmd)
+    res = invoke_as_superuser(cmd)
     debug(res.data)
     assert res.retcode == 0
     assert res.data["email"] == NEW_EMAIL
@@ -148,14 +142,14 @@ async def test_edit_as_superuser(
     BAD_CACHE_DIR = "not_absolute"
     with pytest.raises(SystemExit):
         cmd = f"user edit {user_id} --new-cache-dir {BAD_CACHE_DIR}"
-        await invoke_as_superuser(cmd)
+        invoke_as_superuser(cmd)
 
     # If the user was made a superuser, check that we can go back to normal
     # user
     if new_is_superuser:
         cmd = f"user edit {user_id} --remove-superuser"
         debug(cmd)
-        res = await invoke_as_superuser(cmd)
+        res = invoke_as_superuser(cmd)
         debug(res.data)
         assert res.retcode == 0
         assert not res.data["is_superuser"]
@@ -165,31 +159,29 @@ async def test_edit_as_superuser(
     if new_is_non_verified:
         cmd = f"user edit {user_id} --make-verified"
         debug(cmd)
-        res = await invoke_as_superuser(cmd)
+        res = invoke_as_superuser(cmd)
         debug(res.data)
         assert res.retcode == 0
         assert res.data["is_verified"]
 
 
-async def test_edit_arguments(invoke_as_superuser):
+def test_edit_arguments(invoke_as_superuser):
     # Test that superuser flags are mutually exclusive
     with pytest.raises(SystemExit):
         cmd = "user edit SOME_USER_ID --make-superuser --remove-superuser"
-        await invoke_as_superuser(cmd)
+        invoke_as_superuser(cmd)
 
 
 @pytest.mark.skip(
     reason="Delete-user endpoint was removed in fractal-server 1.4.0"
 )
-async def test_delete_as_user(
-    invoke, invoke_as_superuser, register_user, caplog
-):
+def test_delete_as_user(invoke, invoke_as_superuser, register_user, caplog):
     # Register a new user
-    res = await invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
+    res = invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
     user_id = res.data["id"]
     # Call fractal user edit
     with pytest.raises(SystemExit):
-        await invoke(f"user delete {user_id}")
+        invoke(f"user delete {user_id}")
     debug(caplog.text)
     assert "403" in caplog.text
 
@@ -197,23 +189,23 @@ async def test_delete_as_user(
 @pytest.mark.skip(
     reason="Delete-user endpoint was removed in fractal-server 1.4.0"
 )
-async def test_delete_as_superuser(invoke_as_superuser, caplog):
+def test_delete_as_superuser(invoke_as_superuser, caplog):
     # Register a new user
-    res = await invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
+    res = invoke_as_superuser(f"user register {EMAIL_USER} {PWD_USER}")
     user_id = res.data["id"]
     # Call fractal user delete
-    res = await invoke_as_superuser(f"user delete {user_id}")
+    res = invoke_as_superuser(f"user delete {user_id}")
     assert res.retcode == 0
     # Check that user was not found
     with pytest.raises(SystemExit):
-        res = await invoke_as_superuser(f"user show {user_id}")
+        res = invoke_as_superuser(f"user show {user_id}")
     debug(caplog.text)
     assert "404" in caplog.text
     assert "Not Found" in caplog.text
 
 
-async def test_whoami_as_user(invoke, register_user):
-    res = await invoke("user whoami")
+def test_whoami_as_user(invoke, register_user):
+    res = invoke("user whoami")
     assert res.retcode == 0
     debug(res.data)
     assert res.data["email"] == environ["FRACTAL_USER"]
@@ -221,14 +213,14 @@ async def test_whoami_as_user(invoke, register_user):
     user_id = res.data["id"]
 
     # Test user whoami with --batch flag
-    res = await invoke("--batch user whoami")
+    res = invoke("--batch user whoami")
     debug(res.data)
     assert res.data == user_id
     assert res.retcode == 0
 
 
-async def test_whoami_as_superuser(invoke_as_superuser):
-    res = await invoke_as_superuser("user whoami")
+def test_whoami_as_superuser(invoke_as_superuser):
+    res = invoke_as_superuser("user whoami")
     assert res.retcode == 0
     debug(res.data)
     assert res.data["email"] == "admin@fractal.xy"
diff --git a/tests/test_workflow.py b/tests/test_workflow.py
index 04bb3bf80..c48a6e04e 100644
--- a/tests/test_workflow.py
+++ b/tests/test_workflow.py
@@ -1,4 +1,3 @@
-import asyncio
 import json
 import logging
 import time
@@ -10,15 +9,15 @@
 TIMEOUT = 15.0
 
 
-async def test_workflow_new(register_user, invoke):
+def test_workflow_new(register_user, invoke):
     PROJECT_NAME = "project_name"
-    res = await invoke(f"project new {PROJECT_NAME}")
+    res = invoke(f"project new {PROJECT_NAME}")
     proj = res.data
     assert proj["name"] == PROJECT_NAME
     project_id = proj["id"]
 
     WORKFLOW_NAME = "mywf"
-    res = await invoke(f"workflow new {WORKFLOW_NAME} {project_id}")
+    res = invoke(f"workflow new {WORKFLOW_NAME} {project_id}")
     wf = res.data
     debug(wf)
     assert res.retcode == 0
@@ -27,95 +26,95 @@ async def test_workflow_new(register_user, invoke):
 
     # Include --batch
     WORKFLOW_NAME = "mywf-2"
-    res = await invoke(f"--batch workflow new {WORKFLOW_NAME} {project_id}")
+    res = invoke(f"--batch workflow new {WORKFLOW_NAME} {project_id}")
     assert res.retcode == 0
     debug(res.data)
     assert isinstance(res.data, int)
 
 
-async def test_workflow_delete(register_user, invoke):
+def test_workflow_delete(register_user, invoke):
     # Create project
-    res_pj = await invoke("project new project_name")
+    res_pj = invoke("project new project_name")
     assert res_pj.retcode == 0
     project_id = res_pj.data["id"]
 
     # Create workflow
-    res_wf = await invoke(f"workflow new MyWorkflow {project_id}")
+    res_wf = invoke(f"workflow new MyWorkflow {project_id}")
     workflow_id = res_wf.data["id"]
     assert res_wf.retcode == 0
 
     # List workflows
-    res_list = await invoke(f"workflow list {project_id}")
+    res_list = invoke(f"workflow list {project_id}")
     assert res_list.retcode == 0
     debug(res_list.data)
     assert len(res_list.data) == 1
 
     # Delete workflow
-    res_delete = await invoke(f"workflow delete {project_id} {workflow_id}")
+    res_delete = invoke(f"workflow delete {project_id} {workflow_id}")
     assert res_delete.retcode == 0
 
     # List workflows
-    res_list = await invoke(f"workflow list {project_id}")
+    res_list = invoke(f"workflow list {project_id}")
     assert res_list.retcode == 0
     debug(res_list.data)
     assert len(res_list.data) == 0
 
 
-async def test_workflow_edit(register_user, invoke):
+def test_workflow_edit(register_user, invoke):
     # Create a project
-    res_pj = await invoke("project new project_name_1")
+    res_pj = invoke("project new project_name_1")
     assert res_pj.retcode == 0
     project_id = res_pj.data["id"]
 
     # Add a workflow
-    res_wf = await invoke(f"workflow new MyWorkflow {project_id}")
+    res_wf = invoke(f"workflow new MyWorkflow {project_id}")
     workflow_id = res_wf.data["id"]
     assert res_wf.retcode == 0
 
     # Fail editing with no edits
     cmd = f"workflow edit {project_id} {workflow_id}"
     with pytest.raises(SystemExit):
-        res = await invoke(cmd)
+        res = invoke(cmd)
 
     # Edit workflow name
     NAME = "new-workflow-name"
     cmd = f"workflow edit {project_id} {workflow_id} --new-name {NAME}"
     debug(cmd)
-    res_edit = await invoke(cmd)
+    res_edit = invoke(cmd)
     assert res_edit.retcode == 0
     debug(res_edit.data)
 
     # List workflows, and check edit
-    res = await invoke(f"workflow show {project_id} {workflow_id}")
+    res = invoke(f"workflow show {project_id} {workflow_id}")
     debug(res.data)
     assert res.retcode == 0
     assert res.data["name"] == NAME
 
 
-async def test_workflow_list(register_user, invoke):
+def test_workflow_list(register_user, invoke):
     PROJECT_NAME = "project_name"
-    res_pj = await invoke(f"project new {PROJECT_NAME}")
+    res_pj = invoke(f"project new {PROJECT_NAME}")
     project_id = res_pj.data["id"]
     debug(project_id)
 
-    res_wf = await invoke(f"workflow new WF1 {project_id}")
+    res_wf = invoke(f"workflow new WF1 {project_id}")
     res_wf.show()
     assert res_wf.retcode == 0
 
-    res_wf = await invoke(f"workflow new WF2 {project_id}")
+    res_wf = invoke(f"workflow new WF2 {project_id}")
     res_wf.show()
     assert res_wf.retcode == 0
 
-    res_list = await invoke(f"workflow list {project_id}")
+    res_list = invoke(f"workflow list {project_id}")
     debug(res_list)
     debug(res_list.data)
     assert res_list.retcode == 0
     assert len(res_list.data) == 2
 
 
-async def test_workflow_list_when_two_projects_exist(register_user, invoke):
-    res_pj1 = await invoke("project new PRJ1")
-    res_pj2 = await invoke("project new PRJ2")
+def test_workflow_list_when_two_projects_exist(register_user, invoke):
+    res_pj1 = invoke("project new PRJ1")
+    res_pj2 = invoke("project new PRJ2")
     project_id_1 = res_pj1.data["id"]
     project_id_2 = res_pj2.data["id"]
 
@@ -123,23 +122,23 @@ async def test_workflow_list_when_two_projects_exist(register_user, invoke):
     NUM_WF_PROJECT_2 = 4
 
     for wf in range(NUM_WF_PROJECT_1):
-        res_wf = await invoke(f"workflow new WF{wf} {project_id_1}")
+        res_wf = invoke(f"workflow new WF{wf} {project_id_1}")
         assert res_wf.retcode == 0
 
     for wf in range(NUM_WF_PROJECT_2):
-        res_wf = await invoke(f"workflow new WF{wf} {project_id_2}")
+        res_wf = invoke(f"workflow new WF{wf} {project_id_2}")
         assert res_wf.retcode == 0
 
-    res_list_1 = await invoke(f"workflow list {project_id_1}")
+    res_list_1 = invoke(f"workflow list {project_id_1}")
     assert res_list_1.retcode == 0
     assert len(res_list_1.data) == NUM_WF_PROJECT_1
 
-    res_list_2 = await invoke(f"workflow list {project_id_2}")
+    res_list_2 = invoke(f"workflow list {project_id_2}")
     assert res_list_2.retcode == 0
     assert len(res_list_2.data) == NUM_WF_PROJECT_2
 
 
-async def test_workflow_add_task(
+def test_workflow_add_task(
     caplog,
     invoke,
     register_user,
@@ -156,10 +155,10 @@ async def test_workflow_add_task(
         the WorkflowTask's are correctly registered in the db, and the returned
         object has the right properties
     """
-    res = await invoke("project new MyProject")
+    res = invoke("project new MyProject")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
-    t = await task_factory()
+    wf = workflow_factory(project_id=project_id)
+    t = task_factory()
 
     # Add a WorkflowTask with --args-file and --meta-file arguments
     ARGS = {"arg": "arg_value"}
@@ -174,15 +173,13 @@ async def test_workflow_add_task(
     cmd = f"workflow add-task {project_id} {wf.id}"
     # Test fail with no task_id nor task_name
     with pytest.raises(SystemExit):
-        res = await invoke(cmd)
+        invoke(cmd)
     # Test fail with both task_id and task_name
     with pytest.raises(SystemExit):
-        res = await invoke(f"{cmd} --task-id {t.id} --task-name {t.name}")
+        invoke(f"{cmd} --task-id {t.id} --task-name {t.name}")
     # Test fail with both task_id and version
     with pytest.raises(SystemExit):
-        res = await invoke(
-            f"{cmd} --task-id {t.id} --task-version 1.2.3.4.5.6"
-        )
+        invoke(f"{cmd} --task-id {t.id} --task-version 1.2.3.4.5.6")
     assert caplog.records[-1].msg == (
         "Too many arguments: cannot provide both `task_id` and `task_version`."
     )
@@ -193,7 +190,7 @@ async def test_workflow_add_task(
     )
     debug(cmd)
     # Test success
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
 
     workflow_task = res.data
@@ -208,14 +205,14 @@ async def test_workflow_add_task(
         f"--task-name {t.name} --order 1"
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     debug(res.data)
     workflow_task_id_2 = int(res.data)
 
     # Check that the WorkflowTask's in Workflow.task_list have the correct IDs
     cmd = f"workflow show {project_id} {wf.id}"
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     workflow = res.data
     debug(workflow)
@@ -223,7 +220,7 @@ async def test_workflow_add_task(
     assert list_IDs == [workflow_task_id_1, workflow_task_id_2]
 
 
-async def test_workflow_add_task_by_name(
+def test_workflow_add_task_by_name(
     invoke,
     register_user,
     task_factory,
@@ -236,15 +233,15 @@ async def test_workflow_add_task_by_name(
     THEN the WorkflowTask is added (for a valid name) or an error is raised
     (for invalid name)
     """
-    res = await invoke("project new MyProject")
+    res = invoke("project new MyProject")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
-    task = await task_factory()
+    wf = workflow_factory(project_id=project_id)
+    task = task_factory()
     debug(task)
 
     cmd = f"workflow add-task {project_id} {wf.id} --task-name {task.name}"
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     debug(res.data)
     assert res.data["task"]["id"] == task.id
@@ -255,11 +252,11 @@ async def test_workflow_add_task_by_name(
             f"workflow add-task {project_id} {wf.id} --task-name INVALID_NAME"
         )
         debug(cmd)
-        res = await invoke(cmd)
+        res = invoke(cmd)
 
 
 @pytest.mark.skip(reason="Definition of expected behavior is ongoing")
-async def test_task_cache_with_non_unique_names(
+def test_task_cache_with_non_unique_names(
     invoke,
     register_user,
     task_factory,
@@ -275,31 +272,31 @@ async def test_task_cache_with_non_unique_names(
         * Addressing tasks by name raises a FileNotFoundError
     """
 
-    res = await invoke("project new MyProject")
+    res = invoke("project new MyProject")
     project_id = res.data["id"]
 
     # Create two tasks with the same name
-    task1 = await task_factory()
-    task2 = await task_factory()
+    task1 = task_factory()
+    task2 = task_factory()
     assert task1.name == task2.name
 
     # Verify that a warning is raised upon creating the cache file
     caplog.set_level(logging.WARNING)
-    res = await invoke("task list")
+    res = invoke("task list")
     assert res.retcode == 0
     debug(caplog.text)
     assert "Cannot" in caplog.text
 
     # Verify that adding tasks to a worfklow by name (as opposed to "by id")
     # fails because of missing cache file
-    wf = await workflow_factory(project_id=project_id)
+    wf = workflow_factory(project_id=project_id)
     cmd = f"workflow add-task {project_id} {wf.id} --task-name {task1.name}"
     debug(cmd)
     with pytest.raises(FileNotFoundError):
-        res = await invoke(cmd)
+        res = invoke(cmd)
 
 
-async def test_workflow_rm_task(
+def test_workflow_rm_task(
     invoke,
     register_user,
     task_factory,
@@ -307,28 +304,28 @@ async def test_workflow_rm_task(
     tmp_path: Path,
 ):
     # Create project, workflow and task
-    res = await invoke("project new MyProject")
+    res = invoke("project new MyProject")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
-    t = await task_factory()
+    wf = workflow_factory(project_id=project_id)
+    t = task_factory()
 
     # Add task to workflow, twice
     cmd = f"workflow add-task {project_id} {wf.id} --task-id {t.id}"
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     workflow_task_id_1 = res.data["id"]
 
     # Remove task 1 from workflow
     cmd = f"workflow rm-task {project_id} {wf.id} {workflow_task_id_1}"
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     debug(res.data)
 
 
-async def test_workflow_edit_task(
+def test_workflow_edit_task(
     invoke,
     register_user,
     task_factory,
@@ -343,14 +340,14 @@ async def test_workflow_edit_task(
         gargs
     """
 
-    res = await invoke("project new MyProject")
+    res = invoke("project new MyProject")
     project_id = res.data["id"]
-    wf = await workflow_factory(project_id=project_id)
-    t = await task_factory()
+    wf = workflow_factory(project_id=project_id)
+    t = task_factory()
 
     # Create task, without overriding arguments
     cmd = f"workflow add-task {project_id} {wf.id} --task-id {t.id}"
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
 
     # New arguments to be used
@@ -372,13 +369,13 @@ async def test_workflow_edit_task(
         f"--args-file {args_file} --meta-file {meta_file}"
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     assert res.data["args"] == ARGS
     assert res.data["meta"] == META
 
     # Check that also the workflow in the db was correctly updated
-    res = await invoke(f"workflow show {project_id} {wf.id}")
+    res = invoke(f"workflow show {project_id} {wf.id}")
     assert res.retcode == 0
     debug(res.data)
     assert res.data["task_list"][0]["args"] == ARGS
@@ -398,10 +395,10 @@ async def test_workflow_edit_task(
     )
     debug(cmd)
     with pytest.raises(SystemExit):
-        res = await invoke(cmd)
+        res = invoke(cmd)
 
 
-async def test_workflow_apply(
+def test_workflow_apply(
     register_user, invoke, testdata_path: Path, tmp_path: Path
 ):
     """
@@ -416,7 +413,7 @@ async def test_workflow_apply(
     )
     WORKFLOW_NAME = "mywf"
     DATASET_NAME = "myds"
-    res0 = await invoke(f"task collect {PACKAGE_NAME}")
+    res0 = invoke(f"task collect {PACKAGE_NAME}")
     debug(res0)
     venv_path = res0.data["data"]["venv_path"]
     debug(venv_path)
@@ -425,7 +422,7 @@ async def test_workflow_apply(
     # Wait for task collection to end
     starting_time = time.perf_counter()
     while True:
-        res1 = await invoke(f"task check-collection {state_id}")
+        res1 = invoke(f"task check-collection {state_id}")
         if res1.data["data"]["status"] == "OK":
             debug(res1.data)
             break
@@ -433,35 +430,35 @@ async def test_workflow_apply(
         assert time.perf_counter() - starting_time < TIMEOUT
 
     # Create a project
-    res = await invoke("project new testproject")
+    res = invoke("project new testproject")
     assert res.retcode == 0
     prj = res.data
     prj_id = prj["id"]
-    res = await invoke(f"project add-dataset {prj_id} test_name")
+    res = invoke(f"project add-dataset {prj_id} test_name")
     input_dataset_id = res.data["id"]
 
     # Create output dataset
-    res = await invoke(f"project add-dataset {prj_id} {DATASET_NAME}")
+    res = invoke(f"project add-dataset {prj_id} {DATASET_NAME}")
     assert res.retcode == 0
     dataset = res.data
     output_dataset_id = dataset["id"]
 
     # Add resources to datasets
     for dataset_id in (input_dataset_id, output_dataset_id):
-        res = await invoke(
+        res = invoke(
             f"dataset add-resource {prj_id} {dataset_id} {str(tmp_path)}"
         )
         assert res.retcode == 0
 
     # Create workflow and add task twice
-    res = await invoke(f"workflow new {WORKFLOW_NAME} {prj_id}")
+    res = invoke(f"workflow new {WORKFLOW_NAME} {prj_id}")
     workflow = res.data
     workflow_id = workflow["id"]
     debug(workflow)
     assert res.retcode == 0
     for _ in [0, 1]:
         TASK_ID = 1
-        res = await invoke(
+        res = invoke(
             f"workflow add-task {prj_id} {workflow_id} --task-id {TASK_ID}"
         )
         workflow_task = res.data
@@ -480,7 +477,7 @@ async def test_workflow_apply(
         f'--worker-init "export SOMEVARIABLE=1"'
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     job = res.data
     debug(job)
     assert res.retcode == 0
@@ -495,7 +492,7 @@ async def test_workflow_apply(
     starting_time = time.perf_counter()
     debug(cmd)
     while True:
-        res = await invoke(cmd)
+        res = invoke(cmd)
         job = res.data
         debug(job)
         assert res.retcode == 0
@@ -515,7 +512,7 @@ async def test_workflow_apply(
     args_file = str(tmp_path / "args.json")
     with open(args_file, "w") as f:
         json.dump({"raise_error": True}, f)
-    res = await invoke(
+    res = invoke(
         f"workflow add-task {prj_id} {workflow_id} --task-id {TASK_ID}"
         f" --args-file {args_file}"
     )
@@ -525,7 +522,7 @@ async def test_workflow_apply(
         f"{prj_id} {workflow_id} {input_dataset_id} {output_dataset_id}"
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     job_id = res.data["id"]
 
@@ -536,7 +533,7 @@ async def test_workflow_apply(
     cmd = f"job show {prj_id} {job_id} --do-not-separate-logs"
     starting_time = time.perf_counter()
     while True:
-        res = await invoke(cmd)
+        res = invoke(cmd)
         job = res.data
         debug(job)
         assert res.retcode == 0
@@ -547,9 +544,9 @@ async def test_workflow_apply(
     assert job["log"] is not None
 
     # Prepare and submit a workflow with --batch
-    res = await invoke(f"workflow new OneMoreWorkflow {prj_id}")
+    res = invoke(f"workflow new OneMoreWorkflow {prj_id}")
     workflow_id = res.data["id"]
-    res = await invoke(
+    res = invoke(
         f"workflow add-task {prj_id} {workflow_id} --task-id {TASK_ID}"
     )
     assert res.retcode == 0
@@ -558,13 +555,13 @@ async def test_workflow_apply(
         f"{prj_id} {workflow_id} {input_dataset_id} {output_dataset_id}"
     )
     debug(cmd)
-    res = await invoke(cmd)
+    res = invoke(cmd)
     assert res.retcode == 0
     debug(res.data)
     assert isinstance(res.data, int)
 
 
-async def test_workflow_export(
+def test_workflow_export(
     register_user,
     invoke,
     workflow_factory,
@@ -573,25 +570,21 @@ async def test_workflow_export(
     caplog,
 ):
 
-    res = await invoke("project new testproject")
+    res = invoke("project new testproject")
     assert res.retcode == 0
     project_id = res.data["id"]
 
     NAME = "WorkFlow"
-    wf = await workflow_factory(project_id=project_id, name=NAME)
+    wf = workflow_factory(project_id=project_id, name=NAME)
     prj_id = wf.project_id
     wf_id = wf.id
     filename = str(tmp_path / "exported_wf.json")
 
-    task = await task_factory(owner="exact-lab")
-    res = await invoke(
-        f"workflow add-task {prj_id} {wf_id} --task-id {task.id}"
-    )
+    task = task_factory(owner="exact-lab")
+    res = invoke(f"workflow add-task {prj_id} {wf_id} --task-id {task.id}")
     assert res.retcode == 0
 
-    res = await invoke(
-        f"workflow export {prj_id} {wf_id} --json-file {filename}"
-    )
+    res = invoke(f"workflow export {prj_id} {wf_id} --json-file {filename}")
     assert res.retcode == 0
     assert caplog.records[-1].msg == (
         "This workflow includes custom tasks (the ones with sources: "
@@ -610,7 +603,7 @@ async def test_workflow_export(
             assert "workflow_id" not in wftask
 
 
-async def test_workflow_import(
+def test_workflow_import(
     register_user,
     invoke,
     testdata_path: Path,
@@ -619,28 +612,28 @@ async def test_workflow_import(
 ):
     # collect tasks
     PACKAGE_NAME = testdata_path / "fractal_tasks_dummy-0.1.0-py3-none-any.whl"
-    res0 = await invoke(f"task collect {PACKAGE_NAME}")
+    res0 = invoke(f"task collect {PACKAGE_NAME}")
     assert res0.retcode == 0
     state_id = res0.data["id"]
     starting_time = time.perf_counter()
     while True:
-        res1 = await invoke(f"task check-collection {state_id}")
+        res1 = invoke(f"task check-collection {state_id}")
         if res1.data["data"]["status"] == "OK":
             break
-        await asyncio.sleep(1)
+        time.sleep(1)
         assert time.perf_counter() - starting_time < TIMEOUT
 
     # create project
     PROJECT_NAME = "project_name"
-    res_pj = await invoke(f"project new {PROJECT_NAME}")
+    res_pj = invoke(f"project new {PROJECT_NAME}")
     assert res_pj.retcode == 0
     project_id = res_pj.data["id"]
 
-    await task_factory(source="custom_source", owner="exact-lab")
+    task_factory(source="custom_source", owner="exact-lab")
 
     # import workflow into project
     filename = str(testdata_path / "import-export/workflow.json")
-    res = await invoke(
+    res = invoke(
         f"workflow import --project-id {project_id} --json-file {filename}"
     )
     debug(res.data)
@@ -655,13 +648,13 @@ async def test_workflow_import(
 
     # get the workflow from the server, and check that it is the same
     workflow_id = res.data["id"]
-    res = await invoke(f"workflow show {project_id} {workflow_id}")
+    res = invoke(f"workflow show {project_id} {workflow_id}")
     assert res.retcode == 0
     assert res.data == imported_workflow
 
     # import workflow into project, with --batch
     filename = str(testdata_path / "import-export/workflow_2.json")
-    res = await invoke(
+    res = invoke(
         f"--batch workflow import --project-id {project_id} "
         f"--json-file {filename}"
     )