Download main.py from Yuruyuruu/FastApi: direct link, hf CLI and curl.
- Browser
- Download file 4.89 kB
-
https://huggingface.co/spaces/Yuruyuruu/FastApi/resolve/main/main.py
- Command line
-
hf download hf://spaces/Yuruyuruu/FastApi/main.py
-
curl -L -o main.py https://huggingface.co/spaces/Yuruyuruu/FastApi/resolve/main/main.py
4.89 kB
| import os | |
| import re | |
| import requests | |
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| from typing import List, Optional | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from huggingface_hub import InferenceClient | |
| app = FastAPI(title="Yuyu - LibraryLuxe AI") | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # ================== CONFIG ================== | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| client = InferenceClient(api_key=HF_TOKEN) | |
| # Better model (try these in order) | |
| MODEL = "Qwen/Qwen2.5-7B-Instruct" # Best quality | |
| # MODEL = "mistralai/Mistral-7B-Instruct-v0.3" | |
| # MODEL = "microsoft/Phi-3.5-mini-instruct" | |
| # =========================================== | |
| class ChatHistoryItem(BaseModel): | |
| role: str | |
| content: str | |
| class ChatRequest(BaseModel): | |
| message: str | |
| history: List[ChatHistoryItem] = [] | |
| class BookEnrichment(BaseModel): | |
| title: Optional[str] = None | |
| author: Optional[str] = None | |
| cover_url: Optional[str] = None | |
| description: Optional[str] = None | |
| isbn: Optional[str] = None | |
| class ChatResponse(BaseModel): | |
| response: str | |
| book_data: Optional[BookEnrichment] = None | |
| # ================== MASTER LIBRARIAN KNOWLEDGE BASE ================== | |
| SYSTEM_PROMPT = """ | |
| You are Yuyu, the Master Librarian at LibraryLuxe. | |
| ### CORE RULES: | |
| - ALL prices and balances must be mentioned in MMK (Myanmar Kyat). | |
| - Use the 'Actual Library Plans' and 'User Context' provided in the message for precision. | |
| ### 1. MEMBERSHIP & SUBSCRIPTIONS | |
| - We have different plans (Basic, Premium, Basic yearly, Premium yearly.) with different book limits and prices. | |
| (Basic: maxed books=3, Borrow days=14 days, Premium: maxed books=5, Borrow days=21days) | |
| - Users can subscribe using their Wallet or other payment methods. | |
| - IMPORTANT: When a user subscribes, it might stay "Pending" until an Admin approves it. | |
| - To Renew/Upgrade: Go to the 'Membership' page and click 'Renew' or 'Upgrade'. | |
| ### 2. WALLET & PAYMENTS | |
| - Users have a digital Wallet. They can 'Top Up' money into it. | |
| - Wallet balance can be used to buy subscriptions instantly. | |
| - To Top Up: Go to the 'Wallet' section in the profile menu. | |
| ### 3. LOYALTY & REWARDS | |
| - Users earn 'Loyalty Points' for borrowing books and buying membership plans. | |
| - Points can be redeemed for 'Rewards' in 'Rewards' page. | |
| - To check points: Visit the 'Rewards' page. | |
| ### 4. BORROWING & RETURNS | |
| - Each plan has a 'Max Books' limit and 'Borrowing Days' limit. | |
| - To Return: Users must 'Request Return' from their 'My Books' page OR go to the library and return it. A librarian will then verify the physical return. | |
| - Overdue books might prevent new borrowings. | |
| ### 5. PERSONALITY & TONE | |
| - Be warm, helpful, and professional. | |
| - Use the user's name if provided. | |
| - ALWAYS use the 'Actual Library Plans' and 'User Context' provided in the message for precision. | |
| - If you don't know a specific detail about their account, ask them to check their 'Dashboard' or email aiyurina1610@gmail.com. | |
| Keep responses helpful but concise (max 2 paragraphs). | |
| """ | |
| def get_book_details(isbn: str) -> Optional[BookEnrichment]: | |
| try: | |
| url = f"https://openlibrary.org/api/books?bibkeys=ISBN:{isbn}&format=json&jscmd=data" | |
| resp = requests.get(url, timeout=6) | |
| data = resp.json() | |
| key = f"ISBN:{isbn}" | |
| if key in data: | |
| b = data[key] | |
| return BookEnrichment( | |
| title=b.get("title"), | |
| author=", ".join([a.get("name", "") for a in b.get("authors", [])]), | |
| cover_url=b.get("cover", {}).get("large"), | |
| description=b.get("notes") or b.get("description"), | |
| isbn=isbn | |
| ) | |
| except: | |
| pass | |
| return None | |
| def home(): | |
| return {"status": "online", "message": "Yuyu is ready!"} | |
| async def chat(request: ChatRequest): | |
| # Extract ISBN | |
| isbn_match = re.search(r"\b(?:97[89])?\d{9}[\dX]\b", request.message) | |
| book_data = get_book_details(isbn_match.group(0)) if isbn_match else None | |
| # Build messages | |
| messages = [{"role": "system", "content": SYSTEM_PROMPT}] | |
| # Add recent history | |
| for item in request.history[-6:]: | |
| messages.append({"role": item.role, "content": item.content}) | |
| messages.append({"role": "user", "content": request.message}) | |
| try: | |
| response = client.chat.completions.create( | |
| model=MODEL, | |
| messages=messages, | |
| max_tokens=450, | |
| temperature=0.75, | |
| top_p=0.9, | |
| ) | |
| ai_reply = response.choices[0].message.content.strip() | |
| except Exception as e: | |
| ai_reply = "I'm a bit overloaded right now... Please try again in a few seconds." | |
| return ChatResponse(response=ai_reply, book_data=book_data) |