Skip to content

feat: Add user registration endpoints in API v2.#10430

Merged
ricofurtado merged 13 commits into
mainfrom
lf-model-credits
Nov 10, 2025
Merged

feat: Add user registration endpoints in API v2.#10430
ricofurtado merged 13 commits into
mainfrom
lf-model-credits

Conversation

@ricofurtado
Copy link
Copy Markdown
Contributor

@ricofurtado ricofurtado commented Oct 28, 2025

This pull request introduces a new user registration API to the backend, integrating it into the existing FastAPI v2 router structure. The main addition is a new registration module that supports registering users by email and retrieving all registrations. The router is properly registered and exposed in the API, with supporting code for handling registration data in a local JSON file.

Notes:
-I decided not to require authentication for the endpoints, as we might not have that during the desktop initialization.
-We could later extract the local(private) functions to a service as they grow in number for future implementations.

Related PRs

Summary by CodeRabbit

  • New Features
    • Introduced user registration API supporting email-based registration
    • Added endpoint to retrieve total registration count and complete list of registered users
    • Implemented automatic duplicate email detection and prevention
    • Added service information root endpoint with available endpoints
    • Registrations are persistently stored with UTC timestamps

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 28, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

A new user registration API is added to Langflow's v2 API. The implementation introduces a registration router with endpoints to register users, retrieve registration records, and access service info. User registrations are persisted to a JSON file with duplicate email prevention and UTC timestamping.

Changes

Cohort / File(s) Summary
Router Integration
src/backend/base/langflow/api/router.py, src/backend/base/langflow/api/v2/__init__.py
Imported and registered the new v2 registration router. Exposed registration_router in the v2 module's public API.
Registration API Implementation
src/backend/base/langflow/api/v2/registration.py
New module implementing user registration API with FastAPI endpoints, Pydantic data models (RegisterRequest, RegisterResponse), JSON-based persistence to data/users/registrations.json, duplicate prevention, UTC timestamping, and error handling.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as /registration Endpoint
    participant FileOps as File Operations
    participant Storage as registrations.json

    Client->>API: POST /register (email)
    activate API
    API->>API: Validate RegisterRequest
    API->>FileOps: load_registrations()
    FileOps->>Storage: Read JSON
    Storage-->>FileOps: [registrations]
    FileOps-->>API: registrations dict
    
    alt Duplicate Email
        API-->>Client: HTTP 400 (Duplicate)
    else New Email
        API->>API: Add timestamp, create entry
        API->>FileOps: _save_registration(append=true)
        FileOps->>Storage: Write updated JSON (atomic)
        Storage-->>FileOps: Success
        FileOps-->>API: Saved
        API-->>Client: HTTP 200 + RegisterResponse
    end
    deactivate API

    Client->>API: GET /registrations
    activate API
    API->>FileOps: load_registrations()
    FileOps->>Storage: Read JSON
    Storage-->>FileOps: [registrations]
    FileOps-->>API: registrations dict
    API-->>Client: HTTP 200 (count + list)
    deactivate API
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20-25 minutes

  • File I/O and atomic writes: Verify the temporary file pattern for atomic writes is correctly implemented and handles edge cases (permissions, concurrent access).
  • JSON schema consistency: Ensure registration object structure (timestamp format, field names) is consistently applied across save and load operations.
  • Duplicate detection logic: Confirm email-based duplicate checks are case-sensitive or case-insensitive as intended.
  • Error handling: Review exception handling in file operations, especially for directory creation failures and malformed JSON scenarios.

Pre-merge checks and finishing touches

❌ Failed checks (1 error, 3 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error The PR introduces a new registration module (src/backend/base/langflow/api/v2/registration.py) with significant functionality including two Pydantic data models, five helper functions for file I/O and registration management, and three FastAPI endpoints. However, the PR contains no corresponding test files. The git diff shows only 3 files changed with 129 insertions total, none of which are test files. The existing v2 API test structure shows the project follows the pattern test_*.py under src/backend/tests/unit/api/v2/, with existing tests for other v2 endpoints like test_files.py and test_mcp_servers_file.py, but no test_registration.py file was added or modified in this PR. Create a new test file src/backend/tests/unit/api/v2/test_registration.py that includes comprehensive test coverage for the new registration functionality. The tests should cover: (1) unit tests for helper functions (load_registrations(), save_registration(), append_registration(), _save_registration()) including successful operations, file I/O errors, and edge cases; (2) endpoint tests for POST /register with success and duplicate email scenarios; (3) endpoint tests for GET /registrations with valid data retrieval; (4) endpoint tests for GET / root endpoint; (5) tests for data persistence to JSON file and proper error handling; and (6) tests validating the critical data loss bug mentioned in review comments where save_registration() should use append=True instead of append=False.
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Test Quality And Coverage ⚠️ Warning The pull request adds a new user registration API module with three async endpoints and supporting functions but contains no test files. The codebase clearly establishes pytest testing patterns for v2 API routers, as evidenced by test_files.py and test_mcp_servers_file.py in src/backend/tests/unit/api/v2/. The registration module implements complex functionality requiring comprehensive test coverage: file I/O operations, atomic writes with temporary files, duplicate email detection, error handling for OSError and JSONDecodeError, and proper HTTP response codes. No tests exist to validate successful registration flow, error cases, the critical data loss bug in save_registration() (which uses append=False), or the unauthenticated access to the /registrations endpoint. The existing test patterns show use of AsyncClient, async fixtures, and proper async/await patterns with pytest-asyncio, none of which are present for the registration module. Create src/backend/tests/unit/api/v2/test_registration.py following the established pytest patterns. Include tests for: (1) POST /register endpoint with valid email returning 200 and RegisterResponse; (2) duplicate email registration returning 400 status; (3) file I/O errors returning 500 status; (4) GET /registrations endpoint retrieving all registrations successfully; (5) GET /registrations with load errors returning 500 status; (6) GET / root endpoint smoke test; (7) helper functions with mocked file operations to verify the data loss bug where save_registration(append=False) overwrites existing registrations; (8) load_registrations() returning empty list when file doesn't exist. Use AsyncClient fixtures for endpoint testing, monkeypatch for environment/path manipulation, and temporary directories to avoid side effects, following the patterns established in test_files.py.
Test File Naming And Structure ⚠️ Warning The PR introduces a new registration module at src/backend/base/langflow/api/v2/registration.py with three FastAPI endpoints for user registration and retrieval. However, the PR does not include any corresponding test files. The codebase has an established testing pattern with tests located at src/backend/tests/unit/api/v2/, and similar API v2 modules like files.py and mcp.py have corresponding test files (test_files.py, test_mcp_servers_file.py). No test file exists at the expected location src/backend/tests/unit/api/v2/test_registration.py, which means the new functionality lacks test coverage for both positive and negative scenarios, edge cases, and error conditions that would be expected based on the repository's testing standards. Create a comprehensive test file at src/backend/tests/unit/api/v2/test_registration.py following the established pytest pattern in the repository. The test file should include test cases covering: the POST /registration/register endpoint with valid and duplicate email scenarios, the GET /registration/registrations endpoint with proper response validation, error handling scenarios, the root GET /registration/ endpoint, and helper functions like load_registrations(), save_registration(), and append_registration(). Additionally, given the critical issues identified in review comments (data loss bug on line 34, security concerns on the /registrations endpoint, and hardcoded path issues), tests should verify the correct behavior once those issues are addressed.
Excessive Mock Usage Warning ❓ Inconclusive The "Excessive Mock Usage Warning" check cannot be assessed because the PR does not include any test files for the new registration API. A thorough search of the test directory structure confirms that no test_registration.py file exists in /src/backend/tests/unit/api/v2/, which only contains test_files.py and test_mcp_servers_file.py. The registration.py module implements file I/O operations, JSON persistence, email validation, and three API endpoints, yet it lacks any accompanying test coverage. Therefore, there are no mock objects to analyze for excessive usage, making the custom check unable to be evaluated. The check is inconclusive due to the absence of test files rather than excessive mock usage. This PR should include comprehensive test coverage for the registration module before merging. Create a test_registration.py file in /src/backend/tests/unit/api/v2/ with unit tests for core functions (load_registrations, _save_registration) using temporary directories instead of excessive mocking, endpoint tests using AsyncClient (as shown in existing v2 tests), and error case handling. Following the existing test patterns in test_files.py and test_mcp_servers_file.py, use real file I/O with pytest fixtures and tmpdir for file operations rather than over-mocking the file system, ensuring the tests validate actual registration persistence behavior.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat: Add user registration endpoints in API v2" accurately and directly summarizes the main change in the pull request. The changeset adds a new registration module with multiple endpoints (POST /registration/register, GET /registration/registrations, GET /registration/) and integrates it into the FastAPI v2 router. The title is specific and clear—it identifies both what is being added (user registration endpoints) and where (API v2)—making it easy for teammates scanning history to understand the primary change without needing to inspect the detailed code.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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.

@ricofurtado ricofurtado removed the request for review from lucaseduoli October 28, 2025 16:46
@github-actions github-actions Bot added the enhancement New feature or request label Oct 28, 2025
@ricofurtado ricofurtado requested review from Cristhianzl, Copilot and mpawlow and removed request for Copilot October 28, 2025 16:46
@codecov
Copy link
Copy Markdown

codecov Bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 71.11111% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 31.46%. Comparing base (403b939) to head (177eb6c).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
.../API/queries/registration/use-post-registration.ts 0.00% 14 Missing ⚠️
...s/API/queries/registration/use-get-registration.ts 0.00% 11 Missing ⚠️
src/backend/base/langflow/api/v2/registration.py 98.41% 1 Missing ⚠️

❌ Your project status has failed because the head coverage (39.35%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

❗ There is a different number of reports uploaded between BASE (403b939) and HEAD (177eb6c). Click for more details.

HEAD has 6 uploads less than BASE
Flag BASE (403b939) HEAD (177eb6c)
frontend 2 1
backend 10 5
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #10430      +/-   ##
==========================================
- Coverage   38.90%   31.46%   -7.44%     
==========================================
  Files        1477     1328     -149     
  Lines       85270    60085   -25185     
  Branches    10240     8986    -1254     
==========================================
- Hits        33175    18908   -14267     
+ Misses      51048    40271   -10777     
+ Partials     1047      906     -141     
Flag Coverage Δ
backend 51.13% <98.46%> (-5.73%) ⬇️
frontend 13.55% <0.00%> (-0.79%) ⬇️
lfx 39.35% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/backend/base/langflow/api/router.py 100.00% <100.00%> (ø)
.../frontend/src/controllers/API/helpers/constants.ts 55.55% <ø> (ø)
src/backend/base/langflow/api/v2/registration.py 98.41% <98.41%> (ø)
...s/API/queries/registration/use-get-registration.ts 0.00% <0.00%> (ø)
.../API/queries/registration/use-post-registration.ts 0.00% <0.00%> (ø)

... and 371 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 28, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/backend/base/langflow/api/v2/registration.py (1)

27-32: Consider adding explicit error handling for JSON decode errors.

While the function is simple, it could fail silently if the JSON file is corrupted. Consider adding explicit error handling to provide better diagnostics.

 def load_registrations() -> list[dict]:
     """Load existing registrations from file."""
     if REGISTRATIONS_FILE.exists():
-        with REGISTRATIONS_FILE.open("r") as f:
-            return json.load(f)
+        try:
+            with REGISTRATIONS_FILE.open("r") as f:
+                return json.load(f)
+        except json.JSONDecodeError as e:
+            logger.error(f"Failed to parse registrations file: {e}")
+            # Could either return [] or re-raise depending on desired behavior
+            return []
     return []
📜 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 5ea70dd and ecc2ed5.

📒 Files selected for processing (3)
  • src/backend/base/langflow/api/router.py (2 hunks)
  • src/backend/base/langflow/api/v2/__init__.py (1 hunks)
  • src/backend/base/langflow/api/v2/registration.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{src/backend/**/*.py,tests/**/*.py,Makefile}

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code

Files:

  • src/backend/base/langflow/api/v2/__init__.py
  • src/backend/base/langflow/api/router.py
  • src/backend/base/langflow/api/v2/registration.py
⏰ 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). (17)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Run Backend Tests / LFX Tests - Python 3.10
  • GitHub Check: Run Frontend Tests / Determine Test Suites and Shard Distribution
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Component Index
  • GitHub Check: Update Starter Projects
🔇 Additional comments (7)
src/backend/base/langflow/api/router.py (2)

27-27: LGTM!

The import follows the established pattern for v2 routers.


59-59: LGTM!

The router registration follows the established pattern for v2 routers.

src/backend/base/langflow/api/v2/__init__.py (1)

3-3: LGTM!

The import and export follow the established pattern for v2 routers.

Also applies to: 8-8

src/backend/base/langflow/api/v2/registration.py (4)

1-9: LGTM!

The imports are appropriate for the registration API functionality.


10-19: LGTM!

The router configuration and Pydantic models are well-defined. Using EmailStr provides built-in email validation.


75-99: Endpoint logic is correct but depends on fixing the critical bug in save_registration().

The endpoint implementation is well-structured with proper error handling. However, line 82 calls save_registration(), which currently has the critical bug that deletes all existing registrations. Once that bug is fixed (see previous comment), this endpoint should function correctly.


116-125: LGTM!

The root endpoint provides useful service information and is appropriately implemented.

Comment thread src/backend/base/langflow/api/v2/registration.py Outdated
Comment thread src/backend/base/langflow/api/v2/registration.py Outdated
Comment thread src/backend/base/langflow/api/v2/registration.py Outdated
Comment on lines +101 to +114
@router.get("/registrations")
async def get_registrations():
"""Get all registered users."""
try:
registrations = load_registrations()
return {
"total": len(registrations),
"registrations": registrations
}
except (OSError, json.JSONDecodeError) as e:
raise HTTPException(
status_code=500,
detail=f"Failed to load registrations: {e!r}"
) from e
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Oct 28, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Security concern: Unauthenticated access to all user emails.

The /registrations endpoint exposes all registered user emails without any authentication. While the PR objectives mention that authentication is not required for desktop initialization, exposing PII (personally identifiable information) without authentication is a significant privacy and security risk.

Consider one of the following approaches:

  1. Add authentication/authorization to this endpoint (admin-only access)
  2. Remove or disable this endpoint in production environments
  3. If truly needed for desktop scenarios, restrict access by IP address (localhost only)
  4. At minimum, add rate limiting to prevent enumeration attacks
from fastapi import Depends
from langflow.api.v1.auth import get_current_active_user

@router.get("/registrations")
async def get_registrations(current_user: dict = Depends(get_current_active_user)):
    """Get all registered users. Requires authentication."""
    # Only allow admin users
    if not current_user.get("is_admin"):
        raise HTTPException(status_code=403, detail="Admin access required")
    
    try:
        registrations = load_registrations()
        return {
            "total": len(registrations),
            "registrations": registrations
        }
    except (OSError, json.JSONDecodeError) as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to load registrations: {e!r}"
        ) from e
🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v2/registration.py around lines 101-114, the
GET /registrations endpoint currently returns all user emails unauthenticated —
change it to require authentication and admin-only access: add a
Depends(get_current_active_user) parameter, import the auth helper, verify
current_user.get("is_admin") and return 403 if not admin; alternatively, if this
endpoint is only needed for local desktop flows include an environment check and
restrict access to localhost (requests only from 127.0.0.1) or disable the route
in production, and add rate limiting to mitigate enumeration attacks.

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.

Unauthenticated access for the enpoints is part of the design to support the Desktop calls.

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.

@ricofurtado, thank you for clarifying the design intention for Desktop support. I understand that the registration flow needs to be accessible without authentication.

However, I'd like to distinguish between two scenarios:

  1. POST /registration/register - Being unauthenticated is reasonable for desktop onboarding
  2. GET /registration/registrations - Exposing all user emails without authentication is a privacy concern, even for desktop scenarios

For the bulk retrieval endpoint, consider these alternatives that preserve desktop functionality while protecting user data:

Option 1: Localhost-only access

from fastapi import Request

@router.get("/registrations")
async def get_registrations(request: Request):
    """Get all registered users. Localhost only."""
    client_host = request.client.host if request.client else None
    if client_host not in ("127.0.0.1", "localhost", "::1"):
        raise HTTPException(status_code=403, detail="Access restricted to localhost")
    
    try:
        registrations = load_registrations()
        return {"total": len(registrations), "registrations": registrations}
    except (OSError, json.JSONDecodeError) as e:
        raise HTTPException(status_code=500, detail=f"Failed to load registrations: {e!r}") from e

Option 2: Remove the endpoint entirely
If the Desktop app only needs to register users and doesn't need to retrieve the full list, consider removing GET /registrations entirely.

Option 3: Add rate limiting
At minimum, implement rate limiting to prevent enumeration attacks.

Does the Desktop application actually require the ability to retrieve all registrations, or is the registration endpoint sufficient?


✏️ Learnings added
Learnt from: ricofurtado
PR: langflow-ai/langflow#10430
File: src/backend/base/langflow/api/v2/registration.py:0-0
Timestamp: 2025-10-29T03:55:50.208Z
Learning: In the langflow project, user registration endpoints in API v2 (`src/backend/base/langflow/api/v2/registration.py`) are intentionally designed to be unauthenticated to support Desktop application initialization and onboarding flows.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 28, 2025
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Oct 29, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 15%
14.66% (3955/26976) 7.45% (1533/20560) 8.99% (532/5913)

Unit Test Results

Tests Skipped Failures Errors Time
1588 0 💤 0 ❌ 0 🔥 19.512s ⏱️

Copy link
Copy Markdown
Contributor

@mpawlow mpawlow left a comment

Choose a reason for hiding this comment

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

@ricofurtado

Code Review 1

  • See PR comments: (1 a) to (1 z)

Comment thread src/backend/base/langflow/api/v2/registration.py Outdated
Comment thread src/backend/base/langflow/api/v2/registration.py
Comment thread src/backend/base/langflow/api/v2/registration.py Outdated
Comment thread src/backend/base/langflow/api/v2/registration.py Outdated
Comment thread src/backend/base/langflow/api/v2/registration.py
Comment thread src/frontend/src/controllers/API/queries/registration/use-get-registratrions.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-get-registratrions.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-post-registration.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-post-registration.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-post-registration.ts Outdated
Copy link
Copy Markdown
Contributor Author

@ricofurtado ricofurtado left a comment

Choose a reason for hiding this comment

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

There is a new version of this code where I removed the multi-user registration. Will submit after testing.

return _save_registration(email=email, append=False)


def append_registration(email: str) -> bool:
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.

I changed the behaviour for a single user

def _save_registration(email: str, append: bool) -> bool: # noqa: FBT001
"""Save a new registration to file with atomic write."""
try:
registrations = load_registrations()
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.

Changed the behaviour for a single user here as well

registration = {
"email": email,
"registered_at": datetime.now(tz=timezone.utc).isoformat(),
"langflow_connected": False,
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.

The idea was to use this field to trigger the reconciliation process when backend was not available yet, but we solved the problem using another approach. I'll remove it.

if append:
registrations.append(registration)
else:
registrations = [registration]
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.

Part of the single-user changes.

registrations = [registration]

# Save to file
temp_file = REGISTRATIONS_FILE.with_suffix(".tmp")
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.

Part of the single-user changes. That was introduced for concurrent file access(not a valid scenario anymore) on single-user

Comment thread src/frontend/src/controllers/API/queries/registration/use-get-registratrions.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-get-registratrions.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-post-registration.ts Outdated
Comment thread src/frontend/src/controllers/API/queries/registration/use-post-registration.ts Outdated
"""Load existing registrations from file."""
if REGISTRATIONS_FILE.exists():
with REGISTRATIONS_FILE.open("r") as f:
return json.load(f)
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.

Avoiding bloating the code with too many different error messages, it is easier to spot the exception type with a generic message.

@ricofurtado ricofurtado removed the request for review from Cristhianzl October 30, 2025 16:46
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 30, 2025
Comment on lines +50 to +57
if REGISTRATION_FILE.exists():
try:
with REGISTRATION_FILE.open("r") as f:
return json.load(f)
except json.JSONDecodeError:
logger.error(f"Corrupted registration file: {REGISTRATION_FILE}")
return None
return None
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.

⚡️Codeflash found 21% (0.21x) speedup for load_registration in src/backend/base/langflow/api/v2/registration.py

⏱️ Runtime : 1.20 milliseconds 994 microseconds (best of 62 runs)

📝 Explanation and details

The optimized code achieves a 20% speedup through two key file I/O optimizations:

1. More efficient file existence check: Replaced REGISTRATION_FILE.exists() with not REGISTRATION_FILE.is_file(). The is_file() method is more specific and slightly faster since it checks for regular files only, avoiding unnecessary directory checks.

2. Faster file reading strategy: Changed from text mode ("r") with json.load(f) to binary mode ("rb") with f.read() followed by json.loads(content). This eliminates Python's incremental text decoding during file reading, instead performing all decoding at once when parsing JSON. For small files like registration data, reading the entire content in one operation is more efficient than the streaming approach.

3. Enhanced error handling: Added UnicodeDecodeError to the exception handling since binary mode reading can raise this error for malformed UTF-8 files, maintaining the same error behavior as the original.

The line profiler shows the file opening operation dropped from 831ms to 476ms (43% faster), and overall function time improved from 3.18ms to 2.54ms. These optimizations are particularly effective for small-to-medium JSON files typical in registration scenarios, as demonstrated by the consistent performance gains across the test cases involving various JSON structures and file sizes.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 26 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 87.5%
🌀 Generated Regression Tests and Runtime
import json
import os
import shutil
# function to test
# (copied from langflow/api/v2/registration.py, as per prompt)
import sys
from pathlib import Path
from types import SimpleNamespace

# imports
import pytest
from langflow.api.v2.registration import load_registration


# Simulate the logger used in the function
class DummyLogger:
    def __init__(self):
        self.last_error = None
    def error(self, msg):
        self.last_error = msg

# Patch logger in the function's module namespace
dummy_logger = DummyLogger()

# The function under test
REGISTRATION_FILE = Path("data/user/registration.json")
from langflow.api.v2.registration import load_registration

# ========== UNIT TESTS ==========

@pytest.fixture(autouse=True)
def setup_and_teardown_registration_file(tmp_path, monkeypatch):
    """
    Fixture to isolate REGISTRATION_FILE to a temp directory for each test.
    """
    # Patch REGISTRATION_FILE to point to a temp directory
    reg_dir = tmp_path / "data/user"
    reg_dir.mkdir(parents=True, exist_ok=True)
    reg_file = reg_dir / "registration.json"
    monkeypatch.setattr(__name__, "REGISTRATION_FILE", reg_file)
    yield reg_file
    # Cleanup is handled by tmp_path fixture

# -------------------------------
# 1. BASIC TEST CASES
# -------------------------------


















#------------------------------------------------
import json
# function to test
# File to store registrations
import logging
import os
from pathlib import Path

# imports
import pytest
from langflow.api.v2.registration import load_registration


# Dummy logger to replace langflow.logging.logger for testing
class DummyLogger:
    def __init__(self):
        self.messages = []
    def error(self, msg):
        self.messages.append(msg)

logger = DummyLogger()

REGISTRATION_FILE = Path("test_registration.json")  # Use a test file to avoid interfering with real data
from langflow.api.v2.registration import load_registration


# Helper functions for test setup/teardown
def write_file(path: Path, content: str):
    with path.open("w") as f:
        f.write(content)

def remove_file(path: Path):
    try:
        path.unlink()
    except FileNotFoundError:
        pass

# ------------------- UNIT TESTS -------------------

# 1. Basic Test Cases




def test_load_registration_minimal_json():
    """Test loading a minimal valid JSON (empty dict)."""
    write_file(REGISTRATION_FILE, "{}")
    codeflash_output = load_registration(); result = codeflash_output



def test_load_registration_non_dict_json():
    """Test loading a valid JSON that is not a dict (e.g., list)."""
    write_file(REGISTRATION_FILE, '["not", "a", "dict"]')
    codeflash_output = load_registration(); result = codeflash_output

def test_load_registration_null_json():
    """Test loading a JSON file containing 'null'."""
    write_file(REGISTRATION_FILE, 'null')
    codeflash_output = load_registration(); result = codeflash_output

def test_load_registration_large_numbers():
    """Test loading JSON with large integer and float values."""
    data = {"bigint": 2**62, "bigfloat": 1.7e308}
    write_file(REGISTRATION_FILE, json.dumps(data))
    codeflash_output = load_registration(); result = codeflash_output

def test_load_registration_special_characters():
    """Test loading JSON with special unicode characters."""
    data = {"name": "José 🚀", "email": "josé@example.com"}
    write_file(REGISTRATION_FILE, json.dumps(data, ensure_ascii=False))
    codeflash_output = load_registration(); result = codeflash_output

def test_load_registration_file_with_whitespace():
    """Test loading a file with leading/trailing whitespace around JSON."""
    data = {"user": "dave"}
    write_file(REGISTRATION_FILE, "   \n  " + json.dumps(data) + "  \n ")
    codeflash_output = load_registration(); result = codeflash_output

def test_load_registration_file_with_comments():
    """Test loading a file with comments (should fail, as JSON does not support comments)."""
    write_file(REGISTRATION_FILE, '{ "user": "eve" } // comment')
    codeflash_output = load_registration(); result = codeflash_output



def test_load_registration_large_nested_dict():
    """Test loading a registration dict with large nested structure."""
    nested = {"inner": {str(i): i for i in range(500)}}
    data = {"user": "large", "details": nested}
    write_file(REGISTRATION_FILE, json.dumps(data))
    codeflash_output = load_registration(); result = codeflash_output


def test_load_registration_large_file_size():
    """Test loading a very large file (close to 1MB)."""
    # Each entry is about 10 bytes, so 100000 entries ~ 1MB
    large_dict = {str(i): "x" * 5 for i in range(1000)}
    write_file(REGISTRATION_FILE, json.dumps(large_dict))
    codeflash_output = load_registration(); result = codeflash_output

def test_load_registration_multiple_calls_consistency():
    """Test that multiple consecutive calls return the same result."""
    data = {"user": "repeat", "email": "repeat@example.com"}
    write_file(REGISTRATION_FILE, json.dumps(data))
    for _ in range(10):
        codeflash_output = load_registration()
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To test or edit this optimization locally git merge codeflash/optimize-pr10430-2025-10-30T20.12.37

Suggested change
if REGISTRATION_FILE.exists():
try:
with REGISTRATION_FILE.open("r") as f:
return json.load(f)
except json.JSONDecodeError:
logger.error(f"Corrupted registration file: {REGISTRATION_FILE}")
return None
return None
if not REGISTRATION_FILE.is_file():
return None
try:
with REGISTRATION_FILE.open("rb") as f: # use binary mode for faster file IO
content = f.read()
return json.loads(content)
except (json.JSONDecodeError, UnicodeDecodeError):
logger.error(f"Corrupted registration file: {REGISTRATION_FILE}")
return None

@ricofurtado ricofurtado enabled auto-merge November 7, 2025 14:37
@ricofurtado ricofurtado closed this Nov 7, 2025
auto-merge was automatically disabled November 7, 2025 14:38

Pull request was closed

@ricofurtado ricofurtado reopened this Nov 7, 2025
@ricofurtado ricofurtado enabled auto-merge November 7, 2025 14:39
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 7, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Nov 10, 2025
@ricofurtado ricofurtado added this pull request to the merge queue Nov 10, 2025
Merged via the queue into main with commit 91d73e7 Nov 10, 2025
80 of 82 checks passed
@ricofurtado ricofurtado deleted the lf-model-credits branch November 10, 2025 21:31
korenLazar pushed a commit to kiran-kate/langflow that referenced this pull request Nov 12, 2025
* feat: Add user registration endpoints in API v2. Desktop Model-credits initiative.

* [autofix.ci] apply automated fixes

* fix: adjust registration API endpoints to REST compliance.

* [autofix.ci] apply automated fixes

* feat: Implement registration API queries for fetching and posting registrations

* feat: Enhance registration API with secure file handling and add hooks for fetching registration

* refactor: Lazy file creation.

* Commit: Delete unused file use-get-registratrions.ts

* feat: Add unit and integration tests for registration API

* refactor: Simplify registration response model by removing success and message fields

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* refactor: Remove success and message assertions from registration tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
korenLazar pushed a commit to kiran-kate/langflow that referenced this pull request Nov 13, 2025
* feat: Add user registration endpoints in API v2. Desktop Model-credits initiative.

* [autofix.ci] apply automated fixes

* fix: adjust registration API endpoints to REST compliance.

* [autofix.ci] apply automated fixes

* feat: Implement registration API queries for fetching and posting registrations

* feat: Enhance registration API with secure file handling and add hooks for fetching registration

* refactor: Lazy file creation.

* Commit: Delete unused file use-get-registratrions.ts

* feat: Add unit and integration tests for registration API

* refactor: Simplify registration response model by removing success and message fields

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* refactor: Remove success and message assertions from registration tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
korenLazar pushed a commit to kiran-kate/langflow that referenced this pull request Nov 13, 2025
* feat: Add user registration endpoints in API v2. Desktop Model-credits initiative.

* [autofix.ci] apply automated fixes

* fix: adjust registration API endpoints to REST compliance.

* [autofix.ci] apply automated fixes

* feat: Implement registration API queries for fetching and posting registrations

* feat: Enhance registration API with secure file handling and add hooks for fetching registration

* refactor: Lazy file creation.

* Commit: Delete unused file use-get-registratrions.ts

* feat: Add unit and integration tests for registration API

* refactor: Simplify registration response model by removing success and message fields

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* refactor: Remove success and message assertions from registration tests

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants