Skip to content

Commit

Permalink
Add ALL ruff rules for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
cbornet committed Oct 17, 2024
1 parent 45c8f98 commit 92089ec
Show file tree
Hide file tree
Showing 57 changed files with 413 additions and 364 deletions.
38 changes: 38 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,44 @@ directory = "coverage"
exclude = ["src/backend/langflow/alembic/*"]
line-length = 120

[tool.ruff.lint]
pydocstyle.convention = "google"
select = ["ALL"]
ignore = [
"C90", # McCabe complexity
"CPY", # Missing copyright
"COM812", # Messes with the formatter
"ERA", # Eradicate commented-out code
"FIX002", # Line contains TODO
"ISC001", # Messes with the formatter
"PERF203", # Rarely useful
"PLR09", # Too many something (arg, statements, etc)
"RUF012", # Pydantic models are currently not well detected. See https://github.com/astral-sh/ruff/issues/13630
"TD002", # Missing author in TODO
"TD003", # Missing issue link in TODO
"TRY301", # A bit too harsh (Abstract `raise` to an inner function)

# Rules that are TODOs
"ANN",
"INP",
]

# Preview rules that are not yet activated
external = ["RUF027"]

[tool.ruff.lint.per-file-ignores]
"scripts/*" = [
"D1",
"INP",
"T201",
]
"src/backend/tests/*" = [
"D1",
"PLR2004",
"S101",
"SLF001",
]

[tool.mypy]
plugins = ["pydantic.mypy"]
follow_imports = "skip"
Expand Down
12 changes: 7 additions & 5 deletions scripts/ci/pypi_nightly_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
PYPI_LANGFLOW_BASE_URL = "https://pypi.org/pypi/langflow-base/json"
PYPI_LANGFLOW_BASE_NIGHTLY_URL = "https://pypi.org/pypi/langflow-base-nightly/json"

ARGUMENT_NUMBER = 2

def get_latest_published_version(build_type: str, is_nightly: bool) -> Version:

def get_latest_published_version(build_type: str, *, is_nightly: bool) -> Version:
import requests

url = ""
Expand All @@ -25,12 +27,12 @@ def get_latest_published_version(build_type: str, is_nightly: bool) -> Version:
msg = f"Invalid build type: {build_type}"
raise ValueError(msg)

res = requests.get(url)
res = requests.get(url, timeout=10)
try:
version_str = res.json()["info"]["version"]
except Exception as e:
msg = "Got unexpected response from PyPI"
raise RuntimeError(msg, e)
raise RuntimeError(msg) from e
return Version(version_str)


Expand Down Expand Up @@ -74,9 +76,9 @@ def create_tag(build_type: str):


if __name__ == "__main__":
if len(sys.argv) != 2:
if len(sys.argv) != ARGUMENT_NUMBER:
msg = "Specify base or main"
raise Exception(msg)
raise ValueError(msg)

build_type = sys.argv[1]
tag = create_tag(build_type)
Expand Down
14 changes: 7 additions & 7 deletions scripts/ci/update_lf_base_dependency.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/usr/bin/env python

import re
import sys
from pathlib import Path

import packaging.version

BASE_DIR = Path(__file__).parent.parent.parent
ARGUMENT_NUMBER = 2


def update_base_dep(pyproject_path: str, new_version: str) -> None:
Expand All @@ -18,7 +21,7 @@ def update_base_dep(pyproject_path: str, new_version: str) -> None:
pattern = re.compile(r'langflow-base = \{ path = "\./src/backend/base", develop = true \}')
if not pattern.search(content):
msg = f'langflow-base poetry dependency not found in "{filepath}"'
raise Exception(msg)
raise ValueError(msg)
content = pattern.sub(replacement, content)
filepath.write_text(content, encoding="utf-8")

Expand All @@ -28,16 +31,13 @@ def verify_pep440(version):
https://github.com/pypa/packaging/blob/16.7/packaging/version.py#L191
"""
try:
return packaging.version.Version(version)
except packaging.version.InvalidVersion:
raise
return packaging.version.Version(version)


def main() -> None:
if len(sys.argv) != 2:
if len(sys.argv) != ARGUMENT_NUMBER:
msg = "New version not specified"
raise Exception(msg)
raise ValueError(msg)
base_version = sys.argv[1]

# Strip "v" prefix from version if present
Expand Down
11 changes: 7 additions & 4 deletions scripts/ci/update_pyproject_name.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#!/usr/bin/env python

import re
import sys
from pathlib import Path

BASE_DIR = Path(__file__).parent.parent.parent
ARGUMENT_NUMBER = 3


def update_pyproject_name(pyproject_path: str, new_project_name: str) -> None:
Expand All @@ -15,7 +18,7 @@ def update_pyproject_name(pyproject_path: str, new_project_name: str) -> None:

if not pattern.search(content):
msg = f'Project name not found in "{filepath}"'
raise Exception(msg)
raise ValueError(msg)
content = pattern.sub(new_project_name, content)

filepath.write_text(content, encoding="utf-8")
Expand All @@ -39,15 +42,15 @@ def update_uv_dep(pyproject_path: str, new_project_name: str) -> None:
# Updates the dependency name for uv
if not pattern.search(content):
msg = f"{replacement} uv dependency not found in {filepath}"
raise Exception(msg)
raise ValueError(msg)
content = pattern.sub(replacement, content)
filepath.write_text(content, encoding="utf-8")


def main() -> None:
if len(sys.argv) != 3:
if len(sys.argv) != ARGUMENT_NUMBER:
msg = "Must specify project name and build type, e.g. langflow-nightly base"
raise Exception(msg)
raise ValueError(msg)
new_project_name = sys.argv[1]
build_type = sys.argv[2]

Expand Down
14 changes: 7 additions & 7 deletions scripts/ci/update_pyproject_version.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/usr/bin/env python

import re
import sys
from pathlib import Path

import packaging.version

BASE_DIR = Path(__file__).parent.parent.parent
ARGUMENT_NUMBER = 3


def update_pyproject_version(pyproject_path: str, new_version: str) -> None:
Expand All @@ -17,7 +20,7 @@ def update_pyproject_version(pyproject_path: str, new_version: str) -> None:

if not pattern.search(content):
msg = f'Project version not found in "{filepath}"'
raise Exception(msg)
raise ValueError(msg)

content = pattern.sub(new_version, content)

Expand All @@ -29,16 +32,13 @@ def verify_pep440(version):
https://github.com/pypa/packaging/blob/16.7/packaging/version.py#L191
"""
try:
return packaging.version.Version(version)
except packaging.version.InvalidVersion:
raise
return packaging.version.Version(version)


def main() -> None:
if len(sys.argv) != 3:
if len(sys.argv) != ARGUMENT_NUMBER:
msg = "New version not specified"
raise Exception(msg)
raise ValueError(msg)
new_version = sys.argv[1]

# Strip "v" prefix from version if present
Expand Down
9 changes: 6 additions & 3 deletions scripts/ci/update_uv_dependency.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#!/usr/bin/env python

import re
import sys
from pathlib import Path

BASE_DIR = Path(__file__).parent.parent.parent
ARGUMENT_NUMBER = 2


def update_uv_dep(base_version: str) -> None:
Expand All @@ -19,7 +22,7 @@ def update_uv_dep(base_version: str) -> None:
# Check if the pattern is found
if not pattern.search(content):
msg = f"{pattern} UV dependency not found in {pyproject_path}"
raise Exception(msg)
raise ValueError(msg)

# Replace the matched pattern with the new one
content = pattern.sub(replacement, content)
Expand All @@ -29,9 +32,9 @@ def update_uv_dep(base_version: str) -> None:


def main() -> None:
if len(sys.argv) != 2:
if len(sys.argv) != ARGUMENT_NUMBER:
msg = "specify base version"
raise Exception(msg)
raise ValueError(msg)
base_version = sys.argv[1]
base_version = base_version.lstrip("v")
update_uv_dep(base_version)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from langflow.base.tools.constants import TOOL_OUTPUT_NAME
from langflow.custom.tree_visitor import RequiredInputsVisitor
from langflow.field_typing import Tool # noqa: TCH001 Needed by add_toolkit_output
from langflow.field_typing import Tool # noqa: TCH001 Needed by _add_toolkit_output
from langflow.graph.state.model import create_state_model
from langflow.helpers.custom import format_type
from langflow.schema.artifact import get_artifact_type, post_process_raw
Expand Down
1 change: 1 addition & 0 deletions src/backend/langflow/version/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Version package."""
7 changes: 6 additions & 1 deletion src/backend/langflow/version/version.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
"""Module for package versioning."""

import contextlib


def get_version() -> str:
"""Retrieves the version of the package from a possible list of package names.
This accounts for after package names are updated for -nightly builds.
Returns:
Expand Down Expand Up @@ -32,7 +35,9 @@ def get_version() -> str:


def is_pre_release(v: str) -> bool:
"""Returns a boolean indicating whether the version is a pre-release version,
"""Returns a boolean indicating whether the version is a pre-release version.
Returns a boolean indicating whether the version is a pre-release version,
as per the definition of a pre-release segment from PEP 440.
"""
return any(label in v for label in ["a", "b", "rc"])
38 changes: 26 additions & 12 deletions src/backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from langflow.services.database.utils import session_getter
from langflow.services.deps import get_db_service
from loguru import logger
from pytest import LogCaptureFixture
from sqlmodel import Session, SQLModel, create_engine, select
from sqlmodel.pool import StaticPool
from typer.testing import CliRunner
Expand Down Expand Up @@ -102,7 +101,7 @@ def _delete_transactions_and_vertex_builds(session, user: User):


@pytest.fixture
def caplog(caplog: LogCaptureFixture):
def caplog(caplog: pytest.LogCaptureFixture):
handler_id = logger.add(
caplog.handler,
format="{message}",
Expand Down Expand Up @@ -144,7 +143,7 @@ def load_flows_dir():


@pytest.fixture(name="distributed_env")
def setup_env(monkeypatch):
def _setup_env(monkeypatch):
monkeypatch.setenv("LANGFLOW_CACHE_TYPE", "redis")
monkeypatch.setenv("LANGFLOW_REDIS_HOST", "result_backend")
monkeypatch.setenv("LANGFLOW_REDIS_PORT", "6379")
Expand All @@ -158,7 +157,11 @@ def setup_env(monkeypatch):


@pytest.fixture(name="distributed_client")
def distributed_client_fixture(session: Session, monkeypatch, distributed_env):
def distributed_client_fixture(
session: Session, # noqa: ARG001
monkeypatch,
distributed_env, # noqa: ARG001
):
# Here we load the .env from ../deploy/.env
from langflow.core import celery_app

Expand Down Expand Up @@ -273,7 +276,12 @@ def json_memory_chatbot_no_llm():


@pytest.fixture(name="client")
async def client_fixture(session: Session, monkeypatch, request, load_flows_dir):
async def client_fixture(
session: Session, # noqa: ARG001
monkeypatch,
request,
load_flows_dir,
):
# Set the database url to a test database
if "noclient" in request.keywords:
yield
Expand All @@ -296,9 +304,11 @@ async def client_fixture(session: Session, monkeypatch, request, load_flows_dir)
db_service.database_url = f"sqlite:///{db_path}"
db_service.reload_engine()
# app.dependency_overrides[get_session] = get_session_override
async with LifespanManager(app, startup_timeout=None, shutdown_timeout=None) as manager:
async with AsyncClient(transport=ASGITransport(app=manager.app), base_url="http://testserver/") as client:
yield client
async with (
LifespanManager(app, startup_timeout=None, shutdown_timeout=None) as manager,
AsyncClient(transport=ASGITransport(app=manager.app), base_url="http://testserver/") as client,
):
yield client
# app.dependency_overrides.clear()
monkeypatch.undo()
# clear the temp db
Expand All @@ -308,7 +318,7 @@ async def client_fixture(session: Session, monkeypatch, request, load_flows_dir)

# create a fixture for session_getter above
@pytest.fixture(name="session_getter")
def session_getter_fixture(client):
def session_getter_fixture(client): # noqa: ARG001
@contextmanager
def blank_session_getter(db_service: "DatabaseService"):
with Session(db_service.engine) as session:
Expand All @@ -326,7 +336,7 @@ def runner():
async def test_user(client):
user_data = UserCreate(
username="testuser",
password="testpassword",
password="testpassword", # noqa: S106
)
response = await client.post("api/v1/users/", json=user_data.model_dump())
assert response.status_code == 201
Expand All @@ -337,7 +347,7 @@ async def test_user(client):


@pytest.fixture
def active_user(client):
def active_user(client): # noqa: ARG001
db_manager = get_db_service()
with db_manager.with_session() as session:
user = User(
Expand Down Expand Up @@ -375,7 +385,11 @@ async def logged_in_headers(client, active_user):


@pytest.fixture
def flow(client, json_flow: str, active_user):
def flow(
client, # noqa: ARG001
json_flow: str,
active_user,
):
from langflow.services.database.models.flow.model import FlowCreate

loaded_json = json.loads(json_flow)
Expand Down
2 changes: 1 addition & 1 deletion src/backend/tests/data/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class TestComponent(CustomComponent):
def refresh_values(self):
# This is a function that will be called every time the component is updated
# and should return a list of random strings
return [f"Random {random.randint(1, 100)}" for _ in range(5)]
return [f"Random {random.randint(1, 100)}" for _ in range(5)] # noqa: S311

def build_config(self):
return {"param": {"display_name": "Param", "options": self.refresh_values}}
Expand Down
Loading

0 comments on commit 92089ec

Please sign in to comment.