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": "user1332",
                                    "query": "What is the seventh test of lovers of God?",
                                    "retrieved_text": "The seventh test is that lovers of God will love those who obey Him and hate the infidels and the disobedient...",
                                    "model_type": "WhereIsAI/UAE-Large-V1",
                                    "reaction": "positive",
                                    "confidence_score": 0.95
                                },
                                {
                                    "user_type": "user",
                                    "username": "user1332",
                                    "query": "What is the seventh test of lovers of God?",
                                    "retrieved_text": "The seventh test is that lovers of God will love those who obey Him and hate the infidels and the disobedient...",
                                    "model_type": "BAAI/bge-large-en-v1.5",
                                    "reaction": "positive",
                                    "confidence_score": 0.92
                                }
                            ]
                          }'

Flutter Implementation:

class SaveInput {
                      final String userType;
                      final String username;
                      final String query;
                      final String retrievedText;
                      final String modelType;
                      final String reaction;
                      final double? confidenceScore;
                    
                      SaveInput({
                        required this.userType,
                        required this.username,
                        required this.query,
                        required this.retrievedText,
                        required this.modelType,
                        required this.reaction,
                        this.confidenceScore,
                      });
                    
                      Map toJson() {
                        return {
                          'user_type': userType,
                          'username': username,
                          'query': query,
                          'retrieved_text': retrievedText,
                          'model_type': modelType,
                          'reaction': reaction,
                          'confidence_score': confidenceScore,
                        };
                      }
                    }
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. Logout Endpoint

POST/logout

This endpoint is used to revoke the current access token.

cURL Request:

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"}'

Step 5: Logout

curl -X POST https://humblebeeai-al-ghazali-rag-retrieval-api.hf.space/logout \
                   -H "Authorization: Bearer your-access-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')),
      );
    }
  }

  Future _logout() async {
    try {
      await logout(_accessToken);
      setState(() {
        _accessToken = '';
        _refreshToken = '';
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Logged out successfully!')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Logout 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'),
            ),
            ElevatedButton(
              onPressed: _logout,
              child: Text('Logout'),
            ),
            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,
    };
  }
}