Skip to content

Commit 3b48de1

Browse files
authored
docs and short description (#50)
* docs and short description * build 3.13 * Allow to use python 3.13
1 parent 37d5c98 commit 3b48de1

File tree

15 files changed

+1048
-868
lines changed

15 files changed

+1048
-868
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
1717
strategy:
1818
matrix:
19-
python-version: ["3.11", "3.12"]
19+
python-version: ["3.11", "3.12", "3.13"]
2020

2121
services:
2222
postgres:

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ docs-publish: ## publish the book to github pages
6262

6363
.PHONY: docs-serve
6464
docs-serve: ## serve documentation
65-
@poetry run mkdocs serve
65+
@poetry run mkdocs serve -w fluid
6666

6767

6868
.PHONY: readme

docs/CNAME

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fluid.quantmind.com

docs/reference/task.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Task
2+
3+
A Task defines the implementation given operation, the inputs required and the scheduling metadata.
4+
Usually, a Task is not created directly, but rather through the use of the `@task` decorator.
5+
6+
## Example
7+
8+
```python
9+
from fluid.scheduler import task, TaskRun
10+
11+
@task
12+
def hello(ctx: TaskRun) -> None:
13+
print("Hello, world!")
14+
```
15+
16+
17+
::: fluid.scheduler.task
18+
19+
::: fluid.scheduler.Task

docs/reference/workers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Workers are the main building block for asynchronous programming with `aio-fluid
44
There are several worker classes which can be imported from `fluid.utils.worker`:
55

66
```python
7-
from fastapi.utils.worker import StoppingWorker
7+
from fluid.utils.worker import StoppingWorker
88
```
99

1010
::: fluid.utils.worker.Worker

examples/tasks/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ async def disabled(context: TaskRun) -> float:
4444

4545
@task(cpu_bound=True, schedule=every(timedelta(seconds=5)))
4646
async def cpu_bound(context: TaskRun) -> None:
47-
"""A CPU bound task running on subprocess"""
47+
"""A CPU bound task running on subprocess
48+
49+
CPU bound tasks are executed on a subprocess to avoid blocking the event loop.
50+
"""
4851
time.sleep(1)
4952
broker = cast(RedisTaskBroker, context.task_manager.broker)
5053
redis = broker.redis_cli

fluid/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Reusable server side python modules"""
22

3-
__version__ = "1.2.1"
3+
__version__ = "1.2.2"

fluid/scheduler/cli.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,18 @@ def ls(ctx: click.Context) -> None:
5353
table.add_column("Name", style="cyan", no_wrap=True)
5454
table.add_column("Schedule", style="magenta")
5555
table.add_column("CPU bound", style="magenta")
56+
table.add_column("Timeout secs", style="green")
57+
table.add_column("Priority", style="magenta")
5658
table.add_column("Description", style="green")
5759
for name in sorted(task_manager.registry):
5860
task = task_manager.registry[name]
5961
table.add_row(
6062
name,
6163
str(task.schedule),
6264
"yes" if task.cpu_bound else "no",
63-
task.description,
65+
str(task.timeout_seconds),
66+
str(task.priority),
67+
task.short_description,
6468
)
6569
console = Console()
6670
console.print(table)

fluid/scheduler/crontab.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from abc import ABC, abstractmethod
66
from datetime import datetime
77
from typing import NamedTuple, Set, Union
8-
98
from zoneinfo import ZoneInfo
109

1110
from fluid.utils.dates import UTC

fluid/scheduler/models.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,26 +105,38 @@ class QueuedTask(BaseModel):
105105

106106

107107
class Task(NamedTuple):
108-
"""A Task execute any time it is invoked"""
108+
"""A Task executes any time it is invoked"""
109109

110110
name: str
111+
"""Task name - unique identifier"""
111112
executor: TaskExecutor
113+
"""Task executor function"""
112114
logger: logging.Logger
115+
"""Task logger"""
113116
module: str = ""
117+
"""Task python module"""
118+
short_description: str = ""
119+
"""Short task description - one line"""
114120
description: str = ""
121+
"""Task description - obtained from the executor docstring if not provided"""
115122
schedule: Scheduler | None = None
123+
"""Task schedule - None means the task is not scheduled"""
116124
randomize: RandomizeType | None = None
117125
params_model: type[BaseModel] | None = None
118126
max_concurrency: int = 0
119127
"""how many tasks can run in each consumer concurrently - 0 means no limit"""
120128
timeout_seconds: int = 60
129+
"""Task timeout in seconds - how long the task can run before being aborted"""
121130
priority: TaskPriority = TaskPriority.medium
131+
"""Task priority - high, medium, low"""
122132

123133
@property
124134
def cpu_bound(self) -> bool:
135+
"""True if the task is CPU bound"""
125136
return self.executor is run_in_subprocess
126137

127138
def params_dump_json(self, params: dict[str, Any]) -> str:
139+
"""Dumps task parameters as JSON string"""
128140
if params_model := self.params_model:
129141
return params_model(**params).model_dump_json()
130142
return json.dumps(params)
@@ -141,7 +153,10 @@ def info(self, **params: Any) -> TaskInfo:
141153

142154

143155
class TaskRun(BaseModel, arbitrary_types_allowed=True):
144-
"""A TaskRun contains all the data generated by a Task run"""
156+
"""A TaskRun contains all the data generated by a Task run
157+
158+
This model is never initialized directly, it is created by the TaskManager
159+
"""
145160

146161
id: str
147162
task: Task
@@ -298,6 +313,7 @@ def task(
298313
*,
299314
name: str | None = None,
300315
schedule: Scheduler | None = None,
316+
short_description: str | None = None,
301317
description: str | None = None,
302318
randomize: RandomizeType | None = None,
303319
max_concurrency: int = 1,
@@ -310,6 +326,13 @@ def task(
310326

311327
# implementation of the task decorator
312328
def task(executor: TaskExecutor | None = None, **kwargs: Any) -> Task | TaskConstructor:
329+
"""Decorator to create a Task
330+
331+
This decorator can be used in two ways:
332+
333+
- As a simple decorator of the executor function
334+
- As a function with keyword arguments
335+
"""
313336
if kwargs and executor:
314337
raise TaskDecoratorError("cannot use positional parameters")
315338
elif kwargs:
@@ -355,12 +378,15 @@ def cpu_bound_task(self, executor: TaskExecutor) -> Task:
355378

356379
def kwargs_defaults(self, executor: TaskExecutor) -> dict[str, Any]:
357380
module = inspect.getmodule(executor)
358-
return {
359-
"name": get_name(executor),
360-
"module": module.__name__ if module else "",
361-
"description": trim_docstring(inspect.getdoc(executor) or ""),
362-
"executor": executor,
363-
}
381+
description = trim_docstring(inspect.getdoc(executor) or "")
382+
short_description = description.split("\n")[0].strip()
383+
return dict(
384+
name=get_name(executor),
385+
module=module.__name__ if module else "",
386+
description=description,
387+
short_description=short_description,
388+
executor=executor,
389+
)
364390

365391

366392
def get_name(o: Any) -> str:

fluid/utils/dates.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from datetime import date, datetime, timezone
22
from typing import Any
3-
43
from zoneinfo import ZoneInfo
54

65
UTC = ZoneInfo("UTC")

0 commit comments

Comments
 (0)