285 lines
9.9 KiB
Python
285 lines
9.9 KiB
Python
# Menggunakan Huggingface
|
|
# from fastapi import FastAPI, HTTPException
|
|
# from fastapi.middleware.cors import CORSMiddleware
|
|
# from huggingface_hub import InferenceClient
|
|
# import random
|
|
# import logging
|
|
|
|
# app = FastAPI()
|
|
|
|
# app.add_middleware(
|
|
# CORSMiddleware,
|
|
# allow_origins=["*"],
|
|
# allow_credentials=True,
|
|
# allow_methods=["*"],
|
|
# allow_headers=["*"],
|
|
# )
|
|
|
|
# # Logging setup
|
|
# logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
|
|
|
# # Token Hugging Face (gunakan .env di production)
|
|
# HF_TOKEN = "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"
|
|
# #meta-llama/Llama-2-7b-chat-hf
|
|
# #meta-llama/Llama-3.2-3B-Instruct
|
|
# client = InferenceClient(model="meta-llama/Llama-3.2-3B-Instruct", token=HF_TOKEN)
|
|
|
|
# data_sources = {
|
|
# "cerita": {
|
|
# "Malin Kundang": "Malin Kundang adalah seorang anak dari keluarga miskin yang menjadi kaya raya namun menolak mengakui ibunya, hingga akhirnya dikutuk menjadi batu.",
|
|
# "Bawang Merah Bawang Putih": "Bawang Putih adalah gadis baik hati yang diperlakukan buruk oleh ibu dan saudara tirinya, tetapi kebaikannya membuahkan hasil berkat ikan ajaib.",
|
|
# "Sangkuriang": "Sangkuriang jatuh cinta pada ibunya, Dayang Sumbi, dan diberi tugas mustahil untuk membangun perahu dalam satu malam. Ia gagal dan akhirnya marah, menendang perahu hingga menjadi Gunung Tangkuban Perahu.",
|
|
# "Si Kancil": "Si Kancil dengan kecerdikannya berhasil menipu buaya untuk menyeberangi sungai dengan aman.",
|
|
# "Timun Mas": "Seorang ibu tua mendapatkan anak dari biji timun emas. Namun, anak itu harus melarikan diri dari raksasa jahat yang ingin memakannya."
|
|
# },
|
|
# "pantun": {
|
|
# "Pantun Nasihat": "Jalan-jalan ke kota Blitar,\nJangan lupa membeli roti.\nRajin belajar sejak pintar,\nAgar sukses di kemudian hari.",
|
|
# "Pantun Jenaka": "Ke pasar beli ikan teri,\nIkan habis tinggal kepala.\nJangan suka mencuri,\nNanti ketahuan malah celaka."
|
|
# },
|
|
# "puisi": {
|
|
# "Puisi Alam": "Langit biru membentang luas,\nBurung-burung terbang bebas.\nAngin sepoi menyapu dedaunan,\nAlam indah penuh kedamaian.",
|
|
# "Puisi Persahabatan": "Sahabat sejati selalu ada,\nDalam suka dan dalam duka.\nBersama kita jalani hari,\nMengukir cerita tak terlupa."
|
|
# }
|
|
# }
|
|
|
|
# @app.post("/generate/")
|
|
# async def generate_text():
|
|
# try:
|
|
# selected_stories = random.sample(list(data_sources["cerita"].keys()), 3)
|
|
# selected_pantun = random.choice(list(data_sources["pantun"].keys()))
|
|
# selected_puisi = random.choice(list(data_sources["puisi"].keys()))
|
|
|
|
# story_prompts = "\n\n".join([
|
|
# f"Judul: {story}\nIsi:\n{data_sources['cerita'][story]}"
|
|
# for story in selected_stories
|
|
# ])
|
|
|
|
# pantun_prompt = f"Judul: {selected_pantun}\nIsi:\n{data_sources['pantun'][selected_pantun]}"
|
|
# puisi_prompt = f"Judul: {selected_puisi}\nIsi:\n{data_sources['puisi'][selected_puisi]}"
|
|
|
|
# full_prompt = f"""
|
|
# Kamu adalah asisten pengajar untuk siswa SD kelas 3. Berdasarkan teks di bawah ini, buat soal untuk latihan siswa.
|
|
|
|
# **Instruksi:**
|
|
# 1. Untuk setiap teks (cerita, pantun, puisi), tampilkan:
|
|
# - Judul
|
|
# - Isi lengkap teks
|
|
# - 1 soal pilihan ganda (A-D) beserta jawaban benar dalam format: Jawaban Benar: X
|
|
# - 1 soal isian beserta jawaban ideal dalam format: Jawaban Ideal: [isi jawaban])
|
|
# 2. Gunakan bahasa sederhana dan mudah dipahami siswa SD kelas 3.
|
|
# 3. Gunakan format seperti contoh ini:
|
|
|
|
# ---
|
|
|
|
# Judul: [judul]
|
|
# Isi:
|
|
# [isi teks]
|
|
|
|
# **Soal Pilihan Ganda:**
|
|
# 1. [pertanyaan]
|
|
# A. ...
|
|
# B. ...
|
|
# C. ...
|
|
# D. ...
|
|
# Jawaban Benar: X
|
|
|
|
# **Soal Isian:**
|
|
# [pertanyaan]
|
|
# Jawaban Ideal: [isi jawaban]
|
|
|
|
# ---
|
|
|
|
# **TEKS CERITA:**
|
|
# {story_prompts}
|
|
|
|
# **TEKS PANTUN:**
|
|
# {pantun_prompt}
|
|
|
|
# **TEKS PUISI:**
|
|
# {puisi_prompt}
|
|
|
|
# Jangan gabungkan semua soal jadi satu bagian. Setiap teks harus punya blok tersendiri seperti format di atas.
|
|
# """
|
|
|
|
# logging.info("Mengirim prompt ke Hugging Face...")
|
|
# response = client.text_generation(full_prompt, max_new_tokens=1000)
|
|
# generated_text = response.strip()
|
|
|
|
# if not generated_text:
|
|
# raise HTTPException(status_code=500, detail="Model tidak menghasilkan pertanyaan.")
|
|
|
|
# return {
|
|
# "selected_stories": [
|
|
# {
|
|
# "title": story,
|
|
# "content": data_sources["cerita"][story]
|
|
# } for story in selected_stories
|
|
# ],
|
|
# "selected_pantun": {
|
|
# "title": selected_pantun,
|
|
# "content": data_sources["pantun"][selected_pantun]
|
|
# },
|
|
# "selected_puisi": {
|
|
# "title": selected_puisi,
|
|
# "content": data_sources["puisi"][selected_puisi]
|
|
# },
|
|
# "generated_questions": generated_text
|
|
# }
|
|
|
|
# except Exception as e:
|
|
# logging.error(f"Error saat generate: {e}")
|
|
# raise HTTPException(status_code=500, detail=f"Terjadi kesalahan: {str(e)}")
|
|
|
|
|
|
# Menggunakan Groq
|
|
from fastapi import FastAPI, HTTPException, Query
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from groq import Groq
|
|
import random
|
|
import logging
|
|
from pydantic import BaseModel
|
|
from difflib import SequenceMatcher
|
|
|
|
app = FastAPI()
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Logging setup
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
|
|
|
# Langsung masukkan API Key Groq di sini
|
|
client = Groq(api_key="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")
|
|
|
|
data_sources = {
|
|
"cerita": {
|
|
"Malin Kundang": "Pada zaman dahulu, hiduplah seorang anak bernama Malin Kundang...",
|
|
"Bawang Merah Bawang Putih": "Bawang Merah selalu iri dengan kebaikan Bawang Putih...",
|
|
"Timun Mas": "Timun Mas adalah seorang gadis pemberian raksasa kepada seorang petani..."
|
|
},
|
|
"pantun": {
|
|
"Pantun Pendidikan": "Belajar pagi membaca buku,\nSiang datang janganlah lesu,\nMenuntut ilmu jangan jemu,\nAgar sukses di masa depanmu."
|
|
},
|
|
"puisi": {
|
|
"Puisi Alam": "Langit biru terbentang luas,\nGunung tinggi menjulang tegas,\nHijau daun menari bebas,\nAlam indah ciptaan yang cerdas."
|
|
}
|
|
}
|
|
|
|
@app.post("/generate/") # Endpoint untuk generate soal
|
|
async def generate_text():
|
|
try:
|
|
selected_stories = random.sample(list(data_sources["cerita"].keys()), 3)
|
|
selected_pantun = random.choice(list(data_sources["pantun"].keys()))
|
|
selected_puisi = random.choice(list(data_sources["puisi"].keys()))
|
|
|
|
story_prompts = "\n\n".join([f"Judul: {story}\nIsi:\n{data_sources['cerita'][story]}" for story in selected_stories])
|
|
pantun_prompt = f"Judul: {selected_pantun}\nIsi:\n{data_sources['pantun'][selected_pantun]}"
|
|
puisi_prompt = f"Judul: {selected_puisi}\nIsi:\n{data_sources['puisi'][selected_puisi]}"
|
|
|
|
full_prompt = f"""
|
|
Kamu adalah asisten pengajar untuk siswa SD kelas 3. Berdasarkan teks di bawah ini, buat soal untuk latihan siswa.
|
|
|
|
**Instruksi:**
|
|
1. Untuk setiap teks (cerita, pantun, puisi), tampilkan:
|
|
- Judul
|
|
- Isi lengkap teks
|
|
- 1 soal pilihan ganda (A-D) beserta jawaban benar dalam format: Jawaban Benar: X
|
|
- 1 soal isian beserta jawaban ideal dalam format: Jawaban Ideal: [isi jawaban])
|
|
2. Gunakan bahasa sederhana dan mudah dipahami siswa SD kelas 3.
|
|
3. Gunakan format seperti contoh ini:
|
|
|
|
---
|
|
|
|
Judul: [judul]
|
|
Isi:
|
|
[isi teks]
|
|
|
|
**Soal Pilihan Ganda:**
|
|
1. [pertanyaan]
|
|
A. ...
|
|
B. ...
|
|
C. ...
|
|
D. ...
|
|
Jawaban Benar: X
|
|
|
|
**Soal Isian:**
|
|
[pertanyaan]
|
|
Jawaban Ideal: [isi jawaban]
|
|
|
|
---
|
|
|
|
**TEKS CERITA:**
|
|
{story_prompts}
|
|
|
|
**TEKS PANTUN:**
|
|
{pantun_prompt}
|
|
|
|
**TEKS PUISI:**
|
|
{puisi_prompt}
|
|
|
|
Jangan gabungkan semua soal jadi satu bagian. Setiap teks harus punya blok tersendiri seperti format di atas.
|
|
"""
|
|
|
|
logging.info("Mengirim prompt ke Groq LLaMA-3.1-8b-instant...")
|
|
|
|
completion = client.chat.completions.create(
|
|
model="llama-3.1-8b-instant",
|
|
messages=[{"role": "user", "content": full_prompt}],
|
|
temperature=0.7,
|
|
max_tokens=1000
|
|
)
|
|
|
|
generated_text = completion.choices[0].message.content.strip()
|
|
|
|
return {
|
|
"selected_stories": [{"title": story, "content": data_sources["cerita"][story]} for story in selected_stories],
|
|
"selected_pantun": {"title": selected_pantun, "content": data_sources["pantun"][selected_pantun]},
|
|
"selected_puisi": {"title": selected_puisi, "content": data_sources["puisi"][selected_puisi]},
|
|
"generated_questions": generated_text
|
|
}
|
|
|
|
except Exception as e:
|
|
logging.error(f"Error saat generate: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Terjadi kesalahan: {str(e)}")
|
|
|
|
class FeedbackRequest(BaseModel):
|
|
user_answer: str
|
|
expected_answer: str
|
|
|
|
@app.post("/generate-feedback/")
|
|
async def generate_feedback(request: FeedbackRequest):
|
|
try:
|
|
user_answer = request.user_answer.strip()
|
|
expected_answer = request.expected_answer.strip()
|
|
|
|
prompt = f"""
|
|
Kamu adalah asisten pengajar untuk siswa SD kelas 3. Siswa memberikan jawaban berikut untuk soal isian.
|
|
|
|
**Jawaban Siswa:** {user_answer}
|
|
**Jawaban Ideal:** {expected_answer}
|
|
|
|
Beri feedback singkat dan membangun, maksimal 2 kalimat. Gunakan bahasa yang mudah dimengerti oleh siswa SD. Jika jawaban siswa salah, berikan petunjuk atau koreksi yang membantu.
|
|
"""
|
|
|
|
logging.info("Mengirim prompt feedback ke Groq...")
|
|
|
|
completion = client.chat.completions.create(
|
|
model="llama-3.1-8b-instant",
|
|
messages=[{"role": "user", "content": prompt}],
|
|
temperature=0.7,
|
|
max_tokens=150
|
|
)
|
|
|
|
feedback = completion.choices[0].message.content.strip()
|
|
|
|
return {"feedback": feedback}
|
|
|
|
except Exception as e:
|
|
logging.error(f"Error saat generate feedback: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Terjadi kesalahan: {str(e)}")
|