Team Ai
Apppublic

afulara/PythonicRAG-FastAPI-React

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
0likes
App.tsx178 linesDownload Raw Back to src
1import React, { useState } from 'react';2import './App.css';3 4interface DocumentResponse {5  text: string;6  type: string;7  score?: number;8}9 10function App() {11  const [file, setFile] = useState<File | null>(null);12  const [query, setQuery] = useState('');13  const [results, setResults] = useState<DocumentResponse[]>([]);14  const [loading, setLoading] = useState(false);15  const [message, setMessage] = useState('');16  const [sessionId, setSessionId] = useState<string | null>(null);17  const [currentAnswer, setCurrentAnswer] = useState<string>('');18 19  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {20    if (e.target.files && e.target.files[0]) {21      setFile(e.target.files[0]);22    }23  };24 25  const handleUpload = async () => {26    if (!file) {27      setMessage('Please select a file first');28      return;29    }30 31    setLoading(true);32    const formData = new FormData();33    formData.append('file', file);34 35    try {36      const response = await fetch('http://localhost:9000/upload', {37        method: 'POST',38        body: formData,39      });40 41      if (!response.ok) {42        throw new Error('Upload failed');43      }44 45      const data = await response.json();46      setMessage(data.message);47      setSessionId(data.session_id);48      setResults([]);49      setCurrentAnswer('');50    } catch (error) {51      setMessage('Error uploading file');52    } finally {53      setLoading(false);54    }55  };56 57  const handleQuery = async () => {58    if (!query.trim()) {59      setMessage('Please enter a query');60      return;61    }62 63    if (!sessionId) {64      setMessage('Please upload a document first');65      return;66    }67 68    setLoading(true);69    setCurrentAnswer('');70    try {71      const response = await fetch(`http://localhost:9000/query/${sessionId}`, {72        method: 'POST',73        headers: {74          'Content-Type': 'application/json',75        },76        body: JSON.stringify({ text: query, k: 4 }),77      });78 79      if (!response.ok) {80        throw new Error('Query failed');81      }82 83      // Handle streaming response84      const reader = response.body?.getReader();85      const decoder = new TextDecoder();86      let buffer = '';87 88      if (!reader) {89        throw new Error('No reader available');90      }91 92      while (true) {93        const { done, value } = await reader.read();94        if (done) break;95 96        buffer += decoder.decode(value, { stream: true });97        const lines = buffer.split('\n');98        buffer = lines.pop() || '';99 100        for (const line of lines) {101          if (line.startsWith('data: ')) {102            const data = JSON.parse(line.slice(6));103            if (data.type === 'token') {104              setCurrentAnswer(prev => prev + data.text);105            } else if (data.type === 'context') {106              setResults(data.context);107            }108          }109        }110      }111    } catch (error) {112      setMessage('Error querying documents');113    } finally {114      setLoading(false);115    }116  };117 118  return (119    <div className="App">120      <header className="App-header">121        <h1>RAG System</h1>122      </header>123      124      <main className="App-main">125        <section className="upload-section">126          <h2>Upload PDF Document</h2>127          <input type="file" accept=".pdf" onChange={handleFileChange} />128          <button onClick={handleUpload} disabled={loading || !file}>129            {loading ? 'Uploading...' : 'Upload'}130          </button>131        </section>132 133        <section className="query-section">134          <h2>Query Documents</h2>135          <input136            type="text"137            value={query}138            onChange={(e) => setQuery(e.target.value)}139            placeholder="Enter your query..."140            disabled={!sessionId}141          />142          <button onClick={handleQuery} disabled={loading || !query.trim() || !sessionId}>143            {loading ? 'Searching...' : 'Search'}144          </button>145        </section>146 147        {message && <div className="message">{message}</div>}148 149        <section className="results-section">150          <h2>Results</h2>151          {currentAnswer && (152            <div className="llm-response">153              <h3>AI Response</h3>154              <p className="result-text">{currentAnswer}</p>155            </div>156          )}157          158          {results.length > 0 && (159            <div className="relevant-chunks">160              <h3>Relevant Document Chunks</h3>161              {results.map((result, index) => (162                <div key={index} className="result-item">163                  <p className="result-text">{result.text}</p>164                  {result.score !== undefined && (165                    <p className="result-score">Relevance Score: {result.score.toFixed(2)}</p>166                  )}167                </div>168              ))}169            </div>170          )}171        </section>172      </main>173    </div>174  );175}176 177export default App;178