Al Ghazali RAG Retrieval API

Endpoints

1. Login Endpoint

POST/login

This endpoint is used to authenticate the user and issue an access token and a refresh token.

cURL Request:

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/login \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d 'username=user123&password=password123'

Flutter Implementation:

Future login(String username, String password) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/login');
  
  try {
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: {
        'username': username,
        'password': password,
      },
    );

    if (response.statusCode == 200) {
      return LoginResponse.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to login: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

// Model class
class LoginResponse {
  final String accessToken;
  final String refreshToken;
  final String tokenType;
  final int expiresIn;

  LoginResponse({
    required this.accessToken,
    required this.refreshToken,
    required this.tokenType,
    required this.expiresIn,
  });

  factory LoginResponse.fromJson(Map json) {
    return LoginResponse(
      accessToken: json['access_token'],
      refreshToken: json['refresh_token'],
      tokenType: json['token_type'],
      expiresIn: json['expires_in'],
    );
  }
}

Response:

{
    "access_token": "your-access-token",
    "refresh_token": "your-refresh-token",
    "token_type": "bearer",
    "expires_in": 1800
}

2. Refresh Token Endpoint

POST/refresh

This endpoint is used to refresh the access token using a valid refresh token.

cURL Request:

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/refresh \
     -H "Content-Type: application/json" \
     -d '{"refresh_token": "your-refresh-token"}'

Flutter Implementation:

Future refreshToken(String refreshToken) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/refresh');
  
  try {
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'refresh_token': refreshToken,
      }),
    );

    if (response.statusCode == 200) {
      return LoginResponse.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to refresh token: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

Response:

{
    "access_token": "new-access-token",
    "refresh_token": "your-refresh-token",
    "token_type": "bearer",
    "expires_in": 1800
}

4. Save Data Endpoint

POST/save

This endpoint is used to save user feedback and search results to the Hugging Face dataset. It requires a valid access token.

cURL Request:

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/save \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer your-access-token" \
     -d '{
           "items": [
               {
                   "user_type": "user",
                   "username": "user123",
                   "query": "test query",
                   "retrieved_text": "Result 1 text",
                   "model_type": "all-mpnet-base-v2",
                   "reaction": "positive"
               }
           ]
         }'

Flutter Implementation:

class SaveInput {
  final String userType;
  final String username;
  final String query;
  final String retrievedText;
  final String modelType;
  final String reaction;

  SaveInput({
    required this.userType,
    required this.username,
    required this.query,
    required this.retrievedText,
    required this.modelType,
    required this.reaction,
  });

  Map toJson() {
    return {
      'user_type': userType,
      'username': username,
      'query': query,
      'retrieved_text': retrievedText,
      'model_type': modelType,
      'reaction': reaction,
    };
  }
}

Future saveData(List items, String accessToken) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/save');
  
  try {
    final response = await http.post(
      url,
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $accessToken',
      },
      body: jsonEncode({
        'items': items.map((item) => item.toJson()).toList(),
      }),
    );

    if (response.statusCode != 200) {
      throw Exception('Failed to save data: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

Response:

{
    "message": "Data saved successfully"
}

5. Log-out Endpoint

POST/logout

This endpoint is used to revoke the access token after the event of logout click.

cURL Reqeust:

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/logout \
                      -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Flutter Implementation:

Future logout(String accessToken) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/logout');

  try {
    final response = await http.post(
      url,
      headers: {
        'Authorization
        ': 'Bearer $accessToken',
      },
    );

    if (response.statusCode != 200) {
      throw Exception('Failed to logout: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

Response:

{
    "message": "Successfully logged out"
}

Workflow Example

Here's a complete workflow demonstrating how to use the API:

cURL Implementation

Step 1: Login

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/login \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d 'username=user123&password=password123'

Step 2: Search

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/search \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer your-access-token" \
     -d '{"query": "test query"}'

Step 3: Save Data

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/save \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer your-access-token" \
     -d '{
           "items": [
               {
                   "user_type": "user",
                   "username": "user123",
                   "query": "test query",
                   "retrieved_text": "Result 1 text",
                   "model_type": "all-mpnet-base-v2",
                   "reaction": "positive"
               }
           ]
         }'

Step 4: Refresh Token

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/refresh \
     -H "Content-Type: application/json" \
     -d '{"refresh_token": "your-refresh-token"}'

Flutter Implementation

Complete Flutter Example

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Al Ghazali RAG API Example',
      home: ApiWorkflowExample(),
    );
  }
}

class ApiWorkflowExample extends StatefulWidget {
  @override
  _ApiWorkflowExampleState createState() => _ApiWorkflowExampleState();
}

class _ApiWorkflowExampleState extends State {
  String _accessToken = '';
  String _refreshToken = '';
  List _searchResults = [];

  Future _login() async {
    final username = 'user123';
    final password = 'password123';

    try {
      final loginResponse = await login(username, password);
      setState(() {
        _accessToken = loginResponse.accessToken;
        _refreshToken = loginResponse.refreshToken;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Login successful!')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Login failed: $e')),
      );
    }
  }

  Future _search() async {
    final query = 'test query';

    try {
      final results = await search(query, _accessToken);
      setState(() {
        _searchResults = results;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Search successful!')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Search failed: $e')),
      );
    }
  }

  Future _saveData() async {
    final items = [
      SaveInput(
        userType: 'user',
        username: 'user123',
        query: 'test query',
        retrievedText: _searchResults[0].text,
        modelType: _searchResults[0].modelType,
        reaction: 'positive',
      ),
    ];

    try {
      await saveData(items, _accessToken);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Data saved successfully!')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Failed to save data: $e')),
      );
    }
  }

  Future _refreshToken() async {
    try {
      final loginResponse = await refreshToken(_refreshToken);
      setState(() {
        _accessToken = loginResponse.accessToken;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Token refreshed successfully!')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Token refresh failed: $e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Al Ghazali RAG API Workflow'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            ElevatedButton(
              onPressed: _login,
              child: Text('Login'),
            ),
            ElevatedButton(
              onPressed: _search,
              child: Text('Search'),
            ),
            ElevatedButton(
              onPressed: _saveData,
              child: Text('Save Data'),
            ),
            ElevatedButton(
              onPressed: _refreshToken,
              child: Text('Refresh Token'),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: _searchResults.length,
                itemBuilder: (context, index) {
                  final result = _searchResults[index];
                  return ListTile(
                    title: Text(result.text),
                    subtitle: Text('Similarity: ${result.similarity}, Model: ${result.modelType}'),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Future login(String username, String password) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/login');

  try {
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/x-www-form-urlencoded'},
      body: {
        'username': username,
        'password': password,
      },
    );

    if (response.statusCode == 200) {
      return LoginResponse.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to login: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

Future refreshToken(String refreshToken) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/refresh');

  try {
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'refresh_token': refreshToken,
      }),
    );

    if (response.statusCode == 200) {
      return LoginResponse.fromJson(jsonDecode(response.body));
    } else {
      throw Exception('Failed to refresh token: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

Future> search(String query, String accessToken) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/search');

  try {
    final response = await http.post(
      url,
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $accessToken',
      },
      body: jsonEncode({
        'query': query,
      }),
    );

    if (response.statusCode == 200) {
      List jsonList = jsonDecode(response.body);
      return jsonList.map((json) => SearchResult.fromJson(json)).toList();
    } else {
      throw Exception('Search failed: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

Future saveData(List items, String accessToken) async {
  final url = Uri.parse('https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/save');

  try {
    final response = await http.post(
      url,
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $accessToken',
      },
      body: jsonEncode({
        'items': items.map((item) => item.toJson()).toList(),
      }),
    );

    if (response.statusCode != 200) {
      throw Exception('Failed to save data: ${response.body}');
    }
  } catch (e) {
    throw Exception('Network error: $e');
  }
}

class LoginResponse {
  final String accessToken;
  final String refreshToken;
  final String tokenType;
  final int expiresIn;

  LoginResponse({
    required this.accessToken,
    required this.refreshToken,
    required this.tokenType,
    required this.expiresIn,
  });

  factory LoginResponse.fromJson(Map json) {
    return LoginResponse(
      accessToken: json['access_token'],
      refreshToken: json['refresh_token'],
      tokenType: json['token_type'],
      expiresIn: json['expires_in'],
    );
  }
}

class SearchResult {
  final String text;
  final double similarity;
  final String modelType;

  SearchResult({
    required this.text,
    required this.similarity,
    required this.modelType,
  });

  factory SearchResult.fromJson(Map json) {
    return SearchResult(
      text: json['text'],
      similarity: json['similarity'].toDouble(),
      modelType: json['model_type'],
    );
  }
}

class SaveInput {
  final String userType;
  final String username;
  final String query;
  final String retrievedText;
  final String modelType;
  final String reaction;

  SaveInput({
    required this.userType,
    required this.username,
    required this.query,
    required this.retrievedText,
    required this.modelType,
    required this.reaction,
  });

  Map toJson() {
    return {
      'user_type': userType,
      'username': username,
      'query': query,
      'retrieved_text': retrievedText,
      'model_type': modelType,
      'reaction': reaction,
    };
  }
}