Skip to content

Commit 6fdb1ca

Browse files
perf: Load X-Pack
1 parent 7ae095d commit 6fdb1ca

File tree

4 files changed

+65
-17
lines changed

4 files changed

+65
-17
lines changed

backend/main.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import logging
22
from fastapi.concurrency import asynccontextmanager
3-
from fastapi.responses import FileResponse
4-
from fastapi.staticfiles import StaticFiles
5-
import os
63
import sentry_sdk
7-
from fastapi import FastAPI, Path, HTTPException
4+
from fastapi import FastAPI
85
from fastapi.routing import APIRoute
96
from starlette.middleware.cors import CORSMiddleware
107
from starlette.exceptions import HTTPException as StarletteHTTPException
@@ -76,19 +73,7 @@ def custom_generate_unique_id(route: APIRoute) -> str:
7673
app.add_exception_handler(StarletteHTTPException, exception_handler.http_exception_handler)
7774
app.add_exception_handler(Exception, exception_handler.global_exception_handler)
7875

79-
frontend_dist = os.path.abspath("../frontend/dist")
80-
if not os.path.exists(frontend_dist):
81-
logging.warning(f"The front-end build directory does not exist: {frontend_dist}")
82-
logging.warning("Please make sure you have built the front-end project")
8376

84-
else:
85-
86-
@app.get("/", include_in_schema=False)
87-
async def read_index():
88-
return FileResponse(path=os.path.join(frontend_dist, "index.html"))
89-
90-
91-
app.mount("/", StaticFiles(directory=frontend_dist), name="static")
9277

9378
mcp.setup_server()
9479

backend/pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,20 @@ dependencies = [
3535
"oracledb (>=3.1.1,<4.0.0)",
3636
"pyyaml (>=6.0.2,<7.0.0)",
3737
"fastapi-mcp (>=0.3.4,<0.4.0)",
38+
"sqlbot-xpack==0.0.2",
3839
]
3940
[[tool.uv.index]]
41+
name = "default"
4042
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
4143
default = true
44+
[[tool.uv.index]]
45+
46+
name = "testpypi"
47+
url = "https://test.pypi.org/simple"
48+
explicit = true
49+
50+
[tool.uv.sources]
51+
sqlbot-xpack = { index = "testpypi" }
4252

4353
[tool.uv]
4454
dev-dependencies = [

frontend/src/router/watch.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { ElMessage } from 'element-plus-secondary'
22
import { useCache } from '@/utils/useCache'
33
import { useUserStore } from '@/stores/user'
4-
4+
import { request } from '@/utils/request'
55
const userStore = useUserStore()
66
const { wsCache } = useCache()
77
const whiteList = ['/login']
88
export const watchRouter = (router: any) => {
99
router.beforeEach(async (to: any, from: any, next: any) => {
10+
await loadXpackStatic()
1011
const token = wsCache.get('user.token')
1112
if (whiteList.includes(to.path)) {
1213
next()
@@ -32,3 +33,14 @@ export const watchRouter = (router: any) => {
3233
}
3334
})
3435
}
36+
const loadXpackStatic = () => {
37+
if (document.getElementById('sqlbot_xpack_static')) {
38+
return Promise.resolve()
39+
}
40+
const url = '/xpack_static/license-generator.umd.js'
41+
return request.loadRemoteScript(url, 'sqlbot_xpack_static', () => {
42+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
43+
// @ts-ignore
44+
LicenseGenerator?.init(import.meta.env.VITE_API_BASE_URL)
45+
})
46+
}

frontend/src/utils/request.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ class HttpService {
6969
if (token && config.headers) {
7070
config.headers['X-SQLBOT-TOKEN'] = `Bearer ${token}`
7171
}
72+
if (config.url?.includes('/xpack_static/') && config.baseURL) {
73+
config.baseURL = config.baseURL.replace('/api/v1', '')
74+
// Skip auth for xpack_static requests
75+
return config
76+
}
77+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
78+
// @ts-ignore
79+
const request_key = LicenseGenerator.generate()
80+
config.headers['X-SQLBOT-KEY'] = request_key
7281

7382
// Request logging
7483
// console.log(`[Request] ${config.method?.toUpperCase()} ${config.url}`)
@@ -258,6 +267,38 @@ class HttpService {
258267
responseType: 'blob',
259268
})
260269
}
270+
271+
public loadRemoteScript(url: string, id?: string, cb?: any): Promise<HTMLElement> {
272+
if (!url) {
273+
return Promise.reject(new Error('URL is required to load remote script'))
274+
}
275+
if (id && document.getElementById(id)) {
276+
return Promise.resolve(document.getElementById(id) as HTMLElement)
277+
}
278+
return new Promise<HTMLElement>((resolve, reject) => {
279+
this.get(url, {
280+
responseType: 'text',
281+
headers: {
282+
'Content-Type': 'application/javascript',
283+
},
284+
})
285+
.then((response: any) => {
286+
const script = document.createElement('script')
287+
script.textContent = response
288+
script.id = id || `remote-script-${Date.now()}`
289+
// Append script to head
290+
document.head.appendChild(script)
291+
if (cb) {
292+
cb()
293+
}
294+
resolve(script)
295+
})
296+
.catch((error: any) => {
297+
console.error(`Failed to load script from ${url}:`, error)
298+
reject(new Error(`Failed to load script from ${url}: ${error.message}`))
299+
})
300+
})
301+
}
261302
}
262303

263304
// Create singleton instance

0 commit comments

Comments
 (0)