Skip to content
Merged

docs #75

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ docs-publish: ## publish the book to github pages

.PHONY: docs-serve
docs-serve: ## serve documentation
@poetry run mkdocs serve -w fluid -w docs_src
@poetry run mkdocs serve -w fluid -w docs -w docs_src


.PHONY: readme
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

Here's the reference or code API, the classes, functions, parameters, attributes, and all the `aio-fluid` parts you can use in your applications.

If you want to learn how to use the library you are much better off reading the [Tutorials](../tutorials).
If you want to learn how to use the library you are much better off reading the [Tutorials](../tutorials/index.md).
2 changes: 1 addition & 1 deletion docs/reference/task_cli.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Task Manager Cli

Command line tools for task manager applications.
Command line tools for [TaskManager][fluid.scheduler.TaskManager] applications.

This modules requires the `cli` extra to be installed.

Expand Down
3 changes: 2 additions & 1 deletion docs/reference/task_manager.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Task Manager

The Task Manager is a component that manages the execution of tasks. It is the simplest way to run tasks and it is the base class for the [TaskConsumer][fluid.scheduler.TaskConsumer] and the[TaskScheduler][fluid.scheduler.TaskScheduler].
The Task Manager is a component that manages the execution of tasks. It is the simplest way to run tasks and it is the base class for the [TaskConsumer][fluid.scheduler.TaskConsumer]
and the [TaskScheduler][fluid.scheduler.TaskScheduler].

It can be imported from `fluid.scheduler`:

Expand Down
2 changes: 2 additions & 0 deletions docs/reference/utils.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Utils

::: fluid.utils.lazy.LazyGroup

::: fluid.utils.log.config
28 changes: 13 additions & 15 deletions fluid/scheduler/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,7 @@ class TaskManagerCLI(LazyGroup):

def __init__(
self,
task_manager_app: TaskManagerApp,
log_config: dict | None = None,
**kwargs: Any,
):
kwargs.setdefault("commands", DEFAULT_COMMANDS)
super().__init__(**kwargs)
self.task_manager_app: Annotated[
task_manager_app: Annotated[
TaskManagerApp,
Doc(
"""
Expand All @@ -54,20 +48,24 @@ def __init__(
or a string import path to a FastAPI app.
"""
),
] = task_manager_app
self.log_config: Annotated[
dict,
],
log_config: Annotated[
dict | None,
Doc(
"""
Log configuration parameters.

These parameters are passed to the log_config argument of
`fluid.utils.log.config()`.
These parameters are passed to the [log.config][fluid.utils.log.config]
function when configuring logging.
"""
),
] = (
log_config or {}
)
] = None,
**kwargs: Any,
):
kwargs.setdefault("commands", DEFAULT_COMMANDS)
super().__init__(**kwargs)
self.task_manager_app = task_manager_app
self.log_config = log_config or {}


def ctx_task_manager_cli(ctx: click.Context) -> TaskManagerCLI:
Expand Down
21 changes: 19 additions & 2 deletions fluid/utils/lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Any

import click
from typing_extensions import Annotated, Doc


class LazyGroup(click.Group):
Expand All @@ -19,8 +20,24 @@ class LazyGroup(click.Group):
def __init__(
self,
*,
lazy_subcommands: dict[str, str] | None = None,
**kwargs: Any,
lazy_subcommands: Annotated[
dict[str, str] | None,
Doc(
"""
A dictionary mapping command names to their import paths.

This allows subcommands to be lazily loaded from the specified module paths.
"""
),
] = None,
**kwargs: Annotated[
Any,
Doc(
"""
Additional keyword arguments passed to the click.Group initializer.
"""
),
],
):
super().__init__(**kwargs)
self.lazy_subcommands = lazy_subcommands or {}
Expand Down
74 changes: 62 additions & 12 deletions fluid/utils/log.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
from logging.config import dictConfig
from typing import Any, Sequence
from typing import Sequence

from typing_extensions import Annotated, Doc

try:
import pythonjsonlogger
Expand All @@ -22,22 +24,25 @@ def get_logger(name: str = "", prefix: bool = False) -> logging.Logger:
return logging.getLogger(name) if name else logger


def level_num(level: str) -> int:
def get_level_num(level: str | int) -> int:
if isinstance(level, int):
return level
return getattr(logging, level.upper())


def log_config(
level: int,
other_level: int = logging.WARNING,
level: str | int = settings.LOG_LEVEL,
other_level: str | int = logging.WARNING,
app_names: Sequence[str] = (settings.APP_NAME,),
log_handler: str = settings.LOG_HANDLER,
log_format: str = settings.PYTHON_LOG_FORMAT,
formatters: dict[str, dict[str, str]] | None = None,
) -> dict:
other_level = max(level, other_level)
level_num = get_level_num(level)
other_level_num = max(level_num, get_level_num(other_level))
log_handlers = {
"plain": {
"level": level,
"level": level_num,
"class": "logging.StreamHandler",
"formatter": "plain",
}
Expand All @@ -46,12 +51,12 @@ def log_config(
if pythonjsonlogger is not None:
log_handlers.update(
json={
"level": level,
"level": level_num,
"class": "logging.StreamHandler",
"formatter": "json",
},
nicejson={
"level": level,
"level": level_num,
"class": "logging.StreamHandler",
"formatter": "nicejson",
},
Expand All @@ -78,14 +83,59 @@ def log_config(
"formatters": log_formatters,
"handlers": log_handlers,
"loggers": {
app_name: {"level": level, "handlers": [log_handler], "propagate": 0}
app_name: {"level": level_num, "handlers": [log_handler], "propagate": 0}
for app_name in app_name_set
},
"root": {"level": other_level, "handlers": [log_handler]},
"root": {"level": other_level_num, "handlers": [log_handler]},
}


def config(**kwargs: Any) -> dict:
cfg = log_config(level_num(settings.LOG_LEVEL), **kwargs)
def config(
level: Annotated[
str | int,
Doc(
"Log levels for application loggers defined by the `app_names` parameter. "
"By default this value is taken from the `LOG_LEVEL` env variable"
),
] = settings.LOG_LEVEL,
other_level: Annotated[
str | int,
Doc("log levels for loggers not prefixed by `app_names`"),
] = logging.WARNING,
app_names: Annotated[
Sequence[str],
Doc(
"Application names for which the log level is set, "
"these are the prefixes which will be set at `log_level`"
),
] = (settings.APP_NAME,),
log_handler: Annotated[
str,
Doc(
"Log handler to use, by default it is taken from the "
"`LOG_HANDLER` env variable and if missing `plain` is used"
),
] = settings.LOG_HANDLER,
log_format: Annotated[
str,
Doc(
"log format to use, by default it is taken from the "
"`PYTHON_LOG_FORMAT` env variable"
),
] = settings.PYTHON_LOG_FORMAT,
formatters: Annotated[
dict[str, dict[str, str]] | None,
Doc("Additional formatters to add to the logging configuration"),
] = None,
) -> dict:
"""Configure logging for the application"""
cfg = log_config(
level=level,
other_level=other_level,
app_names=app_names,
log_handler=log_handler,
log_format=log_format,
formatters=formatters,
)
dictConfig(cfg)
return cfg
Loading