VcRlAgent commited on
Commit
e87fd2c
·
1 Parent(s): a1c92e6

Initial WorkWise backend GPU

Browse files
Files changed (9) hide show
  1. Dockerfile.txt +13 -0
  2. app copy 2.py +0 -57
  3. app copy.py +0 -87
  4. app.py +0 -36
  5. app.py.bak +0 -16
  6. app.py.min.working +0 -27
  7. app/{main.py.bak → main.py} +2 -4
  8. requirements.txt +18 -5
  9. space.yaml +33 -0
Dockerfile.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY app/ ./app/
9
+ COPY data/ ./data/
10
+
11
+ EXPOSE 8000
12
+
13
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
app copy 2.py DELETED
@@ -1,57 +0,0 @@
1
- import gradio as gr
2
- import spaces
3
-
4
- # Import your services
5
- from app.config import settings
6
- from app.services.vector_store import vector_store
7
- from app.utils.logger import setup_logger
8
-
9
- logger = setup_logger(__name__)
10
-
11
- @spaces.GPU
12
- def query_jira(question: str):
13
- try:
14
- from app.services.rag_service import process_query
15
- return process_query(question)
16
- except Exception as e:
17
- return f"Error: {str(e)}"
18
-
19
- # Create Gradio app with API
20
- with gr.Blocks() as demo:
21
- gr.Markdown("# WorkWise - Jira RAG Assistant")
22
-
23
- input_text = gr.Textbox(label="Question")
24
- output_text = gr.Textbox(label="Answer")
25
- submit_btn = gr.Button("Ask")
26
-
27
- submit_btn.click(fn=query_jira, inputs=input_text, outputs=output_text, api_name="ask")
28
-
29
- # Access FastAPI app from Gradio
30
- app = demo.app
31
-
32
- # CORS Middleware
33
- app.add_middleware(
34
- CORSMiddleware,
35
- allow_origins=settings.ALLOWED_ORIGINS,
36
- allow_credentials=True,
37
- allow_methods=["*"],
38
- allow_headers=["*"],
39
- )
40
-
41
- # Add your custom routes to Gradio's underlying FastAPI app
42
- from app.routes import ingest_routes, ask_routes, metrics_routes
43
-
44
- app.include_router(ingest_routes.router, prefix="/api", tags=["Ingestion"])
45
- app.include_router(ask_routes.router, prefix="/api", tags=["Query"])
46
- app.include_router(metrics_routes.router, prefix="/api", tags=["Metrics"])
47
-
48
- @app.get("/health")
49
- async def health_check():
50
- try:
51
- info = vector_store.get_collection_info()
52
- return {"status": "healthy", "vectors_count": info.get("vectors_count", 0)}
53
- except Exception as e:
54
- return {"status": "error", "message": str(e)}
55
-
56
- if __name__ == "__main__":
57
- demo.launch(ssr_mode=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app copy.py DELETED
@@ -1,87 +0,0 @@
1
- import gradio as gr
2
- from fastapi import FastAPI
3
- from fastapi.middleware.cors import CORSMiddleware
4
- import spaces
5
-
6
- # Import your existing routes and services
7
- from app.config import settings
8
- from app.routes import ingest_routes, ask_routes, metrics_routes
9
- from app.services.vector_store import vector_store
10
- from app.utils.logger import setup_logger
11
-
12
- logger = setup_logger(__name__)
13
-
14
- # Create FastAPI app
15
- app = FastAPI(
16
- title="WorkWise Backend",
17
- description="RAG-powered Jira analytics application",
18
- version="1.0.0"
19
- )
20
-
21
- # CORS Middleware
22
- app.add_middleware(
23
- CORSMiddleware,
24
- allow_origins=settings.ALLOWED_ORIGINS,
25
- allow_credentials=True,
26
- allow_methods=["*"],
27
- allow_headers=["*"],
28
- )
29
-
30
- # Include your existing routers
31
- app.include_router(ingest_routes.router, prefix="/api", tags=["Ingestion"])
32
- app.include_router(ask_routes.router, prefix="/api", tags=["Query"])
33
- app.include_router(metrics_routes.router, prefix="/api", tags=["Metrics"])
34
-
35
- @app.get("/")
36
- async def root():
37
- return {
38
- "status": "online",
39
- "service": "WorkWise API",
40
- "version": "1.0.0"
41
- }
42
-
43
- @app.get("/health")
44
- async def health_check():
45
- try:
46
- info = vector_store.get_collection_info()
47
- return {
48
- "status": "healthy",
49
- "index_path": settings.FAISS_INDEX_PATH,
50
- "payloads_path": settings.FAISS_PAYLOADS_PATH,
51
- "vectors_count": info.get("vectors_count", 0)
52
- }
53
- except Exception as e:
54
- logger.error(f"Health check failed: {e}")
55
- return {"status": "error", "message": str(e)}
56
-
57
- # Minimal Gradio UI (required for ZeroGPU)
58
- @spaces.GPU
59
- def query_jira(question: str):
60
- """Simple wrapper for Gradio - calls your actual RAG logic"""
61
- try:
62
- # Import your actual query function here
63
- from app.services.rag_service import process_query # adjust import as needed
64
- result = process_query(question)
65
- return result
66
- except Exception as e:
67
- return f"Error: {str(e)}"
68
-
69
- # Create Gradio interface
70
- with gr.Blocks(title="WorkWise - Ask Jira") as demo:
71
- gr.Markdown("# WorkWise - Jira RAG Assistant")
72
- gr.Markdown("Ask questions about your Jira data")
73
-
74
- with gr.Row():
75
- input_text = gr.Textbox(label="Your Question", placeholder="e.g., What are the top issues this sprint?")
76
- output_text = gr.Textbox(label="Answer")
77
-
78
- submit_btn = gr.Button("Ask")
79
- submit_btn.click(fn=query_jira, inputs=input_text, outputs=output_text)
80
-
81
- # Mount Gradio to FastAPI
82
- #app = gr.mount_gradio_app(app, demo, path="/")
83
- demo = gr.mount_gradio_app(demo, app, path="/")
84
-
85
- # Launch
86
- if __name__ == "__main__":
87
- demo.launch(ssr_mode=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py DELETED
@@ -1,36 +0,0 @@
1
- import spaces
2
- import gradio as gr
3
- from fastapi import FastAPI
4
- from fastapi.responses import JSONResponse
5
-
6
- # Step 1: Create a simple function
7
- @spaces.GPU
8
- def simple_function(text):
9
- return f"Echo: {text}"
10
-
11
- # Step 2: Create Gradio interface
12
- demo = gr.Interface(
13
- fn=simple_function,
14
- inputs=gr.Textbox(label="Input"),
15
- outputs=gr.Textbox(label="Output")
16
- )
17
-
18
- # Step 3: Get FastAPI app from Gradio
19
- fastapi_app = demo.app
20
-
21
- # Step 4: Add FastAPI endpoints AFTER getting the app
22
- @fastapi_app.get("/health")
23
- def health_check():
24
- return JSONResponse({"status": "healthy", "message": "API is working"})
25
-
26
- @fastapi_app.get("/api/test")
27
- def test_endpoint():
28
- return JSONResponse({"message": "FastAPI endpoint works!"})
29
-
30
- @fastapi_app.post("/api/echo")
31
- def echo_endpoint(data: dict):
32
- return JSONResponse({"echo": data})
33
-
34
- # Step 5: Launch
35
- if __name__ == "__main__":
36
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py.bak DELETED
@@ -1,16 +0,0 @@
1
- import gradio as gr
2
- import spaces
3
- from fastapi import FastAPI
4
- import uvicorn
5
- from threading import Thread
6
-
7
- @spaces.GPU
8
- def process(data):
9
- # Your GPU logic
10
- return result
11
-
12
- # Minimal Gradio UI
13
- demo = gr.Interface(fn=process, inputs="text", outputs="text")
14
-
15
- # Launch Gradio (keeps space alive)
16
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py.min.working DELETED
@@ -1,27 +0,0 @@
1
- import gradio as gr
2
- from fastapi import FastAPI
3
- import spaces
4
-
5
- app = FastAPI()
6
-
7
- @spaces.GPU
8
- def your_gpu_function(input_data):
9
- # Your GPU computation
10
- return {"message": "FastAPI is working"}
11
- #return result
12
-
13
- # FastAPI endpoint
14
- @app.get("/api/predict")
15
- async def predict(input: str):
16
- result = your_gpu_function(input)
17
- return {"result": result}
18
-
19
- # Gradio interface (required for ZeroGPU)
20
- with gr.Blocks() as demo:
21
- gr.Interface(fn=your_gpu_function, inputs="text", outputs="text")
22
-
23
- # Mount FastAPI to Gradio
24
- app = gr.mount_gradio_app(app, demo, path="/")
25
-
26
- if __name__ == "__main__":
27
- demo.launch(ssr_mode=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/{main.py.bak → main.py} RENAMED
@@ -9,7 +9,7 @@ from app.utils.logger import setup_logger
9
  logger = setup_logger(__name__)
10
 
11
  app = FastAPI(
12
- title="WorkWise Backend",
13
  description="RAG-powered Jira analytics application",
14
  version="1.0.0"
15
  )
@@ -17,7 +17,7 @@ app = FastAPI(
17
  # CORS Middleware
18
  app.add_middleware(
19
  CORSMiddleware,
20
- allow_origins=settings.ALLOWED_ORIGINS,
21
  allow_credentials=True,
22
  allow_methods=["*"],
23
  allow_headers=["*"],
@@ -57,7 +57,6 @@ async def health_check():
57
  return {"status": "error", "message": str(e)}
58
 
59
  # This is needed only when this was a Docker Space. Remove for Gradio
60
- '''
61
  if __name__ == "__main__":
62
  import uvicorn
63
  uvicorn.run(
@@ -67,4 +66,3 @@ if __name__ == "__main__":
67
  reload=True,
68
  log_level=settings.LOG_LEVEL
69
  )
70
- '''
 
9
  logger = setup_logger(__name__)
10
 
11
  app = FastAPI(
12
+ title="WorkWise Backend GPU",
13
  description="RAG-powered Jira analytics application",
14
  version="1.0.0"
15
  )
 
17
  # CORS Middleware
18
  app.add_middleware(
19
  CORSMiddleware,
20
+ allow_origins=settings.ALLOWED_ORIGINS if hasattr(settings, "ALLOWED_ORIGINS") else ["*"],
21
  allow_credentials=True,
22
  allow_methods=["*"],
23
  allow_headers=["*"],
 
57
  return {"status": "error", "message": str(e)}
58
 
59
  # This is needed only when this was a Docker Space. Remove for Gradio
 
60
  if __name__ == "__main__":
61
  import uvicorn
62
  uvicorn.run(
 
66
  reload=True,
67
  log_level=settings.LOG_LEVEL
68
  )
 
requirements.txt CHANGED
@@ -1,12 +1,25 @@
1
- spaces
2
  fastapi==0.109.0
3
  uvicorn[standard]==0.27.0
4
  python-dotenv==1.0.0
 
 
 
5
  pandas==2.2.0
6
  numpy==1.26.3
7
- sentence-transformers==2.3.1
8
- faiss-cpu==1.7.4
9
- qdrant-client==1.7.3
10
  pydantic==2.5.3
11
  python-multipart==0.0.6
12
- requests==2.31.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  fastapi==0.109.0
2
  uvicorn[standard]==0.27.0
3
  python-dotenv==1.0.0
4
+ python-multipart==0.0.6 # if you accept file uploads
5
+
6
+ # === Data / utilities ===
7
  pandas==2.2.0
8
  numpy==1.26.3
9
+ requests==2.31.0
 
 
10
  pydantic==2.5.3
11
  python-multipart==0.0.6
12
+ tqdm==4.66.4 # progress bars
13
+ loguru==0.7.2 # clean logging
14
+
15
+ # Vector/Embedding stack (keep exactly what you use)
16
+ faiss-cpu==1.7.4 # keep if you use FAISS locally
17
+ qdrant-client==1.7.3 # keep if using Qdrant
18
+
19
+
20
+ # === ML / AI stack (GPU-compatible) ===
21
+ # Using torch for embeddings/models:
22
+ torch #-- choose the right wheel for your CUDA (see Dockerfile notes)
23
+ transformers
24
+ sentence-transformers
25
+
space.yaml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # === Hugging Face Space Configuration ===
2
+
3
+ # We’re using a custom container because this is a GPU FastAPI backend.
4
+ sdk: "docker"
5
+
6
+ # (Optional metadata)
7
+ title: "WorkWise Backend GPU"
8
+ emoji: "⚙️"
9
+ colorFrom: "blue"
10
+ colorTo: "indigo"
11
+ app_port: 7860 # HF routes traffic through port 7860 inside the container
12
+ pinned: false
13
+
14
+ # Hardware (HF will spin up a GPU runtime)
15
+ hardware: "gpu"
16
+
17
+ # Docker build context
18
+ # Hugging Face will automatically build your Dockerfile at repo root
19
+ # (Make sure you have Dockerfile and requirements.txt)
20
+ ---
21
+
22
+ # Optional environment variables (you can also set these from HF UI)
23
+ env:
24
+ - name: HF_HOME
25
+ value: /data/huggingface
26
+ - name: HF_HUB_DISABLE_TELEMETRY
27
+ value: "1"
28
+ - name: CUDA_VISIBLE_DEVICES
29
+ value: "0"
30
+
31
+ # If your app uses secrets (API keys, vector DB URL), define them via
32
+ # “Settings → Repository secrets” in Hugging Face UI (not here)
33
+