Spaces:
Sleeping
Sleeping
Upload 26 files
Browse files- frontend/src/index.css +7 -0
- frontend/src/index.html +13 -0
- frontend/vite.config.ts +6 -2
- main.py +7 -1
- services/storage.py +8 -0
frontend/src/index.css
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@tailwind base;
|
| 2 |
+
@tailwind components;
|
| 3 |
+
@tailwind utilities;
|
| 4 |
+
|
| 5 |
+
body {
|
| 6 |
+
font-family: system-ui, sans-serif;
|
| 7 |
+
}
|
frontend/src/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
+
<title>SpaceProbe Dashboard</title>
|
| 7 |
+
</head>
|
| 8 |
+
<body class="bg-black text-white">
|
| 9 |
+
<div id="root"></div>
|
| 10 |
+
|
| 11 |
+
<script type="module" src="/src/main.tsx"></script>
|
| 12 |
+
</body>
|
| 13 |
+
</html>
|
frontend/vite.config.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
server: {
|
| 3 |
proxy: {
|
| 4 |
"/api": "http://localhost:8000",
|
| 5 |
},
|
| 6 |
},
|
| 7 |
-
};
|
|
|
|
| 1 |
+
import { defineConfig } from "vite";
|
| 2 |
+
import react from "@vitejs/plugin-react";
|
| 3 |
+
|
| 4 |
+
export default defineConfig({
|
| 5 |
+
plugins: [react()],
|
| 6 |
server: {
|
| 7 |
proxy: {
|
| 8 |
"/api": "http://localhost:8000",
|
| 9 |
},
|
| 10 |
},
|
| 11 |
+
});
|
main.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from fastapi import FastAPI
|
| 2 |
from app.api.routes import repos, metrics, status
|
| 3 |
from app.services.storage import storage
|
|
|
|
| 4 |
import asyncio
|
| 5 |
|
| 6 |
app = FastAPI(title="SpaceProbe API")
|
|
@@ -22,4 +23,9 @@ async def start_aggregator_service():
|
|
| 22 |
storage.aggregate(repo_id)
|
| 23 |
await asyncio.sleep(5)
|
| 24 |
|
| 25 |
-
asyncio.create_task(loop())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from fastapi import FastAPI
|
| 2 |
from app.api.routes import repos, metrics, status
|
| 3 |
from app.services.storage import storage
|
| 4 |
+
from fastapi.responses import FileResponse
|
| 5 |
import asyncio
|
| 6 |
|
| 7 |
app = FastAPI(title="SpaceProbe API")
|
|
|
|
| 23 |
storage.aggregate(repo_id)
|
| 24 |
await asyncio.sleep(5)
|
| 25 |
|
| 26 |
+
asyncio.create_task(loop())
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
@app.get("/{full_path:path}")
|
| 30 |
+
async def serve_spa():
|
| 31 |
+
return FileResponse("static/index.html")
|
services/storage.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from typing import Dict, List, Any
|
| 2 |
from datetime import datetime, timedelta
|
| 3 |
from app.models.schema import Repo, MetricPoint, RepoStatus
|
|
|
|
| 4 |
|
| 5 |
class InMemoryStorage:
|
| 6 |
def __init__(self):
|
|
@@ -78,6 +79,13 @@ class InMemoryStorage:
|
|
| 78 |
# prune (keep reasonable size)
|
| 79 |
if len(series) > 1000:
|
| 80 |
series.pop(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
# Global instance
|
| 83 |
storage = InMemoryStorage()
|
|
|
|
| 1 |
from typing import Dict, List, Any
|
| 2 |
from datetime import datetime, timedelta
|
| 3 |
from app.models.schema import Repo, MetricPoint, RepoStatus
|
| 4 |
+
from app.services.storage import storage
|
| 5 |
|
| 6 |
class InMemoryStorage:
|
| 7 |
def __init__(self):
|
|
|
|
| 79 |
# prune (keep reasonable size)
|
| 80 |
if len(series) > 1000:
|
| 81 |
series.pop(0)
|
| 82 |
+
|
| 83 |
+
def get_aggregated_metrics(self, repo_id: str, range: str):
|
| 84 |
+
repo = self.metrics.get(repo_id)
|
| 85 |
+
if not repo:
|
| 86 |
+
return []
|
| 87 |
+
|
| 88 |
+
return repo.get(range, [])
|
| 89 |
|
| 90 |
# Global instance
|
| 91 |
storage = InMemoryStorage()
|