diff --git a/solara/__init__.py b/solara/__init__.py index 0f647194f..04ff6c829 100644 --- a/solara/__init__.py +++ b/solara/__init__.py @@ -65,6 +65,7 @@ def _using_solara_server(): from .autorouting import generate_routes, generate_routes_directory, RenderPage, RoutingProvider, DefaultLayout from .checks import check_jupyter from .scope import get_kernel_id, get_session_id +from .tasks import task, use_task, Task, TaskResult def display(*objs, **kwargs): diff --git a/solara/hooks/use_thread.py b/solara/hooks/use_thread.py index 20f083744..b10262589 100644 --- a/solara/hooks/use_thread.py +++ b/solara/hooks/use_thread.py @@ -7,13 +7,14 @@ import solara from solara.datatypes import Result, ResultState -from solara.util import cancel_guard, nullcontext +from solara.util import cancel_guard, nullcontext, deprecated SOLARA_ALLOW_OTHER_TRACER = os.environ.get("SOLARA_ALLOW_OTHER_TRACER", False) in (True, "True", "true", "1") T = TypeVar("T") logger = logging.getLogger("solara.hooks.use_thread") +@deprecated("`use_thread` is deprecated, use the more modern and performant `use_task` or `Task` instead", category=FutureWarning) def use_thread( callback: Union[ Callable[[threading.Event], T], diff --git a/solara/lab/__init__.py b/solara/lab/__init__.py index e0c6b94e1..822a6b7f3 100644 --- a/solara/lab/__init__.py +++ b/solara/lab/__init__.py @@ -2,8 +2,29 @@ from .components import * # noqa: F401, F403 from .utils import cookies, headers # noqa: F401, F403 from ..lifecycle import on_kernel_start # noqa: F401 -from ..tasks import task, use_task, Task, TaskResult # noqa: F401, F403 +from ..tasks import task as _task, use_task as _use_task, Task as _Task, TaskResult as _TaskResult from ..toestand import computed # noqa: F401 +from ..util import deprecated + + +@deprecated("solara.lab.task has been moved out of the lab namespace, use solara.task instead") +def task(*args, **kwargs): + _task(*args, **kwargs) + + +@deprecated("solara.lab.use_task has been moved out of the lab namespace, use solara.use_task instead") +def use_task(*args, **kwargs): + return _use_task(*args, **kwargs) + + +@deprecated("solara.lab.Task has been moved out of the lab namespace, use solara.Task instead") +class Task(_Task): + pass + + +@deprecated("solara.lab.TaskResult has been moved out of the lab namespace, use solara.TaskResult instead") +class TaskResult(_TaskResult): + pass def __getattr__(name): diff --git a/solara/tasks.py b/solara/tasks.py index 5b559e35e..61faefba2 100644 --- a/solara/tasks.py +++ b/solara/tasks.py @@ -532,7 +532,7 @@ def task( ```solara import asyncio import solara - from solara.lab import task + from solara import task @task async def fetch_data(): @@ -561,7 +561,7 @@ def Page(): ```solara import time import solara - from solara.lab import task + from solara import task @task def fetch_data(): @@ -600,7 +600,7 @@ def Page(): ```solara import time import solara - from solara.lab import task + from solara import task @task @@ -637,7 +637,7 @@ def Page(): ```solara import time import solara - from solara.lab import task + from solara import task @task @@ -739,7 +739,7 @@ def use_task( def use_task( f: Union[None, Callable[[], R]] = None, *, - dependencies: Union[None, List] = [], + dependencies: Union[None, List] = None, raise_error=True, prefer_threaded=True, ) -> Union[Callable[[Callable[[], R]], "Task[[], R]"], "Task[[], R]"]: @@ -760,7 +760,7 @@ def use_task( ```solara import time import solara - from solara.lab import use_task, Task + from solara import use_task, Task @solara.component @@ -787,7 +787,7 @@ def square(): ```solara import asyncio import solara - from solara.lab import use_task, Task + from solara import use_task, Task @solara.component @@ -809,7 +809,7 @@ async def square(): ## Arguments - `f`: The function or coroutine to run as a task. - - `dependencies`: A list of dependencies that will trigger a rerun of the task when changed, the task will run automatically execute when the `dependencies=None` + - `dependencies`: A list of dependencies that will trigger a rerun of the task when changed, the task will not automatically execute when the `dependencies=None`. - `raise_error`: If true, an error in the task will be raised. If false, the error should be handled by the user and is available in the `.exception` attribute of the task result object. - `prefer_threaded` - bool: Will run coroutine functions as a task in a thread when threads are available. diff --git a/solara/util.py b/solara/util.py index c3fffa8ce..fa7de2a84 100644 --- a/solara/util.py +++ b/solara/util.py @@ -11,6 +11,7 @@ from pathlib import Path from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union from urllib.parse import urlencode +import warnings if TYPE_CHECKING: import numpy as np @@ -346,3 +347,33 @@ def wrapper(): return return_value return wrapper + + +def deprecated(reason: str, category=DeprecationWarning): + """ + Mark functions as deprecated. When the function is called, a warning is shown with the provided reason. + + Parameters + ---------- + + reason : str + The message to display when the deprecated function is used. + category : type, optional + The warning category to use, defaults to DeprecationWarning. Use DeprecationWarning when users do not need to see + the warning, and FutureWarning when users should see the warning. + + """ + + def decorator(func): + @functools.wraps(func) + def wrapped(*args, **kwargs): + warnings.warn( + reason, + category=category, + stacklevel=2, # this way we show the line where the function is called + ) + return func(*args, **kwargs) + + return wrapped + + return decorator diff --git a/solara/website/pages/__init__.py b/solara/website/pages/__init__.py index fc1b0377d..4d905feca 100644 --- a/solara/website/pages/__init__.py +++ b/solara/website/pages/__init__.py @@ -209,6 +209,8 @@ "/api/widget": "/documentation/api/utilities/widget", "/api/default_layout": "/documentation/components/layout", "/api/title": "/documentation/components/page/title", + "/documentation/components/lab/use_task": "/documentation/api/hooks/use_task", + "/documentation/components/lab/task": "/documentation/api/utilities/task", } diff --git a/solara/website/pages/documentation/components/lab/use_task.py b/solara/website/pages/documentation/api/hooks/use_task.py similarity index 70% rename from solara/website/pages/documentation/components/lab/use_task.py rename to solara/website/pages/documentation/api/hooks/use_task.py index 1e2d63480..f0839eeeb 100644 --- a/solara/website/pages/documentation/components/lab/use_task.py +++ b/solara/website/pages/documentation/api/hooks/use_task.py @@ -2,10 +2,9 @@ import solara import solara.autorouting -import solara.lab from solara.website.components import NoPage from solara.website.utils import apidoc title = "use_task" Page = NoPage -__doc__ += apidoc(solara.lab.use_task) # type: ignore +__doc__ += apidoc(solara.use_task) # type: ignore diff --git a/solara/website/pages/documentation/api/hooks/use_thread.md b/solara/website/pages/documentation/api/hooks/use_thread.md index 4055de8b0..fa45a2d34 100644 --- a/solara/website/pages/documentation/api/hooks/use_thread.md +++ b/solara/website/pages/documentation/api/hooks/use_thread.md @@ -1,4 +1,6 @@ -# use_thread +# use_thread (deprecated) + +### use_thread is deprecated, use [use_task](/documentation/api/hooks/use_task) or [Task](/documentation/api/utilities/task) instead ```python def use_thread( diff --git a/solara/website/pages/documentation/api/hooks/use_thread.py b/solara/website/pages/documentation/api/hooks/use_thread.py index bf6dfa723..3c977c2df 100644 --- a/solara/website/pages/documentation/api/hooks/use_thread.py +++ b/solara/website/pages/documentation/api/hooks/use_thread.py @@ -6,7 +6,7 @@ from solara.alias import rw HERE = Path(__file__).parent -title = "use_thread" +title = "use_thread (deprecated)" __doc__ = open(HERE / "use_thread.md").read() diff --git a/solara/website/pages/documentation/components/lab/task.py b/solara/website/pages/documentation/api/utilities/task.py similarity index 71% rename from solara/website/pages/documentation/components/lab/task.py rename to solara/website/pages/documentation/api/utilities/task.py index 5babb7c44..7fd8e0a9a 100644 --- a/solara/website/pages/documentation/components/lab/task.py +++ b/solara/website/pages/documentation/api/utilities/task.py @@ -2,10 +2,9 @@ import solara import solara.autorouting -import solara.lab from solara.website.components import NoPage from solara.website.utils import apidoc title = "Task" Page = NoPage -__doc__ += apidoc(solara.lab.task) # type: ignore +__doc__ += apidoc(solara.task) # type: ignore