Spaces:
Sleeping
Sleeping
fix3
Browse files
app.py
CHANGED
|
@@ -12,7 +12,7 @@ from uvicorn import run as uvicorn_run
|
|
| 12 |
|
| 13 |
# Slack Libraries (Async versions)
|
| 14 |
from slack_bolt.async_app import AsyncApp
|
| 15 |
-
from slack_bolt.adapter.fastapi import AsyncSlackRequestHandler
|
| 16 |
from slack_sdk.oauth.installation_store.async_installation_store import AsyncInstallationStore
|
| 17 |
from slack_sdk.oauth import AuthorizeUrlGenerator
|
| 18 |
from slack_bolt.models.installation import Installation
|
|
@@ -76,9 +76,8 @@ class SupabaseAsyncInstallationStore(AsyncInstallationStore):
|
|
| 76 |
}
|
| 77 |
try:
|
| 78 |
await asyncio.to_thread(
|
| 79 |
-
self.supabase.table("installations").upsert
|
| 80 |
)
|
| 81 |
-
await asyncio.to_thread(self.supabase.table("installations").upsert(data, on_conflict="team_id").execute)
|
| 82 |
logger.info(f"Saved installation for team: {installation.team_id}")
|
| 83 |
except Exception as e:
|
| 84 |
logger.error(f"Failed to save installation for team {installation.team_id}: {e}")
|
|
@@ -87,7 +86,7 @@ class SupabaseAsyncInstallationStore(AsyncInstallationStore):
|
|
| 87 |
async def fetch_installation(self, team_id: str, *, enterprise_id: str | None = None, user_id: str | None = None) -> Installation | None:
|
| 88 |
try:
|
| 89 |
result = await asyncio.to_thread(
|
| 90 |
-
self.supabase.table("installations").select("*").eq("team_id", team_id).execute
|
| 91 |
)
|
| 92 |
if not result.data:
|
| 93 |
return None
|
|
@@ -105,12 +104,12 @@ class SupabaseAsyncInstallationStore(AsyncInstallationStore):
|
|
| 105 |
)
|
| 106 |
except Exception as e:
|
| 107 |
logger.error(f"Failed to fetch installation for team {team_id}: {e}")
|
| 108 |
-
|
| 109 |
|
| 110 |
async def delete(self, team_id: str, *, enterprise_id: str | None = None, user_id: str | None = None) -> None:
|
| 111 |
try:
|
| 112 |
await asyncio.to_thread(
|
| 113 |
-
self.supabase.table("installations").delete().eq("team_id", team_id).execute
|
| 114 |
)
|
| 115 |
logger.info(f"Deleted installation for team: {team_id}")
|
| 116 |
except Exception as e:
|
|
@@ -210,10 +209,10 @@ async def store_embeddings(chunks: List[str]):
|
|
| 210 |
embedding = embed_text(chunk)
|
| 211 |
try:
|
| 212 |
await asyncio.to_thread(
|
| 213 |
-
supabase.table("documents").insert({
|
| 214 |
-
"content":
|
| 215 |
-
"embedding":
|
| 216 |
-
}).execute
|
| 217 |
)
|
| 218 |
except Exception as e:
|
| 219 |
logger.error(f"Failed to insert chunk into Supabase: {str(e)}")
|
|
@@ -222,7 +221,7 @@ async def is_table_empty() -> bool:
|
|
| 222 |
"""Checks if the documents table has any records."""
|
| 223 |
try:
|
| 224 |
result = await asyncio.to_thread(
|
| 225 |
-
supabase.table("documents").select("id", count="exact").limit(1).execute
|
| 226 |
)
|
| 227 |
return result.count == 0
|
| 228 |
except Exception as e:
|
|
@@ -236,9 +235,9 @@ async def search_documents(query: str, match_count: int = 5) -> List[Dict[str, A
|
|
| 236 |
query_embedding = embed_text(query)
|
| 237 |
try:
|
| 238 |
result = await asyncio.to_thread(
|
| 239 |
-
lambda: supabase.rpc("match_documents", {
|
| 240 |
-
"query_embedding":
|
| 241 |
-
"match_count":
|
| 242 |
}).execute()
|
| 243 |
)
|
| 244 |
return result.data
|
|
@@ -257,7 +256,7 @@ async def answer_question(question: str, context: str) -> str:
|
|
| 257 |
context_slice = context[:MAX_CONTEXT_LEN]
|
| 258 |
|
| 259 |
result = await asyncio.to_thread(
|
| 260 |
-
|
| 261 |
)
|
| 262 |
return result['answer']
|
| 263 |
except Exception as e:
|
|
@@ -373,7 +372,7 @@ async def health():
|
|
| 373 |
db_status = "error"
|
| 374 |
try:
|
| 375 |
await asyncio.to_thread(
|
| 376 |
-
supabase.table("installations").select("team_id").limit(1).execute
|
| 377 |
)
|
| 378 |
db_status = "ok"
|
| 379 |
except Exception as e:
|
|
@@ -391,6 +390,7 @@ async def install_url():
|
|
| 391 |
scopes=["app_mentions:read", "files:read", "chat:write", "im:read", "im:write", "channels:read"]
|
| 392 |
)
|
| 393 |
# NOTE: The redirect_uri should match your Slack App config (e.g., https://yourspace.hf.space/slack/oauth/callback)
|
|
|
|
| 394 |
url = generator.generate(state="state")
|
| 395 |
return {"install_url": url}
|
| 396 |
except Exception as e:
|
|
@@ -403,7 +403,7 @@ async def oauth_callback(request: Request):
|
|
| 403 |
try:
|
| 404 |
response = await handler.handle_async(request)
|
| 405 |
# For successful OAuth, return a simple HTML response
|
| 406 |
-
if response.status_code == 200:
|
| 407 |
return HTMLResponse(
|
| 408 |
content="<html><body><h1>Installation successful!</h1><p>You can now use the bot in your Slack workspace.</p></body></html>",
|
| 409 |
status_code=200
|
|
|
|
| 12 |
|
| 13 |
# Slack Libraries (Async versions)
|
| 14 |
from slack_bolt.async_app import AsyncApp
|
| 15 |
+
from slack_bolt.adapter.fastapi.async_handler import AsyncSlackRequestHandler
|
| 16 |
from slack_sdk.oauth.installation_store.async_installation_store import AsyncInstallationStore
|
| 17 |
from slack_sdk.oauth import AuthorizeUrlGenerator
|
| 18 |
from slack_bolt.models.installation import Installation
|
|
|
|
| 76 |
}
|
| 77 |
try:
|
| 78 |
await asyncio.to_thread(
|
| 79 |
+
lambda: self.supabase.table("installations").upsert(data, on_conflict="team_id").execute()
|
| 80 |
)
|
|
|
|
| 81 |
logger.info(f"Saved installation for team: {installation.team_id}")
|
| 82 |
except Exception as e:
|
| 83 |
logger.error(f"Failed to save installation for team {installation.team_id}: {e}")
|
|
|
|
| 86 |
async def fetch_installation(self, team_id: str, *, enterprise_id: str | None = None, user_id: str | None = None) -> Installation | None:
|
| 87 |
try:
|
| 88 |
result = await asyncio.to_thread(
|
| 89 |
+
lambda: self.supabase.table("installations").select("*").eq("team_id", team_id).execute()
|
| 90 |
)
|
| 91 |
if not result.data:
|
| 92 |
return None
|
|
|
|
| 104 |
)
|
| 105 |
except Exception as e:
|
| 106 |
logger.error(f"Failed to fetch installation for team {team_id}: {e}")
|
| 107 |
+
return None
|
| 108 |
|
| 109 |
async def delete(self, team_id: str, *, enterprise_id: str | None = None, user_id: str | None = None) -> None:
|
| 110 |
try:
|
| 111 |
await asyncio.to_thread(
|
| 112 |
+
lambda: self.supabase.table("installations").delete().eq("team_id", team_id).execute()
|
| 113 |
)
|
| 114 |
logger.info(f"Deleted installation for team: {team_id}")
|
| 115 |
except Exception as e:
|
|
|
|
| 209 |
embedding = embed_text(chunk)
|
| 210 |
try:
|
| 211 |
await asyncio.to_thread(
|
| 212 |
+
lambda c=chunk, e=embedding: supabase.table("documents").insert({
|
| 213 |
+
"content": c,
|
| 214 |
+
"embedding": e
|
| 215 |
+
}).execute()
|
| 216 |
)
|
| 217 |
except Exception as e:
|
| 218 |
logger.error(f"Failed to insert chunk into Supabase: {str(e)}")
|
|
|
|
| 221 |
"""Checks if the documents table has any records."""
|
| 222 |
try:
|
| 223 |
result = await asyncio.to_thread(
|
| 224 |
+
lambda: supabase.table("documents").select("id", count="exact").limit(1).execute()
|
| 225 |
)
|
| 226 |
return result.count == 0
|
| 227 |
except Exception as e:
|
|
|
|
| 235 |
query_embedding = embed_text(query)
|
| 236 |
try:
|
| 237 |
result = await asyncio.to_thread(
|
| 238 |
+
lambda qe=query_embedding, mc=match_count: supabase.rpc("match_documents", {
|
| 239 |
+
"query_embedding": qe,
|
| 240 |
+
"match_count": mc
|
| 241 |
}).execute()
|
| 242 |
)
|
| 243 |
return result.data
|
|
|
|
| 256 |
context_slice = context[:MAX_CONTEXT_LEN]
|
| 257 |
|
| 258 |
result = await asyncio.to_thread(
|
| 259 |
+
lambda: qa_pipeline(question=question, context=context_slice)
|
| 260 |
)
|
| 261 |
return result['answer']
|
| 262 |
except Exception as e:
|
|
|
|
| 372 |
db_status = "error"
|
| 373 |
try:
|
| 374 |
await asyncio.to_thread(
|
| 375 |
+
lambda: supabase.table("installations").select("team_id").limit(1).execute()
|
| 376 |
)
|
| 377 |
db_status = "ok"
|
| 378 |
except Exception as e:
|
|
|
|
| 390 |
scopes=["app_mentions:read", "files:read", "chat:write", "im:read", "im:write", "channels:read"]
|
| 391 |
)
|
| 392 |
# NOTE: The redirect_uri should match your Slack App config (e.g., https://yourspace.hf.space/slack/oauth/callback)
|
| 393 |
+
# If needed, add: redirect_uri=os.environ.get("SLACK_REDIRECT_URI")
|
| 394 |
url = generator.generate(state="state")
|
| 395 |
return {"install_url": url}
|
| 396 |
except Exception as e:
|
|
|
|
| 403 |
try:
|
| 404 |
response = await handler.handle_async(request)
|
| 405 |
# For successful OAuth, return a simple HTML response
|
| 406 |
+
if hasattr(response, 'status_code') and response.status_code == 200:
|
| 407 |
return HTMLResponse(
|
| 408 |
content="<html><body><h1>Installation successful!</h1><p>You can now use the bot in your Slack workspace.</p></body></html>",
|
| 409 |
status_code=200
|