Spaces:
Sleeping
Sleeping
Enhance API versioning and frontend integration
Browse files- Added API versioning information in FastAPI, including a new `/version` endpoint to provide version and build date details.
- Updated the frontend to fetch and display API version information, enhancing user awareness of the current API status.
- Improved footer layout in the App component to include API version and operational status indicators.
- CHANGELOG.md +31 -0
- api/main.py +17 -1
- app/frontend/src/App.js +29 -1
- app/frontend/src/utils/version.js +43 -0
CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Changelog
|
| 2 |
+
|
| 3 |
+
All notable changes to the Quick Understand application will be documented in this file.
|
| 4 |
+
|
| 5 |
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
| 6 |
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
| 7 |
+
|
| 8 |
+
## [0.2.0] - 2024-06-14
|
| 9 |
+
|
| 10 |
+
### Added
|
| 11 |
+
- Response streaming for real-time AI answers
|
| 12 |
+
- Improved font readability with better typography
|
| 13 |
+
- Dark mode support with darker header in dark theme
|
| 14 |
+
- Version information in application footer
|
| 15 |
+
- API version endpoint
|
| 16 |
+
|
| 17 |
+
### Changed
|
| 18 |
+
- Renamed application to "Quick Understand"
|
| 19 |
+
- Enhanced message display with better formatting
|
| 20 |
+
- Fixed duplicate message issues in streaming responses
|
| 21 |
+
- Improved code block styling
|
| 22 |
+
|
| 23 |
+
## [0.1.0] - 2024-06-01
|
| 24 |
+
|
| 25 |
+
### Added
|
| 26 |
+
- Initial release of RAG Chat application
|
| 27 |
+
- Document upload and processing
|
| 28 |
+
- Question answering using RAG approach
|
| 29 |
+
- Basic UI with chat interface
|
| 30 |
+
- Quiz generation feature
|
| 31 |
+
- Document summary visualization
|
api/main.py
CHANGED
|
@@ -18,7 +18,15 @@ from aimakerspace.openai_utils.prompts import (
|
|
| 18 |
from aimakerspace.vectordatabase import VectorDatabase
|
| 19 |
from aimakerspace.openai_utils.chatmodel import ChatOpenAI
|
| 20 |
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
# Add CORS middleware
|
| 24 |
app.add_middleware(
|
|
@@ -540,6 +548,14 @@ def generate_fallback_questions(num_questions: int) -> List[QuizQuestion]:
|
|
| 540 |
async def read_root():
|
| 541 |
return FileResponse("static/index.html")
|
| 542 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 543 |
@app.get("/{path:path}")
|
| 544 |
async def catch_all(path: str):
|
| 545 |
if os.path.exists(f"static/{path}"):
|
|
|
|
| 18 |
from aimakerspace.vectordatabase import VectorDatabase
|
| 19 |
from aimakerspace.openai_utils.chatmodel import ChatOpenAI
|
| 20 |
|
| 21 |
+
# API Version information
|
| 22 |
+
API_VERSION = "0.2.0"
|
| 23 |
+
BUILD_DATE = "2024-06-14" # Update this when making significant changes
|
| 24 |
+
|
| 25 |
+
app = FastAPI(
|
| 26 |
+
title="Quick Understand API",
|
| 27 |
+
description="RAG-based question answering API for document understanding",
|
| 28 |
+
version=API_VERSION
|
| 29 |
+
)
|
| 30 |
|
| 31 |
# Add CORS middleware
|
| 32 |
app.add_middleware(
|
|
|
|
| 548 |
async def read_root():
|
| 549 |
return FileResponse("static/index.html")
|
| 550 |
|
| 551 |
+
@app.get("/version")
|
| 552 |
+
async def get_version():
|
| 553 |
+
return {
|
| 554 |
+
"api_version": API_VERSION,
|
| 555 |
+
"build_date": BUILD_DATE,
|
| 556 |
+
"status": "operational"
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
@app.get("/{path:path}")
|
| 560 |
async def catch_all(path: str):
|
| 561 |
if os.path.exists(f"static/{path}"):
|
app/frontend/src/App.js
CHANGED
|
@@ -7,6 +7,7 @@ import DocumentSummary from './components/DocumentSummary';
|
|
| 7 |
import { ThemeProvider } from './components/ui/theme-provider';
|
| 8 |
import { ThemeToggle } from './components/ui/theme-toggle';
|
| 9 |
import { SettingsDialog } from './components/ui/settings-dialog';
|
|
|
|
| 10 |
|
| 11 |
function App() {
|
| 12 |
const [sessionId, setSessionId] = useState('');
|
|
@@ -14,6 +15,7 @@ function App() {
|
|
| 14 |
const [uploadedFiles, setUploadedFiles] = useState([]);
|
| 15 |
const [activeFileIndex, setActiveFileIndex] = useState(0);
|
| 16 |
const [selectedQuestion, setSelectedQuestion] = useState('');
|
|
|
|
| 17 |
|
| 18 |
// App settings with localStorage persistence
|
| 19 |
const [settings, setSettings] = useState(() => {
|
|
@@ -32,6 +34,16 @@ function App() {
|
|
| 32 |
}
|
| 33 |
}, [sessionId]);
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
// Save settings to localStorage when they change
|
| 36 |
useEffect(() => {
|
| 37 |
localStorage.setItem('appSettings', JSON.stringify(settings));
|
|
@@ -166,7 +178,23 @@ function App() {
|
|
| 166 |
</main>
|
| 167 |
|
| 168 |
<footer className="w-full py-4 px-6 text-center text-sm text-muted-foreground">
|
| 169 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
</footer>
|
| 171 |
</div>
|
| 172 |
</ThemeProvider>
|
|
|
|
| 7 |
import { ThemeProvider } from './components/ui/theme-provider';
|
| 8 |
import { ThemeToggle } from './components/ui/theme-toggle';
|
| 9 |
import { SettingsDialog } from './components/ui/settings-dialog';
|
| 10 |
+
import { getVersionString, fetchApiVersion } from './utils/version';
|
| 11 |
|
| 12 |
function App() {
|
| 13 |
const [sessionId, setSessionId] = useState('');
|
|
|
|
| 15 |
const [uploadedFiles, setUploadedFiles] = useState([]);
|
| 16 |
const [activeFileIndex, setActiveFileIndex] = useState(0);
|
| 17 |
const [selectedQuestion, setSelectedQuestion] = useState('');
|
| 18 |
+
const [apiVersion, setApiVersion] = useState(null);
|
| 19 |
|
| 20 |
// App settings with localStorage persistence
|
| 21 |
const [settings, setSettings] = useState(() => {
|
|
|
|
| 34 |
}
|
| 35 |
}, [sessionId]);
|
| 36 |
|
| 37 |
+
// Fetch API version information
|
| 38 |
+
useEffect(() => {
|
| 39 |
+
const getApiVersion = async () => {
|
| 40 |
+
const versionInfo = await fetchApiVersion();
|
| 41 |
+
setApiVersion(versionInfo);
|
| 42 |
+
};
|
| 43 |
+
|
| 44 |
+
getApiVersion();
|
| 45 |
+
}, []);
|
| 46 |
+
|
| 47 |
// Save settings to localStorage when they change
|
| 48 |
useEffect(() => {
|
| 49 |
localStorage.setItem('appSettings', JSON.stringify(settings));
|
|
|
|
| 178 |
</main>
|
| 179 |
|
| 180 |
<footer className="w-full py-4 px-6 text-center text-sm text-muted-foreground">
|
| 181 |
+
<div className="flex flex-col items-center justify-center">
|
| 182 |
+
<p>Made with <span role="img" aria-label="heart" className="text-red-500">❤️</span> and Shadcn/UI</p>
|
| 183 |
+
<div className="text-xs opacity-70 mt-1 flex items-center gap-2 justify-center">
|
| 184 |
+
<span>UI: {getVersionString()}</span>
|
| 185 |
+
{apiVersion && (
|
| 186 |
+
<>
|
| 187 |
+
<span className="bg-border/30 w-[1px] h-3 inline-block"></span>
|
| 188 |
+
<span>API: v{apiVersion.api_version}</span>
|
| 189 |
+
<span className={`w-2 h-2 rounded-full ${
|
| 190 |
+
apiVersion.status === 'operational'
|
| 191 |
+
? 'bg-green-500'
|
| 192 |
+
: 'bg-amber-500'
|
| 193 |
+
}`} title={`Status: ${apiVersion.status}`}></span>
|
| 194 |
+
</>
|
| 195 |
+
)}
|
| 196 |
+
</div>
|
| 197 |
+
</div>
|
| 198 |
</footer>
|
| 199 |
</div>
|
| 200 |
</ThemeProvider>
|
app/frontend/src/utils/version.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Version information
|
| 2 |
+
import packageInfo from '../../package.json';
|
| 3 |
+
import axios from 'axios';
|
| 4 |
+
|
| 5 |
+
// App version from package.json
|
| 6 |
+
export const APP_VERSION = packageInfo.version;
|
| 7 |
+
|
| 8 |
+
// Build date (when the file is imported/executed)
|
| 9 |
+
export const BUILD_DATE = new Date().toISOString().split('T')[0];
|
| 10 |
+
|
| 11 |
+
// Format the version string for display
|
| 12 |
+
export const getVersionString = () => {
|
| 13 |
+
return `v${APP_VERSION} (${BUILD_DATE})`;
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
// API version information
|
| 17 |
+
export const fetchApiVersion = async () => {
|
| 18 |
+
try {
|
| 19 |
+
const response = await axios.get('/version');
|
| 20 |
+
return response.data;
|
| 21 |
+
} catch (error) {
|
| 22 |
+
console.error('Error fetching API version:', error);
|
| 23 |
+
return {
|
| 24 |
+
api_version: 'unknown',
|
| 25 |
+
build_date: 'unknown',
|
| 26 |
+
status: 'unknown'
|
| 27 |
+
};
|
| 28 |
+
}
|
| 29 |
+
};
|
| 30 |
+
|
| 31 |
+
// Check if version is newer than stored version
|
| 32 |
+
export const isNewVersion = (storedVersion) => {
|
| 33 |
+
if (!storedVersion) return true;
|
| 34 |
+
return storedVersion !== APP_VERSION;
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
export default {
|
| 38 |
+
APP_VERSION,
|
| 39 |
+
BUILD_DATE,
|
| 40 |
+
getVersionString,
|
| 41 |
+
fetchApiVersion,
|
| 42 |
+
isNewVersion
|
| 43 |
+
};
|