Aflați cum să construiți o bancă de întrebări în stil flash-card folosind Google Sheets ca stocare, API-ul instalației R și să o găzduiți pe o picătură digitală oceanică-configurare, implementare și sfaturi.
Motivații
Unul dintre colegii mei a dorit să creeze o întrebare cumulată pentru a -i ajuta pe elevii noștri în subiectul bolii infecțioase și această idee mi -a apărut în cap. De ce nu folosim Google Sheet pentru un loc în care putem stoca întrebările și răspunsurile, apoi avem o altă platformă pentru a găzdui asta? Există multe modalități de a face acest lucru, dar cred că cel mai puțin întrerupt mod (schimbarea unui lucru nu va afecta celelalte părți) este să aveți Google Sheet ca un sistem de stocare, instalator ca API și o picătură digitală pentru ocean pentru a o găzdui! Acesta este un tutorial pas cu pas în crearea unuia.
Obiective:
Sfârșitul în minte
Deci, ceea ce vrem să realizăm la sfârșit este un site în care putem avea un fel de întrebări de studiu a timpului de card flash. În cazul în care avem o întrebare simplă și butonul A pentru a face clic pentru a dezvălui răspunsul, un buton pentru a merge la următoarea întrebare, pentru a sorta la întâmplare întrebările, ca așa …
Dacă sunteți familial cu R sau alte limbaje de programare, toate acestea ar trebui să aibă sens pentru dvs. Dacă nu, este posibil să fie nevoie să înveți un pic de R și unele cunoștințe de codificare. Partea cea mai bună este că acum puteți utiliza LLM pentru a vă ajuta (de exemplu, explicați codul, remediați codul, învățarea codului etc). Rețineți, de asemenea, că unii dintre pași vor necesita o formă de înregistrare și plată (de exemplu, cel mai ieftin ~ 5 $/lună), în special atunci când vine vorba de digitale și contul de ocean digital. Iată, așadar, o listă de instrumente de care aveți nevoie:
Patience & persistence
dacă nu știți cum să codificați (îmi pare rău, acest tutorial este destinat celor care știu deja și au instalat R). Acest lucru se poate aplica și celor care știu să codeze, dar nu sunt familiarizați cu instalatorul sau oceanul digital.Some coding
sau cel puținlots of copy and pasting
- Familiar cu
Google Sheet
- Instalat
R
,plumber
au undigital ocean
cont (dacă nu creați unul) - Au unele
ssh
,bash
cunoştinţe - Familiar cu
HTML
şiCSS
(opțional, dar util) - Ultimul, dar nu cel din urmă,
Be very good with using LLM to help you
Stabiliți -vă întrebările
Pentru a vă configura întrebările, puteți utiliza Google Sheet. Ca așa:
Acesta este doar un exemplu. Rețineți că avem 5 coloane aici. După ce ați creat această foaie Google, asigurați -vă că faceți clic pe Share și schimbați accesul la „Oricine cu linkul poate vizualiza”. Acest lucru este important, deoarece vom folosi acest link pentru a accesa datele din API -ul nostru de instalator. Ca așa:
Apoi copiați linkul și al nostru sheet ID
este între /d/
şi /edit
. În acest caz, ID -ul nostru arată așa 1iDup4-23ir8Faos2Ml_hvWiWYQGv73aLs7NmhjWDxz9
(FYI, acesta nu este un ID real). Salvați acest ID pentru mai târziu.
Proparare și chestii HTML
Acum trebuie să creăm o API de instalator. Dacă nu știți ce este instalatorul, este un pachet R care vă permite să creați API -uri folosind R. Puteți citi mai multe despre el aici.
Pentru a crea o API de instalator, trebuie să creați un nou fișier R Script (de exemplu, api.R
) și adăugați următorul cod:
instalator.R
library(plumber) library(googlesheets4) library(dplyr) # Disable authentication for public sheets gs4_deauth() # Configuration SHEET_ID <- "1iDup4-23ir8Faos2Ml_hvWiWYQGv73aLs7NmhjWDxz9" #### <- this is your google sheet ID # Global variables for caching questions_cache <- NULL last_fetch_time <- 0 cache_duration <- 5 * 60 # 5 minutes in seconds # Function to fetch questions from Google Sheets fetch_questions_from_sheet <- function() { tryCatch({ sheet_data <- read_sheet(SHEET_ID, range = "A2:E100", col_names = FALSE) # Set column names names(sheet_data) <- c("question", "answer", "reference", "image_url", "tag") # Clean and process data questions <- sheet_data %>% filter(!is.na(question) & !is.na(answer) & question != "" & answer != "") %>% mutate( id = row_number(), question = as.character(question), answer = as.character(answer), reference = ifelse(is.na(reference), "", as.character(reference)), image_url = ifelse(is.na(image_url), "", as.character(image_url)), tag = ifelse(is.na(tag), "general", as.character(tag)) ) %>% select(id, question, answer, reference, image_url, tag) # Update cache questions_cache <<- questions last_fetch_time <<- as.numeric(Sys.time()) cat("Successfully loaded", nrow(questions), "questions\n") return(questions) }, error = function(e) { cat("Error loading from Google Sheets:", e$message, "\n") # Return empty data frame with correct structure return(data.frame( id = integer(0), question = character(0), answer = character(0), reference = character(0), image_url = character(0), tag = character(0), stringsAsFactors = FALSE )) }) } # Function to get questions with caching get_questions <- function() { current_time <- as.numeric(Sys.time()) if (is.null(questions_cache) || (current_time - last_fetch_time) > cache_duration) { return(fetch_questions_from_sheet()) } return(questions_cache) } #* Enable CORS #* @filter cors cors <- function(req, res) { res$setHeader("Access-Control-Allow-Origin", "*") res$setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") res$setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization") if (identical(req$REQUEST_METHOD, "OPTIONS")) { res$status <- 200 return(list()) } else { plumber::forward() } } #* Get all questions (shuffled) #* @get /api/questions/all function() { tryCatch({ cat("API call received for all questions\n") questions <- get_questions() cat("Retrieved", nrow(questions), "questions\n") if (nrow(questions) == 0) { cat("No questions found\n") return(list( success = FALSE, error = "No questions found" )) } # Shuffle the questions shuffled_questions <- questions(sample(nrow(questions)), ) # Convert to list format questions_list <- lapply(1:nrow(shuffled_questions), function(i) { q <- shuffled_questions(i, ) list( id = as.numeric(q$id), question = as.character(q$question), answer = as.character(q$answer), reference = ifelse(is.na(q$reference) || q$reference == "", "", as.character(q$reference)), image_url = ifelse(is.na(q$image_url) || q$image_url == "", "", as.character(q$image_url)), tag = as.character(q$tag) ) }) result <- list( success = TRUE, data = questions_list, total = length(questions_list) ) cat("Returning", length(questions_list), "shuffled questions\n") return(result) }, error = function(e) { cat("Error in all questions endpoint:", e$message, "\n") return(list( success = FALSE, error = paste("Server error:", e$message) )) }) } #* Serve the main HTML page #* @get / #* @serializer html function() { readLines("public/index.html", warn = FALSE) %>% paste(collapse = "\n") } #* Serve CSS file #* @get /styles.css #* @serializer contentType list(type="text/css") function() { readLines("public/styles.css", warn = FALSE) %>% paste(collapse = "\n") } # Cache will be initialized on first API call
Pasul 1: Salvați cele de mai sus ca plumber.R
.
qbank_api.r
#!/usr/bin/env Rscript library(plumber) HOST <- "0.0.0.0" PORT <- 8000 cat("Starting Plumber API...\n") cat("Available at: http://localhost:", PORT, "\n\n") # Create API from plumber.R file api <- plumber::plumb("plumber.R") api$run(host = HOST, port = PORT)
Pasul 2: Salvați codul de mai sus ca qbank_api.R
.
Pasul 3: Creați un folder numit public
și creați două fișiere în el:
index.html
şi
styles.css
.
Pasul 4: rulați qbank_api.R
în consola dvs. R. Acest lucru va începe API -ul instalatorului și ar trebui să vedeți așa ceva:
Pasul 5: accesați browserul și navigatorul la http://0.0.0.0:8000/
sau http://localhost:8000/
. Ar trebui să vedeți o simplă pagină HTML, la fel ca ceea ce am văzut în finalul nostru
Dacă ați ajuns aici și totul funcționează, felicitări! Ați creat o API pentru banca de întrebări la nivel local! Acum, dacă doriți acces la el de oriunde, trebuie să îl găzduiți undeva. Dacă nu aveți nevoie de asta (sunteți bine cu banca de întrebări găzduite local), atunci ați terminat! 🙌
Găzduiește -l cu oceanul digital
Aceasta este partea care poate fi puțin frustrantă să fiu sincer. Sper să ofer un ghid pas cu pas aici. Aceasta este, de asemenea, o modalitate pentru mine să iau notă pentru ca viitorul să mă refer. Lucrurile se actualizează tot timpul, până când citiți acest lucru, lucrurile s -ar putea să nu se mai aplice, iar picăturile pe care am creat -o pentru demo ar fi fost distrusă, dar să dăm tot ce este mai bun!
Pasul 1. Creați un cont digital ocean: Dacă nu aveți unul, mergeți la Digital Ocean și creați un cont. Este posibil să fie nevoie să adăugați o metodă de plată.
Pasul 2.
- Creați un proiect: După conectarea, creați un nou proiect. Îl poți numi ceva de genul „Bank de întrebări” sau orice îți place.
- Creați o picătură: Du -te la
create
apoi faceți clic pedroplet
. Alegeți următoarele opțiuni:- Regiunea centrului de date: Alege o regiune aproape de tine.
- Imagine: Alege
Ubuntu 22.04 (LTS) x64
(Acest lucru este important !!! Nu am reușit să instalez R cu ubbuntu 24) - Plan: Alegeți cel mai ieftin (de exemplu,
Basic
Plan cu 1 GB RAM)
- Autentificare: Utilizați tastele SSH dacă le aveți configurate sau utilizați o parolă. Parola poate fi cea mai ușoară pentru un starter
- Finalizați și creați: Faceți clic pe
Create Droplet
.
Vei vedea apoi așa ceva:
Pasul 3. Conectați -vă la picătura dvs.:
Pasul 4. Instalați R și instalator:
# install R, dependencies, libraries sudo apt update sudo apt install r-base r-base-dev sudo apt install -y libcurl4-openssl-dev libssl-dev libxml2-dev libsodium-dev libfontconfig1-dev libharfbuzz-dev libfribidi-dev libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev build-essential libgit2-dev libssh2-1-dev Rscript -e "install.packages(c('tidyverse', 'plumber', 'rvest', 'googlesheets4'), repos='https://cran.rstudio.com/', dependencies=TRUE)"
Copiați și lipiți cele de mai sus în terminalul dvs. după ce ați fost ssh-ed în picăturile dvs. Atenție că acest lucru poate dura cândva, de asemenea, unele intrări manualeîn așteptarea acestora, vă rugăm să nu ezitați să mergeți la pasul 5 pentru a încărca fișierele necesare
De asemenea, luați notă, că, dacă aveți probleme de instalare a celor de mai sus, s -ar putea să fi rămas fără spațiu RAM sau pe disc. Puteți verifica spațiul pe disc cu df -h
și Ram cu free -h
. Dacă ați rămas fără spațiu, este posibil să fie necesar să redimensionați picăturile sau să ștergeți unele fișiere.
Pasul 5. Încărcați fișierele dvs.:
- Utilizare
sftp
saufilezilla
pentru a încărca fișierele. Mai jos este un exemplu de utilizaresftp
:
sftp root@your_droplet_ip_address sftp> put qbank_api.R sftp> put plumber.R sftp> put public/index.html sftp> put public/styles.css sftp> exit
Asigurați -vă că calea către fișier este specificată corect.
Iată un link către ZIP pentru toate fișierele de care aveți nevoie pentru a obține un produs viabil minim. 🤞
- Dacă utilizați
filezilla
puteți trage și arunca fișierele în directorul de origine al picăturii. Asigurați -vă că fișierele sunt în același director caplumber.R
şiqbank_api.R
.
Pasul 6. Rulează API -ul:
sudo nano /etc/systemd/system/qbank-api.service (Unit) Description=QBank API Service After=network.target (Service) Type=simple User=root WorkingDirectory=/home/idqbank/ ExecStart=/usr/bin/Rscript qbank_api.R Restart=always RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=qbank-api (Install) WantedBy=multi-user.target
Ia notă pe WorkingDirectory
şi ExecStart
linii. Trebuie să schimbați calea către locul în care v -ați încărcat fișierele. De exemplu, dacă ați încărcat fișierele dvs. /home/your_username/qbank/
atunci trebuie să vă schimbați WorkingDirectory=/home/idqbank/
la WorkingDirectory=/home/your_username/qbank/
şi ExecStart=/usr/bin/Rscript qbank_api.R
la ExecStart=/usr/bin/Rscript /home/your_username/qbank/qbank_api.R
.
# Reload systemd to recognize the new service sudo systemctl daemon-reload # Enable the service to start on boot sudo systemctl enable qbank-api.service # Start the service now sudo systemctl start qbank-api.service
Acest lucru va crea un serviciu SystemD care va rula API -ul dvs. în fundal. Doriți să vă asigurați dacă picăturile repornește din anumite motive, doriți ca API -ul dvs. să repornească automat. Prin urmare, pasul de mai sus este important.
Pasul 7. Verificați dacă API -ul funcționează:
sudo systemctl status qbank-api.service
Ar trebui să vezi așa ceva:
Pasul 8. Accesați API -ul dvs.: Acum puteți accesa API -ul dvs. de oriunde! Du -te doar la http://your_droplet_ip_address:8000/
în browserul tău. Ar trebui să vedeți aceeași pagină HTML ca înainte. Asigurați -vă că includeți port
Ai specificat în qbank_api.R
fișier (de exemplu, 8000
) Nu va funcționa cu setarea curentă dacă nu.
Dacă sunteți interesat să eliminați numărul portului, puteți configura un proxy invers folosind Nginx
. Acest lucru este ceva mai avansat și dincolo de sfera de aplicare a acestui tutorial, dar puteți găsi multe tutoriale online despre cum să faceți asta.
Rețineți că folosim http
nu https
. Ceea ce înseamnă că nu avem încă o conexiune sigură. Dacă doriți să aveți o conexiune sigură, trebuie să configurați un certificat SSL. Nu vom trece prin asta pe acest blog.
Asta este! Dacă ai ajuns până acum, felicitări! 👏 Ați creat cu succes o bancă de întrebări folosind Google Shey, Instalație și Digital Ocean Proplet. Acum puteți adăuga mai multe întrebări pe foaia dvs. Google și acestea vor fi disponibile automat în API -ul dvs., după 5 minutes
de schimbări.
Sfaturi
Dacă ați folosit deja LLM (de exemplu, Chatgpt, Claude, Gemini etc), fantastic! Dacă nu ați făcut -o, vă recomand cu mare drag să o utilizați pentru a vă ajuta cu codificarea, depanarea și învățarea. Iată câteva sfaturi:
Explaination
: Toate acestea îți par străine? Copiați și lipiți în LLM și întrebațiexplain this code to me
Follow up on it
: Dacă încă nu înțelegeți ceva, cereți LLM să -l explice mai departe.Debugging
: Dacă aveți o eroare, copiați și lipiți mesajul de eroare în LLM și întrebațiwhat does this error mean?
sauhow do I fix this error?
Screen Caputure
: Încă nu este sigur? Capturați ecranului ceea ce vedeți, atașați o poză pe LLM și întrebați!Fetch URL
: Confuz cu ceea ce am scris aici? Lipiți această adresă URL și întrebațiwhat does this blog mean?
sauhow do I do this?
- Interesat în
SSL cert
şinginx
proxy invers? Rugați -l pe LLM să vă explice sau să întrebațihow do I set up SSL certificate for my droplet?
sauhow do I set up nginx reverse proxy for my droplet?
. Having the end in mind helps
: Asigurați -vă că rulează local înainte de a -l găzdui. Dacă nu rulează la nivel local, nu va rula pe server.
Oportunități de îmbunătățire și alte idei
- Cu siguranță trebuie să creați certificat SSL pentru o conexiune securizată. Puteți utiliza Let’s Encrypt pentru a crea un certificat SSL gratuit.
- Aceasta nu trebuie să fie o bancă de întrebări. Ce zici de fabrica de idei? Tabloul de bord de un fel? Metrici? Okr? Folosește -ți imaginația!
Lecții învățate
- Încercat pe picături multipel pentru a instala R, dar numai Ubuntu 22.04 funcționează deocamdată.
- Dacă aveți probleme de instalare R, s -ar putea să fi rămas fără spațiu RAM sau pe disc.
Dacă vă place acest articol: