Skip to content

Conversation

@hetavi-bluexkye
Copy link

Summary

This PR adds user API key management endpoints to the RAGFlow admin interface, allowing administrators to generate and retrieve API keys for users. It also includes SDK API endpoints for model management, enabling users to add, remove, list, and configure default models. Additionally, it includes comprehensive test infrastructure improvements with proper cleanup mechanisms for API tokens and related cache data.

Changes

Features

Admin API Endpoints

  • User API Key Generation Endpoint: Added POST /admin/users/<user_name>/api_key endpoint to generate new API keys for users
  • User API Key Retrieval Endpoint: Added GET /admin/users/<username>/api_key endpoint to retrieve all API keys for a user
  • Both endpoints require admin authentication and authorization

SDK API Endpoints (Model Management)

  • Add Model Endpoint: Added POST /api/v1/models endpoint to add models for a user by factory and API key
  • Remove Model Endpoint: Added DELETE /api/v1/models endpoint to remove all models for a factory
  • List User Models Endpoint: Added GET /api/v1/models endpoint to list all configured models for a user
  • Set Default Models Endpoint: Added POST /api/v1/models/default endpoint to set default models (chat, embedding, ASR, image-to-text, rerank, TTS)
  • Get Default Models Endpoint: Added GET /api/v1/models/default endpoint to retrieve default model configurations
  • All SDK endpoints require API token authentication

API Endpoints

Admin API Endpoints

Generate User API Key

POST /api/v1/admin/users/<user_name>/api_key

Response:

{
  "code": 0,
  "data": {
    "token": "ragflow-...",
    "beta": "...",
    "tenant_id": "...",
    "create_date": "...",
    "update_date": null
  },
  "message": "API key generated successfully"
}

Get User API Keys

GET /api/v1/admin/users/<username>/api_key

Response:

{
  "code": 0,
  "data": [
    {
      "token": "ragflow-...",
      "beta": "...",
      "tenant_id": "...",
      "dialog_id": "...",
      "source": "...",
      "create_date": "...",
      "update_date": "..."
    }
  ],
  "message": "Get user API keys"
}

SDK API Endpoints

Add Model

POST /api/v1/models

Request Body:

{
  "llm_factory": "OpenAI",
  "api_key": "sk-...",
  "base_url": "https://api.openai.com/v1"  // optional
}

Response:

{
  "code": 0,
  "data": true,
  "message": "Success"
}

Notes:

  • Validates API key by testing access to at least one model of each type (chat, embedding, rerank)
  • Supports special factory authentication methods (VolcEngine, Tencent, Bedrock, BaiduYiyan, Fish Audio, Google Cloud, Azure-OpenAI, OpenRouter)
  • Self-deployed models (LocalAI, Ollama, Xinference, etc.) skip API key validation

Remove Model

DELETE /api/v1/models

Request Body:

{
  "llm_factory": "OpenAI"
}

Response:

{
  "code": 0,
  "data": true,
  "message": "Success"
}

List User Models

GET /api/v1/models?include_details=false

Query Parameters:

  • include_details (bool, optional): Whether to include detailed information (api_base, max_tokens, status). Default: false

Response:

{
  "code": 0,
  "data": {
    "OpenAI": {
      "tags": {...},
      "llm": [
        {
          "type": "chat",
          "name": "gpt-4",
          "used_token": 0,
          "api_base": "...",  // if include_details=true
          "max_tokens": 8192,  // if include_details=true
          "status": "1"  // if include_details=true
        }
      ]
    }
  },
  "message": "Success"
}

Set Default Models

POST /api/v1/models/default

Request Body:

{
  "llm_id": "gpt-4",
  "embd_id": "text-embedding-ada-002",
  "asr_id": "whisper-1",
  "img2txt_id": "gpt-4-vision-preview",
  "rerank_id": "bge-reranker-base",
  "tts_id": "tts-1"
}

Response:

{
  "code": 0,
  "data": true,
  "message": "Success"
}

Notes:

  • All fields are optional, but at least one must be provided
  • Validates that all provided model IDs exist in the tenant's configured models
  • Builtin models are always allowed and do not require prior configuration

Get Default Models

GET /api/v1/models/default

Response:

{
  "code": 0,
  "data": {
    "llm_id": "gpt-4",
    "embd_id": "text-embedding-ada-002",
    "asr_id": "whisper-1",
    "img2txt_id": "gpt-4-vision-preview",
    "rerank_id": "bge-reranker-base",
    "tts_id": "tts-1"
  },
  "message": "Success"
}

@hetavi-bluexkye hetavi-bluexkye changed the title Feature/ond211 2336 add user api key endpoints to rag flow admin interface Introduce User API Key Admin Endpoints and Model Configuration SDK API Dec 10, 2025
Copy link

@as-ondewo as-ondewo left a comment

Choose a reason for hiding this comment

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

General comments:

  • Some files have formatting issues like trailing spaces or not newline at the end of the file. This should be fixed by the pre-commit hooks, so please use them.
  • Expand Python SDK (sdk/python) to cover new endpoints.
  • Add documentation for new HTTP and Python SDK endpoints (docs/references).
  • Add support for new admin endpoints to admin CLI (admin/client/admin_client.py).
  • For completeness we should also add an admin endpoint for deleting API keys. I've updated the Jira ticket to also include this.
  • Consistently use dict and list for type hints instead of Dict and List
  • What's your setup for running the tests? Most of them fail for me.

Copy link

@as-ondewo as-ondewo left a comment

Choose a reason for hiding this comment

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

Here are some more needed changes apart from the unaddressed comments of my first review. Most of them are for the user tests which I didn't look at in depth in my first review.

Choose a reason for hiding this comment

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

General comments that apply to all user tests:

  • use RetCode enum constants instead of integer return codes
  • always check for a concrete return code, not just != 0
  • always check for concrete messages, not just some phrases being contained in the message
  • never use conditional assert statements inside of if statements

Choose a reason for hiding this comment

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

The tests are very incomplete and in some cases test things that shouldn't actually work.

  • setting a built-in default model:
    • for each type of model that has built-in models test
      • setting a model that exists and is configured for the current RAGFlow instance (should work)
      • setting a model that exists but is not configured for the current RAGFlow instance (shouldn't work)
      • setting a model that does not exist (should not work)
    • for setting multiple models simultaneously test
      • setting only valid models
      • setting a mix of valid and invalid models
      • setting only invalid models
    • the tests that you currently have pass but shouldn't because they set models that aren't configured for current RAGFlow instance
  • setting normal (not built-in) models:
    • same tests as for the built-in models
  • setting a model to null or "" should remove the default model, not leave it unchanged
    • add tests for clearing one/multiple/all models

models_after: Dict[str, Any] = res["data"]
assert "Builtin" not in models_after, "Builtin should be removed from models list"

@pytest.mark.p1

Choose a reason for hiding this comment

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

This test is redundant. Other tests already check the return code

# Removing non-existent factory should still succeed (no-op)
assert res["code"] == 0, res

@pytest.mark.p2

Choose a reason for hiding this comment

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

trying to delete a non-existent factory should fail

assert len(models1[factory_name]["llm"]) == len(models2[factory_name]["llm"])

@pytest.mark.p2
def test_list_user_models_tags(self, HttpApiAuth):

Choose a reason for hiding this comment

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

check that the tags are actually correct

assert "tags" in factory_data

@pytest.mark.p2
def test_list_user_models_builtin_factory(self, HttpApiAuth):

Choose a reason for hiding this comment

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

this test is redundant

Choose a reason for hiding this comment

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

  • it shouldn't be possible to add the "Builtin" factory (should always be available)
  • most of the tests here are completely pointless
  • it is not feasible to test all possible model providers but we should at least test all possible success and failure cases for one local model and one API service
  • test parameter validation for all factories
  • test adding an individual model (not just all models from a factory)

@as-ondewo
Copy link

split up into #5 and #6

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.

3 participants