Files
ragflow/web/src/services/data-source-service.ts

71 lines
2.3 KiB
TypeScript
Raw Normal View History

import api from '@/utils/api';
import registerServer from '@/utils/register-server';
import request from '@/utils/request';
const { dataSourceSet, dataSourceList } = api;
const methods = {
dataSourceSet: {
url: dataSourceSet,
method: 'post',
},
dataSourceList: {
url: dataSourceList,
method: 'get',
},
} as const;
const dataSourceService = registerServer<keyof typeof methods>(
methods,
request,
);
export const deleteDataSource = (id: string) =>
request.delete(api.dataSourceDel(id));
export const dataSourceResume = (id: string, data: { resume: boolean }) => {
return request.post(api.dataSourceResume(id), { data });
};
export const dataSourceRebuild = (id: string, data: { kb_id: string }) => {
return request.post(api.dataSourceRebuild(id), { data });
};
export const dataSourceUpdate = (id: string, data: { kb_id: string }) => {
return request.patch(api.dataSourceUpdate(id), { data });
};
export const getDataSourceLogs = (id: string, params?: any) =>
request.get(api.dataSourceLogs(id), { params });
export const featchDataSourceDetail = (id: string) =>
request.get(api.dataSourceDetail(id));
Feature/generic api connector (#13545) # feat: Add Generic REST API Connector ## What problem does this PR solve? RAGFlow supports many specific data source connectors (MySQL, Slack, Google Drive, etc.), but there was no way to connect an arbitrary REST API as a data source. Users with custom or third-party APIs had to write a new connector class for each one. This PR adds a **generic, configuration-driven REST API connector** that lets users connect any REST API as a data source entirely through the UI — no code changes needed per API. --- ## Features ### Core Connector (`common/data_source/rest_api_connector.py`) - Implements `LoadConnector` and `PollConnector` interfaces for full and incremental sync - **Configurable authentication:** None, API Key (custom header), Bearer Token, Basic Auth - **Pluggable pagination:** Page-based, Offset-based, Cursor-based, or None - Smart page-size inference from user's query parameters to avoid duplicate/conflicting params - Configurable request delay between pages to prevent API rate limiting - Auto-detection of the items array in JSON responses (`items`, `results`, `data`, `records`, or first list found) - **Advanced field mapping** with dot-notation (`country.name`), array wildcards (`newsType[*].name`), type hints, and default values - Optional content template rendering (`"Title: {title}\nBody: {body}"`) - HTML stripping for content fields - Stable document IDs via `hash128` from a configurable ID field or auto-generated from item content - Pydantic configuration schema with automatic coercion of UI string inputs to dicts/lists ### Backend Registration (`rag/svr/sync_data_source.py`, `common/constants.py`, `common/data_source/config.py`) - `REST_API` sync class wired into RAGFlow's `func_factory` - Full sync (`load_from_state`) and incremental polling (`poll_source`) support - Credentials and config passed from task to connector following existing patterns (MySQL, SeaFile, etc.) ### Test Connection Endpoint (`api/apps/connector_app.py`) - `POST /v1/connector/<id>/test` validates config schema, authentication, and API connectivity without triggering a sync - Clear error messages for auth failures vs. config issues ### Frontend UI (`web/src/pages/user-setting/data-source/constant/`) - **Postman-style configuration:** Base URL, Query Parameters (key=value per line), Auth, Content Fields, Metadata Fields, Pagination Type - Auth-type-aware form: fields for API key header/value, Bearer token, or Basic username/password appear only when relevant - **Advanced Settings** toggle for: Custom Headers, Max Pages, Request Delay, Poll Timestamp Field, Request Body (POST) - Connector icon (SVG) and i18n strings (English) - **"Test Connection"** button to validate before syncing --- ## Controls & Safety - Configurable max pages safety cap (default: 1000, adjustable in UI) - Configurable request delay between pages (default: 0.5s, adjustable in UI) - Auth errors (401/403) fail immediately without retries; transient errors retry with exponential backoff - Diagnostic logging: auth setup confirmation, request details on failure, content field extraction status --- ## Type of change - [x] New Feature (non-breaking change which adds functionality) ##Visual Screenshots of Features <img width="482" height="510" alt="Screenshot 2026-03-11 at 5 19 52 PM" src="https://github.com/user-attachments/assets/dcb7ab4a-1622-44f3-bb02-d6f0527314c4" /> (Connector can be configured within the external data sources tab) Configuration Parameters: <img width="661" height="682" alt="Screenshot 2026-03-11 at 5 20 46 PM" src="https://github.com/user-attachments/assets/5e154e71-4ab5-4872-bfb2-04f02b73c18a" /> <img width="661" height="682" alt="Screenshot 2026-03-11 at 5 20 54 PM" src="https://github.com/user-attachments/assets/00cb14b7-0bcf-4b94-9d71-34e93369ecb2" /> Connection can be tested before attaching to dataset: <img width="981" height="681" alt="Screenshot 2026-03-11 at 5 21 40 PM" src="https://github.com/user-attachments/assets/aaa6eeeb-89a7-4349-bc34-2423bf8be9ee" /> Ingestion tested with API connector (works perfectly fine): <img width="1062" height="705" alt="Screenshot 2026-03-11 at 5 22 30 PM" src="https://github.com/user-attachments/assets/afcd0d58-cadd-4152-badc-d2f14d96fbec" /> Search & Retrieval works as well with metadata flow: <img width="1062" height="705" alt="Screenshot 2026-03-11 at 5 23 05 PM" src="https://github.com/user-attachments/assets/d41ee935-dcf7-4456-b317-22a76ca032c0" /> --------- Co-authored-by: Ahmad Intisar <ahmadintisar@Ahmads-MacBook-M4-Pro.local> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-13 17:35:01 +05:00
export const testDataSource = (id: string) =>
request.post(api.dataSourceTest(id));
export const startGoogleDriveWebAuth = (payload: {
credentials: string;
redirect_uri?: string;
}) => request.post(api.googleWebAuthStart('google-drive'), { data: payload });
export const pollGoogleDriveWebAuthResult = (payload: { flow_id: string }) =>
request.post(api.googleWebAuthResult('google-drive'), { data: payload });
// Gmail web auth follows the same pattern as Google Drive, but uses
// Gmail-specific endpoints and is consumed by the GmailTokenField UI.
export const startGmailWebAuth = (payload: {
credentials: string;
redirect_uri?: string;
}) => request.post(api.googleWebAuthStart('gmail'), { data: payload });
export const pollGmailWebAuthResult = (payload: { flow_id: string }) =>
request.post(api.googleWebAuthResult('gmail'), { data: payload });
export const startBoxWebAuth = (payload: {
client_id: string;
client_secret: string;
redirect_uri?: string;
}) => request.post(api.boxWebAuthStart(), { data: payload });
export const pollBoxWebAuthResult = (payload: { flow_id: string }) =>
request.post(api.boxWebAuthResult(), { data: payload });
export default dataSourceService;