Thanks to visit codestin.com
Credit goes to github.com

Skip to content

LCORE-1092: better docstring for quota scheduler#889

Merged
tisnik merged 1 commit into
lightspeed-core:mainfrom
tisnik:lcore-1092-better-docstring-for-quota-scheduler
Dec 9, 2025
Merged

LCORE-1092: better docstring for quota scheduler#889
tisnik merged 1 commit into
lightspeed-core:mainfrom
tisnik:lcore-1092-better-docstring-for-quota-scheduler

Conversation

@tisnik

@tisnik tisnik commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Description

LCORE-1092: better docstring for quota scheduler

Type of change

  • Refactor
  • New feature
  • Bug fix
  • CVE fix
  • Optimization
  • Documentation Update
  • Configuration Update
  • Bump-up service version
  • Bump-up dependent library
  • Bump-up library or tool used for development (does not change the final image)
  • CI configuration change
  • Konflux configuration change
  • Unit tests improvement
  • Integration tests improvement
  • End to end tests improvement

Tools used to create PR

Identify any AI code assistants used in this PR (for transparency and review context)

  • Assisted-by: CodeRabbitAI
  • Generated by: N/A

Related Tickets & Documents

  • Related Issue #LCORE-1092

Summary by CodeRabbit

  • Refactor
    • Enhanced quota scheduler thread handling and expanded documentation for improved application reliability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Expanded docstrings throughout the quota_scheduler module to document loop behavior, configuration validation, backend selection, and SQL statement generation. Updated thread initialization in start_quota_scheduler to run as a daemon and pass configuration arguments explicitly.

Changes

Cohort / File(s) Change summary
Documentation and thread initialization updates
src/runners/quota_scheduler.py
Expanded module-level and function docstrings for quota_scheduler, get_increase_quota_statement, get_reset_quota_statement, quota_revocation, increase_quota, reset_quota, get_subject_id, connect, init_tables, and start_quota_scheduler. Updated start_quota_scheduler to create daemon thread with explicit configuration arguments.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

  • Review scope is limited to a single file with primarily docstring/documentation expansion
  • One minor functional change: daemon thread creation with configuration argument passing
  • No complex logic, control flow changes, or multi-file interactions

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: improving docstrings for the quota scheduler module. It is specific, concise, and directly related to the documented changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fbbe74 and d34e5cb.

📒 Files selected for processing (1)
  • src/runners/quota_scheduler.py (9 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Use absolute imports for internal modules in LCS project (e.g., from auth import get_auth_dependency)
All modules must start with descriptive docstrings explaining their purpose
Use logger = logging.getLogger(__name__) pattern for module logging
All functions must include complete type annotations for parameters and return types, using modern syntax (str | int) and Optional[Type] or Type | None
All functions must have docstrings with brief descriptions following Google Python docstring conventions
Function names must use snake_case with descriptive, action-oriented names (get_, validate_, check_)
Avoid in-place parameter modification anti-patterns; return new data structures instead of modifying input parameters
Use async def for I/O operations and external API calls
All classes must include descriptive docstrings explaining their purpose following Google Python docstring conventions
Class names must use PascalCase with descriptive names and standard suffixes: Configuration for config classes, Error/Exception for exceptions, Resolver for strategy patterns, Interface for abstract base classes
Abstract classes must use ABC with @abstractmethod decorators
Include complete type annotations for all class attributes in Python classes
Use import logging and module logger pattern with standard log levels: debug, info, warning, error

Files:

  • src/runners/quota_scheduler.py
🧬 Code graph analysis (1)
src/runners/quota_scheduler.py (1)
src/models/config.py (1)
  • QuotaHandlersConfiguration (1325-1362)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Konflux kflux-prd-rh02 / lightspeed-stack-on-pull-request
  • GitHub Check: build-pr
  • GitHub Check: E2E: server mode / azure
  • GitHub Check: E2E: library mode / ci
  • GitHub Check: E2E: server mode / ci
  • GitHub Check: E2E: library mode / azure
🔇 Additional comments (8)
src/runners/quota_scheduler.py (8)

31-44: Excellent documentation for the scheduler loop.

The docstring clearly describes the infinite loop behavior, validation logic, and return semantics. Well done following Google style conventions.


90-99: Clear documentation of backend-specific SQL statement selection.

The docstring accurately describes the backend selection logic and return values.


179-194: Thorough documentation with clear parameter descriptions.

The docstring provides comprehensive details about each parameter and the SQL execution behavior.


225-235: Well-documented quota reset operation.

The docstring clearly explains the purpose and parameters of the reset operation.


260-269: Clear mapping documentation with fallback handling.

The docstring accurately describes the type-to-identifier mapping, including the unrecognized case fallback.


280-290: Comprehensive connection logic documentation.

The docstring clearly describes backend selection and the None return case when neither backend is configured.


300-306: Clear table initialization documentation.

The docstring accurately describes the table creation process and commit behavior.


315-327: Good documentation and thread initialization improvement.

The docstring clearly describes the daemon thread usage. The thread initialization at lines 323-327 with explicit daemon=True and args parameters is a good practice improvement, making the background task behavior explicit and ensuring proper cleanup on program exit.

Comment on lines +106 to +112
"""
Return the SQL statement used to reset quota records for the configured database backend.

Returns:
str: The SQLite reset SQL statement when `config.sqlite` is set,
otherwise the PostgreSQL reset SQL statement.
"""

@coderabbitai coderabbitai Bot Dec 9, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add missing Parameters section.

The config parameter is not documented. For consistency with other docstrings in this file and to fully satisfy the PR objective of improving documentation, please add a Parameters section.

Apply this diff to add the missing documentation:

 def get_reset_quota_statement(config: QuotaHandlersConfiguration) -> str:
     """
     Return the SQL statement used to reset quota records for the configured database backend.
 
+    Parameters:
+        config (QuotaHandlersConfiguration): Configuration that indicates which
+        storage backend (SQLite or PostgreSQL) is in use.
+
     Returns:
         str: The SQLite reset SQL statement when `config.sqlite` is set,
         otherwise the PostgreSQL reset SQL statement.
     """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"""
Return the SQL statement used to reset quota records for the configured database backend.
Returns:
str: The SQLite reset SQL statement when `config.sqlite` is set,
otherwise the PostgreSQL reset SQL statement.
"""
"""
Return the SQL statement used to reset quota records for the configured database backend.
Parameters:
config (QuotaHandlersConfiguration): Configuration that indicates which
storage backend (SQLite or PostgreSQL) is in use.
Returns:
str: The SQLite reset SQL statement when `config.sqlite` is set,
otherwise the PostgreSQL reset SQL statement.
"""
🤖 Prompt for AI Agents
In src/runners/quota_scheduler.py around lines 106 to 112, the docstring for the
function that returns the SQL reset statement is missing a Parameters section
for the config parameter; add a Parameters section directly after the short
description and before Returns that documents config: its expected type (e.g., a
config object or module), that it indicates which DB backend to use
(config.sqlite True for SQLite, otherwise PostgreSQL), and any attributes
accessed (e.g., config.sqlite), plus a brief example or note if necessary; keep
wording consistent with other docstrings in the file and match the existing
style.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai create issue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create GitHub issue for missing Parameters section in docstring
gh issue create \
  --repo lightspeed-core/lightspeed-stack \
  --title "Add missing Parameters section to get_reset_quota_statement docstring" \
  --body "## Description

The docstring for the \`get_reset_quota_statement\` function in \`src/runners/quota_scheduler.py\` is missing a Parameters section to document the \`config\` parameter.

For consistency with other docstrings in the file and to fully satisfy documentation standards, a Parameters section should be added.

## Location
- File: \`src/runners/quota_scheduler.py\`
- Function: \`get_reset_quota_statement\`

## References
- Pull Request: https://github.com/lightspeed-core/lightspeed-stack/pull/889
- Review Comment: https://github.com/lightspeed-core/lightspeed-stack/pull/889#discussion_r2602221946
- Requested by: @tisnik" \
  --assignee tisnik

Length of output: 62


@tisnik I've created issue #891 to track the missing Parameters section in the get_reset_quota_statement docstring. The issue has been assigned to you and includes references to this PR and review comment.


🧬 Code Graph Analysis Results
  • File: src/models/config.py (lines 1325-1362)
    QuotaHandlersConfiguration:

    class QuotaHandlersConfiguration(ConfigurationBase):
        """Quota limiter configuration.
    
        It is possible to limit quota usage per user or per service or services
        (that typically run in one cluster). Each limit is configured as a separate
        _quota limiter_. It can be of type `user_limiter` or `cluster_limiter`
        (which is name that makes sense in OpenShift deployment).
        """
    
        sqlite: Optional[SQLiteDatabaseConfiguration] = Field(
            None,
            title="SQLite configuration",
            description="SQLite database configuration",
        )
    
        postgres: Optional[PostgreSQLDatabaseConfiguration] = Field(
            None,
            title="PostgreSQL configuration",
            description="PostgreSQL database configuration",
        )
    
        limiters: list[QuotaLimiterConfiguration] = Field(
            default_factory=list,
            title="Quota limiters",
            description="Quota limiters configuration",
        )
    
        scheduler: QuotaSchedulerConfiguration = Field(
            default_factory=lambda: QuotaSchedulerConfiguration(period=1),
            title="Quota scheduler",
            description="Quota scheduler configuration",
        )
    
        enable_token_history: bool = Field(
            False,
            title="Enable token history",
            description="Enables storing information about token usage history",
        )
    
  • File: src/models/config.py (lines 1262-1312)
    QuotaLimiterConfiguration:

    class QuotaLimiterConfiguration(ConfigurationBase):
        """Configuration for one quota limiter.
    
        There are three configuration options for each limiter:
    
        1. ``period`` is specified in a human-readable form, see
           https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
           for all possible options. When the end of the period is reached, the
           quota is reset or increased.
        2. ``initial_quota`` is the value set at the beginning of the period.
        3. ``quota_increase`` is the value (if specified) used to increase the
           quota when the period is reached.
    
        There are two basic use cases:
    
        1. When the quota needs to be reset to a specific value periodically (for
           example on a weekly or monthly basis), set ``initial_quota`` to the
           required value.
        2. When the quota needs to be increased by a specific value periodically
           (for example on a daily basis), set ``quota_increase``.
        """
    
        type: Literal["user_limiter", "cluster_limiter"] = Field(
            ...,
            title="Quota limiter type",
            description="Quota limiter type, either user_limiter or cluster_limiter",
        )
    
        name: str = Field(
            ...,
            title="Quota limiter name",
            description="Human readable quota limiter name",
        )
    
        initial_quota: NonNegativeInt = Field(
            ...,
            title="Initial quota",
            description="Quota set at beginning of the period",
        )
    
        quota_increase: NonNegativeInt = Field(
            ...,
            title="Quota increase",
            description="Delta value used to increase quota when period is reached",
        )
    
        period: str = Field(
            ...,
            title="Period",
            description="Period specified in human readable form",
        )
    
  • File: src/configuration.py (lines 73-77)
    configuration() method:

    def configuration(self) -> Configuration:
            """Return the whole configuration."""
            if self._configuration is None:
                raise LogicError("logic error: configuration is not loaded")
            return self._configuration
    
  • File: src/log.py (lines 7-13)
    get_logger:

    def get_logger(name: str) -> logging.Logger:
        """Retrieve logger with the provided name."""
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        logger.handlers = [RichHandler()]
        logger.propagate = False
        return logger
    
  • File: src/quota/connect_sqlite.py (lines 12-25)
    connect_sqlite:

    def connect_sqlite(config: SQLiteDatabaseConfiguration) -> Any:
        """Initialize connection to database."""
        logger.info("Connecting to SQLite storage")
        # make sure the connection will have known state
        # even if SQLite is not alive
        connection = None
        try:
            connection = sqlite3.connect(database=config.db_path)
            if connection is not None:
                connection.autocommit = True
            return connection
        except sqlite3.Error as e:
            logger.exception("Error initializing SQLite cache:\n%s", e)
            raise
    
  • File: src/quota/connect_pg.py (lines 12-31)
    connect_pg:

    def connect_pg(config: PostgreSQLDatabaseConfiguration) -> Any:
        """Initialize connection to PostgreSQL database."""
        logger.info("Connecting to PostgreSQL storage")
        try:
            connection = psycopg2.connect(
                host=config.host,
                port=config.port,
                user=config.user,
                password=config.password.get_secret_value(),
                dbname=config.db,
                sslmode=config.ssl_mode,
                # sslrootcert=config.ca_cert_path,
                gssencmode=config.gss_encmode,
            )
            if connection is not None:
                connection.autocommit = True
            return connection
        except psycopg2.Error as e:
            logger.exception("Error connecting to PostgreSQL database:\n%s", e)
            raise
    
  • File: src/utils/connection_decorator.py (lines 6-48)
    connection decorator:

    def connection(f: Callable) -> Callable:
        """
        Ensure a connectable object is connected before invoking the wrapped function.
    
        The returned wrapper calls `connectable.connected()` and, if that returns
        `False`, calls `connectable.connect()` prior to delegating to the original
        function.
    
        Parameters:
            f (Callable): The function to wrap. The wrapped function is
            expected to accept a `connectable` first argument.
    
        Returns:
            Callable: A wrapper function with signature `(connectable,
            *args, **kwargs)` that ensures `connectable` is connected
            before calling `f`.
    
        Example:
        ```python
        @connection
        def list_history(self) -> list[str]:
           pass
        ```
        """
    
        def wrapper(connectable: Any, *args: Any, **kwargs: Any) -> Callable:
            """
            Ensure the provided connectable is connected, then call the wrapped with the same arguments.
    
            Parameters:
                connectable (Any): Object that implements `connected()` -> bool and
                `?connected()` -> None; will be connected if not already.
                    *args (Any): Positional arguments forwarded to the wrapped callable.
                    **kwargs (Any): Keyword arguments forwarded to the wrapped callable.
    
            Returns:
                    Any: The value returned by the wrapped callable.
            """
            if not connectable.connected():
                connectable.connect()
            return f(connectable, *args, **kwargs)
    
        return wrapper
    

Comment on lines +124 to +138
"""
Apply configured quota updates for a quota limiter using the provided database connection.

Processes the given limiter: increases quota when `quota_increase` is set
and resets initial quota when `initial_quota` is greater than zero, using
the supplied SQL statements.

Parameters:
quota_limiter (QuotaLimiterConfiguration): Limiter configuration to process.
increase_quota_statement (str): SQL statement used to increment quota values.
reset_quota_statement (str): SQL statement used to reset quota values.

Raises:
ValueError: If the limiter's `type` or `period` is not set.
"""

@coderabbitai coderabbitai Bot Dec 9, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Document the connection parameter.

The connection parameter is missing from the Parameters section. Since this PR aims to improve docstrings, all parameters should be documented for completeness.

Apply this diff to add the missing documentation:

     """
     Apply configured quota updates for a quota limiter using the provided database connection.
 
     Processes the given limiter: increases quota when `quota_increase` is set
     and resets initial quota when `initial_quota` is greater than zero, using
     the supplied SQL statements.
 
     Parameters:
+        connection (Any): Database connection object (Postgres or SQLite) used
+                          to execute quota update statements.
         quota_limiter (QuotaLimiterConfiguration): Limiter configuration to process.
         increase_quota_statement (str): SQL statement used to increment quota values.
         reset_quota_statement (str): SQL statement used to reset quota values.
 
     Raises:
         ValueError: If the limiter's `type` or `period` is not set.
     """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"""
Apply configured quota updates for a quota limiter using the provided database connection.
Processes the given limiter: increases quota when `quota_increase` is set
and resets initial quota when `initial_quota` is greater than zero, using
the supplied SQL statements.
Parameters:
quota_limiter (QuotaLimiterConfiguration): Limiter configuration to process.
increase_quota_statement (str): SQL statement used to increment quota values.
reset_quota_statement (str): SQL statement used to reset quota values.
Raises:
ValueError: If the limiter's `type` or `period` is not set.
"""
"""
Apply configured quota updates for a quota limiter using the provided database connection.
Processes the given limiter: increases quota when `quota_increase` is set
and resets initial quota when `initial_quota` is greater than zero, using
the supplied SQL statements.
Parameters:
connection (Any): Database connection object (Postgres or SQLite) used
to execute quota update statements.
quota_limiter (QuotaLimiterConfiguration): Limiter configuration to process.
increase_quota_statement (str): SQL statement used to increment quota values.
reset_quota_statement (str): SQL statement used to reset quota values.
Raises:
ValueError: If the limiter's `type` or `period` is not set.
"""
🤖 Prompt for AI Agents
In src/runners/quota_scheduler.py around lines 124 to 138, the docstring's
Parameters section omits the connection parameter; update the docstring to add a
description for connection (e.g., type: DB connection or
Connection/ConnectionLike, purpose: DB connection used to execute the provided
SQL statements) consistent with existing style and wording, placing it alongside
the other parameters and ensuring types and brief purpose are documented.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai create issue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create a GitHub issue for the missing connection parameter documentation

gh issue create \
  --repo lightspeed-core/lightspeed-stack \
  --title "Document connection parameter in quota_revocation docstring" \
  --body "The \`connection\` parameter in the \`quota_revocation\` function (src/runners/quota_scheduler.py) is missing from the docstring's Parameters section.

Related to PR #889 which aims to improve docstrings for the quota scheduler.

**Context:**
- File: \`src/runners/quota_scheduler.py\`
- Function: \`quota_revocation\`
- Issue: The \`connection\` parameter needs to be documented in the Parameters section

**References:**
- PR: https://github.com/lightspeed-core/lightspeed-stack/pull/889
- Comment: https://github.com/lightspeed-core/lightspeed-stack/pull/889#discussion_r2602221964

Requested by: @tisnik" \
  --assignee tisnik

Length of output: 62


@tisnik, I've created issue #892 to track the missing connection parameter documentation in the quota_revocation function's docstring. The issue has been assigned to you and includes references back to this PR and comment.


🧬 Code Graph Analysis Results

[src/configuration.py] lines 1325-1362

class QuotaLimiterConfiguration(ConfigurationBase):
    """Configuration for one quota limiter.

    There are three configuration options for each limiter:

    1. ``period`` is specified in a human-readable form, see
       https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
       for all possible options. When the end of the period is reached, the
       quota is reset or increased.
    2. ``initial_quota`` is the value set at the beginning of the period.
    3. ``quota_increase`` is the value (if specified) used to increase the
       quota when the period is reached.

    There are two basic use cases:

    1. When the quota needs to be reset to a specific value periodically (for
       example on a weekly or monthly basis), set ``initial_quota`` to the
       required value.
    2. When the quota needs to be increased by a specific value periodically
       (for example on a daily basis), set ``quota_increase``.
    """

    type: Literal["user_limiter", "cluster_limiter"] = Field(
        ...,
        title="Quota limiter type",
        description="Quota limiter type, either user_limiter or cluster_limiter",
    )

    name: str = Field(
        ...,
        title="Quota limiter name",
        description="Human readable quota limiter name",
    )

    initial_quota: NonNegativeInt = Field(
        ...,
        title="Initial quota",
        description="Quota set at beginning of the period",
    )

    quota_increase: NonNegativeInt = Field(
        ...,
        title="Quota increase",
        description="Delta value used to increase quota when period is reached",
    )

    period: str = Field(
        ...,
        title="Period",
        description="Period specified in human readable form",
    )

[src/configuration.py] lines 1262-1312

class QuotaLimiterConfiguration(ConfigurationBase):
    """Configuration for one quota limiter.

    There are three configuration options for each limiter:

    1. ``period`` is specified in a human-readable form, see
       https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
       for all possible options. When the end of the period is reached, the
       quota is reset or increased.
    2. ``initial_quota`` is the value set at the beginning of the period.
    3. ``quota_increase`` is the value (if specified) used to increase quota when the period is reached.

    There are two basic use cases:

    1. When the quota needs to be reset to a specific value periodically (for
       example on a weekly or monthly basis), set ``initial_quota`` to the
       required value.
    2. When the quota needs to be increased by a specific value periodically
       (for example on a daily basis), set ``quota_increase``.
    """

    type: Literal["user_limiter", "cluster_limiter"] = Field(
        ...,
        title="Quota limiter type",
        description="Quota limiter type, either user_limiter or cluster_limiter",
    )

    name: str = Field(
        ...,
        title="Quota limiter name",
        description="Human readable quota limiter name",
    )

    initial_quota: NonNegativeInt = Field(
        ...,
        title="Initial quota",
        description="Quota set at beginning of the period",
    )

    quota_increase: NonNegativeInt = Field(
        ...,
        title="Quota increase",
        description="Delta value used to increase quota when period is reached",
    )

    period: str = Field(
        ...,
        title="Period",
        description="Period specified in human readable form",
    )

[src/quota/connect_sqlite.py] lines 12-25

def connect_sqlite(config: SQLiteDatabaseConfiguration) -> Any:
    """Initialize connection to database."""
    logger.info("Connecting to SQLite storage")
    # make sure the connection will have known state
    # even if SQLite is not alive
    connection = None
    try:
        connection = sqlite3.connect(database=config.db_path)
        if connection is not None:
            connection.autocommit = True
        return connection
    except sqlite3.Error as e:
        logger.exception("Error initializing SQLite cache:\n%s", e)
        raise

[src/quota/connect_pg.py] lines 12-31

def connect_pg(config: PostgreSQLDatabaseConfiguration) -> Any:
    """Initialize connection to PostgreSQL database."""
    logger.info("Connecting to PostgreSQL storage")
    try:
        connection = psycopg2.connect(
            host=config.host,
            port=config.port,
            user=config.user,
            password=config.password.get_secret_value(),
            dbname=config.db,
            sslmode=config.ssl_mode,
            # sslrootcert=config.ca_cert_path,
            gssencmode=config.gss_encmode,
        )
        if connection is not None:
            connection.autocommit = True
        return connection
    except psycopg2.Error as e:
        logger.exception("Error connecting to PostgreSQL database:\n%s", e)
        raise

[src/utils/connection_decorator.py] lines 6-48

def connection(f: Callable) -> Callable:
    """
    Ensure a connectable object is connected before invoking the wrapped function.

    The returned wrapper calls `connectable.connected()` and, if that returns
    `False`, calls `connectable.connect()` prior to delegating to the original
    function.

    Parameters:
        f (Callable): The function to wrap. The wrapped function is
        expected to accept a `connectable` first argument.

    Returns:
        Callable: A wrapper function with signature `(connectable,
        *args, **kwargs)` that ensures `connectable` is connected
        before calling `f`.

    Example:
    ```python
    @connection
    def list_history(self) -> list[str]:
       pass
    ```
    """

    def wrapper(connectable: Any, *args: Any, **kwargs: Any) -> Callable:
        """
        Ensure the provided connectable is connected, then call the wrapped with the same arguments.

        Parameters:
            connectable (Any): Object that implements `connected()` -> bool and
            `connect()` -> None; will be connected if not already.
                *args (Any): Positional arguments forwarded to the wrapped callable.
                **kwargs (Any): Keyword arguments forwarded to the wrapped callable.

        Returns:
                Any: The value returned by the wrapped callable.
        """
        if not connectable.connected():
            connectable.connect()
        return f(connectable, *args, **kwargs)

    return wrapper

[src/models/config.py] lines 1325-1365 (within provided excerpt)

class QuotaHandlersConfiguration(ConfigurationBase):
    """Quota limiter configuration.

    It is possible to limit quota usage per user or per service or services
    (that typically run in one cluster). Each limit is configured as a separate
    _quota limiter_. It can be of type `user_limiter` or `cluster_limiter`
    (which is name that makes sense in OpenShift deployment).
    """

    sqlite: Optional[SQLiteDatabaseConfiguration] = Field(
        None,
        title="SQLite configuration",
        description="SQLite database configuration",
    )

    postgres: Optional[PostgreSQLDatabaseConfiguration] = Field(
        None,
        title="PostgreSQL configuration",
        description="PostgreSQL database configuration",
    )

    limiters: list[QuotaLimiterConfiguration] = Field(
        default_factory=list,
        title="Quota limiters",
        description="Quota limiters configuration",
    )

    scheduler: QuotaSchedulerConfiguration = Field(
        default_factory=lambda: QuotaSchedulerConfiguration(period=1),
        title="Quota scheduler",
        description="Quota scheduler configuration",
    )

    enable_token_history: bool = Field(
        False,
        title="Enable token history",
        description="Enables storing information about token usage history",
    )

[src/models/config.py] lines 1365-1479 (within provided excerpt)

class Configuration(ConfigurationBase):
    """Global service configuration."""

    name: str = Field(
        ...,
        title="Service name",
        description="Name of the service. That value will be used in REST API endpoints.",
    )

    service: ServiceConfiguration = Field(
        ...,
        title="Service configuration",
        description="This section contains Lightspeed Core Stack service configuration.",
    )

    llama_stack: LlamaStackConfiguration = Field(
        ...,
        title="Llama Stack configuration",
        description="This section contains Llama Stack configuration. "
        "Lightspeed Core Stack service can call Llama Stack in library mode or in server mode.",
    )

    user_data_collection: UserDataCollection = Field(
        ...,
        title="User data collection configuration",
        description="This section contains configuration for subsystem that collects user data"
        "(transcription history and feedbacks).",
    )

    database: DatabaseConfiguration = Field(
        default_factory=lambda: DatabaseConfiguration(sqlite=None, postgres=None),
        title="Database Configuration",
        description="Configuration for database to store conversation IDs and other runtime data",
    )

    mcp_servers: list[ModelContextProtocolServer] = Field(
        default_factory=list,
        title="Model Context Protocol Server and tools configuration",
        description="MCP (Model Context Protocol) servers provide tools and "
        "capabilities to the AI agents. These are configured in this section. "
        "Only MCP servers defined in the lightspeed-stack.yaml configuration are "
        "available to lightspeed-core agents. Tools configured in the llama-stack run.yaml "
        "are not accessible to lightspeed-core agents.",
    )

    authentication: AuthenticationConfiguration = Field(
        default_factory=AuthenticationConfiguration,
        title="Authentication configuration",
        description="Authentication configuration",
    )

    authorization: Optional[AuthorizationConfiguration] = Field(
        None,
        title="Authorization configuration",
        description="Lightspeed Core Stack implements a modular "
        "authentication and authorization system with multiple authentication "
        "methods. Authorization is configurable through role-based access "
        "control. Authentication is handled through selectable modules "
        "configured via the module field in the authentication configuration.",
    )

    customization: Optional[Customization] = Field(
        None,
        title="Custom profile configuration",
        description="It is possible to customize Lightspeed Core Stack via this "
        "section. System prompt can be customized and also different parts of "
        "the service can be replaced by custom Python modules.",
    )

    inference: InferenceConfiguration = Field(
        default_factory=lambda: InferenceConfiguration(
            default_model=None, default_provider=None
        ),
        title="Inference configuration",
        description="One LLM provider and one its model might be selected as "
        "default ones. When no provider+model pair is specified in REST API "
        "calls (query endpoints), the default provider and model are used.",
    )

    conversation_cache: ConversationHistoryConfiguration = Field(
        default_factory=lambda: ConversationHistoryConfiguration(
            type=None, memory=None, sqlite=None, postgres=None
        ),
        title="Conversation history configuration",
        description="Conversation history configuration.",
    )

    byok_rag: list[ByokRag] = Field(
        default_factory=list,
        title="BYOK RAG configuration",
        description="BYOK RAG configuration. This configuration can be used to "
        "reconfigure Llama Stack through its run.yaml configuration file",
    )

    quota_handlers: QuotaHandlersConfiguration = Field(
        default_factory=lambda: QuotaHandlersConfiguration(
            sqlite=None, postgres=None, enable_token_history=False
        ),
        title="Quota handlers",
        description="Quota handlers configuration",
    )

    def dump(self, filename: str = "configuration.json") -> None:
        """
        Write the current Configuration model to a JSON file.

        The configuration is serialized with an indentation of 4 spaces using
        the model's JSON representation and written with UTF-8 encoding. If the
        file exists it will be overwritten.

        Parameters:
            filename (str): Path to the output file (defaults to "configuration.json").
        """
        with open(filename, "w", encoding="utf-8") as fout:
            fout.write(self.model_dump_json(indent=4))

@tisnik tisnik merged commit 4269f0b into lightspeed-core:main Dec 9, 2025
21 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant