makeitworks/Depressionmeters-api
0
1from fastapi import FastAPI, UploadFile, File, Form2from fastapi.responses import JSONResponse3from pydantic import BaseModel4from typing import List5from transformers import AutoTokenizer, AutoModelForSequenceClassification6import torch7import pandas as pd8from io import BytesIO9from huggingface_hub import snapshot_download10 11app = FastAPI()12 13# Unduh model dari Hugging Face Hub ke direktori sementara14snapshot_download("makeitworks/depression", local_dir="/tmp/my_model", local_dir_use_symlinks=False)15 16# Load tokenizer dan model17tokenizer = AutoTokenizer.from_pretrained("/tmp/my_model", trust_remote_code=True)18model = AutoModelForSequenceClassification.from_pretrained("/tmp/my_model", trust_remote_code=True)19 20# Gunakan GPU jika tersedia21device = torch.device("cuda" if torch.cuda.is_available() else "cpu")22model.to(device)23 24# Label klasifikasi25labels = ["Negatif (Depresi)", "Netral", "Positif"]26 27def predict_texts(texts: List[str]) -> List[str]:28 inputs = tokenizer(texts, return_tensors="pt", padding=True, truncation=True)29 inputs = {k: v.to(device) for k, v in inputs.items()}30 with torch.no_grad():31 outputs = model(**inputs)32 predictions = torch.argmax(outputs.logits, dim=1)33 return [labels[p] for p in predictions]34 35@app.get("/")36async def root():37 return {"message": "Welcome to the Depression Meter API!"}38 39@app.get("/version")40async def version():41 return {"version": "1.0.0"}42 43@app.post("/predict-text/")44async def predict_single_text(text: str = Form(...)):45 prediction = predict_texts([text])46 return {"text": text, "prediction": prediction[0]}47 48@app.post("/predict-file/")49async def predict_from_file(file: UploadFile = File(...)):50 if not file.filename.endswith((".xlsx", ".xls")):51 return JSONResponse(status_code=400, content={"error": "File harus format Excel (.xlsx/.xls)"})52 53 contents = await file.read()54 df = pd.read_excel(BytesIO(contents), engine='openpyxl')55 56 if df.empty:57 return JSONResponse(status_code=400, content={"error": "File tidak boleh kosong."})58 59 if "text" not in df.columns:60 return JSONResponse(status_code=400, content={"error": "Kolom 'text' tidak ditemukan dalam file."})61 62 texts = df["text"].tolist()63 predictions = predict_texts(texts)64 df["label"] = predictions65 66 negatif_count = df["label"].value_counts(normalize=True).get("Negatif (Depresi)", 0.0) * 10067 68 return {69 "total_texts": len(df),70 "persentase_depresi": f"{negatif_count:.2f}%",71 "results": df[["text", "label"]].to_dict(orient="records")72 }73 74class TextArray(BaseModel):75 texts: List[str]76 77@app.post("/predict-array/")78async def predict_from_array(data: TextArray):79 if not data.texts:80 return JSONResponse(status_code=400, content={"error": "List teks tidak boleh kosong."})81 82 predictions = predict_texts(data.texts)83 results = [{"text": t, "label": l} for t, l in zip(data.texts, predictions)]84 85 total = len(predictions)86 depresi_count = predictions.count("Negatif (Depresi)")87 persen_depresi = (depresi_count / total) * 100 if total > 0 else 088 89 return {90 "total": total,91 "persentase_depresi": f"{persen_depresi:.2f}%",92 "results": results93 }94 