fix: apikey lock issue and add option to disable tracking (#8361)

* fix(api-key): avoid row-level locks by disabling usage tracking

* [autofix.ci] apply automated fixes

* chore: move parameter handling to settings service

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Ítalo Johnny 2025-06-04 14:05:55 -03:00 committed by GitHub
commit 227a091211
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 6 additions and 8 deletions

View file

@ -191,6 +191,7 @@ The following table lists the environment variables supported by Langflow.
| <Link id="LANGFLOW_DB_MAX_OVERFLOW"/><span class="env-prefix">LANGFLOW_</span>DB_MAX_OVERFLOW | Integer | `20` | **DEPRECATED:** Use <span class="env-prefix">LANGFLOW_</span>DB_CONNECTION_SETTINGS instead. The number of connections to allow that can be opened beyond the pool size. |
| <Link id="LANGFLOW_DB_CONNECT_TIMEOUT"/><span class="env-prefix">LANGFLOW_</span>DB_CONNECT_TIMEOUT | Integer | `20` | The number of seconds to wait before giving up on a lock to be released or establishing a connection to the database. |
| <Link id="LANGFLOW_DB_CONNECTION_SETTINGS"/><span class="env-prefix">LANGFLOW_</span>DB_CONNECTION_SETTINGS | JSON | Not set | A JSON dictionary to centralize database connection parameters. Example: `{"pool_size": 10, "max_overflow": 20}` |
| <Link id="LANGFLOW_DISABLE_TRACK_APIKEY_USAGE"/><span class="env-prefix">LANGFLOW_</span>DISABLE_TRACK_APIKEY_USAGE | Boolean | `false` | If set to `true`, disables tracking of API key usage (`total_uses` and `last_used_at`) to avoid database contention under high concurrency. |
| <Link id="LANGFLOW_ENABLE_LOG_RETRIEVAL"/><span class="env-prefix">LANGFLOW_</span>ENABLE_LOG_RETRIEVAL | Boolean | `false` | Enable log retrieval functionality. |
| <Link id="LANGFLOW_FALLBACK_TO_ENV_VAR"/><span class="env-prefix">LANGFLOW_</span>FALLBACK_TO_ENV_VAR | Boolean | `true` | If enabled, [global variables](../Configuration/configuration-global-variables.md) set in the Langflow UI fall back to an environment variable with the same name when Langflow fails to retrieve the variable value. |
| <Link id="LANGFLOW_FRONTEND_PATH"/><span class="env-prefix">LANGFLOW_</span>FRONTEND_PATH | String | `./frontend` | Path to the frontend directory containing build files. This is for development purposes only.<br/>See [`--frontend-path` option](./configuration-cli.md#run-frontend-path). |

View file

@ -1,4 +1,3 @@
import asyncio
import datetime
import secrets
from typing import TYPE_CHECKING
@ -10,7 +9,7 @@ from sqlmodel.ext.asyncio.session import AsyncSession
from langflow.services.database.models import User
from langflow.services.database.models.api_key import ApiKey, ApiKeyCreate, ApiKeyRead, UnmaskedApiKeyRead
from langflow.services.deps import session_scope
from langflow.services.deps import get_settings_service, session_scope
if TYPE_CHECKING:
from sqlmodel.sql.expression import SelectOfScalar
@ -50,17 +49,14 @@ async def delete_api_key(session: AsyncSession, api_key_id: UUID) -> None:
await session.commit()
update_total_uses_tasks: set[asyncio.Task] = set()
async def check_key(session: AsyncSession, api_key: str) -> User | None:
"""Check if the API key is valid."""
query: SelectOfScalar = select(ApiKey).options(selectinload(ApiKey.user)).where(ApiKey.api_key == api_key)
api_key_object: ApiKey | None = (await session.exec(query)).first()
if api_key_object is not None:
task = asyncio.create_task(update_total_uses(api_key_object.id))
task.add_done_callback(update_total_uses_tasks.discard)
update_total_uses_tasks.add(task)
settings_service = get_settings_service()
if settings_service.settings.disable_track_apikey_usage is not True:
await update_total_uses(api_key_object.id)
return api_key_object.user
return None

View file

@ -134,6 +134,7 @@ class Settings(BaseSettings):
prometheus_port: int = 9090
"""The port on which Langflow will expose Prometheus metrics. 9090 is the default port."""
disable_track_apikey_usage: bool = False
remove_api_keys: bool = False
components_path: list[str] = []
langchain_cache: str = "InMemoryCache"