Spaces:
Runtime error
Runtime error
| import os | |
| import io | |
| import base64 | |
| import json | |
| import datetime | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel | |
| from google.oauth2.service_account import Credentials | |
| from googleapiclient.discovery import build | |
| from googleapiclient.http import MediaIoBaseUpload | |
| import qrcode | |
| app = FastAPI() | |
| # Allow frontend (your InfinityFree domain) to call API | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], # Restrict to your domain in production | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Load secrets from environment (set in Hugging Face Secrets) | |
| SHEET_ID = os.getenv("GOOGLE_SHEET_ID") | |
| FOLDER_ID = os.getenv("GOOGLE_DRIVE_FOLDER_ID") | |
| SERVICE_ACCOUNT_INFO = json.loads(os.getenv("GOOGLE_SERVICE_ACCOUNT_JSON")) | |
| def get_services(): | |
| creds = Credentials.from_service_account_info( | |
| SERVICE_ACCOUNT_INFO, | |
| scopes=[ | |
| "https://www.googleapis.com/auth/drive.file", | |
| "https://www.googleapis.com/auth/spreadsheets" | |
| ] | |
| ) | |
| drive = build("drive", "v3", credentials=creds) | |
| sheets = build("sheets", "v4", credentials=creds) | |
| return drive, sheets | |
| class CertRequest(BaseModel): | |
| pdfBase64: str # base64 encoded PDF | |
| fileName: str # e.g., "John_Doe_certificate.pdf" | |
| name: str | |
| email: str = "" # optional, for future | |
| code: str # 9-character verification code | |
| async def upload_certificate(req: CertRequest): | |
| try: | |
| drive, sheets = get_services() | |
| # Decode PDF | |
| pdf_bytes = base64.b64decode(req.pdfBase64) | |
| media = MediaIoBaseUpload(io.BytesIO(pdf_bytes), mimetype='application/pdf', resumable=False) | |
| # Upload to Drive | |
| file = drive.files().create( | |
| body={'name': req.fileName, 'parents': [FOLDER_ID]}, | |
| media_body=media, | |
| fields='id,webViewLink' | |
| ).execute() | |
| # Make it publicly viewable (anyone with link can view) | |
| drive.permissions().create( | |
| fileId=file['id'], | |
| body={'type': 'anyone', 'role': 'reader'} | |
| ).execute() | |
| # Append record to Google Sheet | |
| now = datetime.datetime.now().isoformat() | |
| values = [[ | |
| now, | |
| req.name, | |
| req.email, | |
| req.code, | |
| file['id'], | |
| file['webViewLink'], | |
| 'active' | |
| ]] | |
| sheets.spreadsheets().values().append( | |
| spreadsheetId=SHEET_ID, | |
| range='Certificates!A:G', # Assumes headers in row 1 | |
| valueInputOption='USER_ENTERED', | |
| body={'values': values} | |
| ).execute() | |
| return {"success": True, "fileUrl": file['webViewLink']} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def verify(code: str): | |
| try: | |
| _, sheets = get_services() | |
| result = sheets.spreadsheets().values().get( | |
| spreadsheetId=SHEET_ID, | |
| range='Certificates!A:G' | |
| ).execute() | |
| rows = result.get('values', []) | |
| # Skip header row | |
| for row in rows[1:]: | |
| if len(row) >= 4 and row[3] == code: | |
| return { | |
| "valid": True, | |
| "name": row[1], | |
| "date": row[0], | |
| "fileUrl": row[5] | |
| } | |
| return {"valid": False} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def health(): | |
| return {"status": "ok"} |