An API is a programmatic way to interact with a webservice that allows us to automate the retrieval of data.
GET
POST
I used the httr2 R package to make HTTP requests to Cloudflare Workers AI Models endpoint
Function to generate story
get_story <-function(prompt,num_of_sentences =5,max_tokens =1000,ACCOUNT_ID =Sys.getenv("ACCOUNT_ID"),API_KEY =Sys.getenv("API_KEY"),base_url =cf_base_url()){if (is.null(prompt) | num_of_sentences <3){return(NULL) }if (test_profanity(prompt)){return(NULL) } url_txt <-paste0(base_url, ACCOUNT_ID, "/ai/run/@cf/meta/llama-3.1-8b-instruct")# Make an API request response_text <- httr2::request(url_txt) |> httr2::req_headers("Authorization"=paste("Bearer", API_KEY) ) |> httr2::req_body_json(list(max_tokens = max_tokens,messages =list(list(role ="system",content =paste0("You tell short stories. Each sentence must describe all details. Each story must have ", num_of_sentences, " sentences. The story must have a beginning, a climax and an end.")),list(role ="user",content = prompt ) ))) |> httr2::req_method("POST") |> httr2::req_error(is_error = \(resp) FALSE) |> httr2::req_perform() |> httr2::resp_body_json()# If response is successful, append it to the user prompt# clean it, and split the text into 5 sentencesif (isTRUE(response_text$success)){ full_text <- response_text$result$response #paste(prompt, response_text$result$response) cleaned_text <-gsub("\n", "", full_text) split_text <-unlist(strsplit(cleaned_text, "(?<=[.])\\s*(?=[A-Z])", perl =TRUE)) } else { split_text <-NULL }# c(prompt, split_text) split_text}
Test the function
new_story <-get_story(prompt ="There once was a prince in the land of Persia.",num_of_sentences =3)
Generates:
[1] "He wore a intricately designed golden crown, adorned with precious rubies and diamonds that caught the light of a full moon, and from the moment he was born, he was destined for greatness."[2] "On his seventh name-day, the prince rode his white stallion, Majdool, through the crowded market of Isfahan, where merchants in tunics and turbans waved in reverence as he passed by, their faces pressed against the walls of their stalls, watching the prince's stately procession."[3] "As he approached the grand square, the prince's horse let out a high-pitched whinny, and the prince's mother, the queen, gently corrected the animal with a soft voice, though her eyes were fixed adoringly on her son."
image_prompt <-"This scene should be illustrated ..."reqs <-lapply( new_story,function(x){req_single_image(x, image_prompt) })resps <- httr2::req_perform_parallel(reqs, on_error ="continue")# All imagesnew_all_imgs <-lapply(resps, get_image)
Step 3: Creating Slides
Quarto is a new, open-source, scientific and technical publishing system
Quarto
An open-source scientific and technical publishing system
I used parameters in the quarto file and the quarto R package.
Quarto file (.qmd)
YAML options (instructions):
---title:"stoRy time with shiny and quarto"author:"A story written by you & AI"format: revealjs: embed-resources: true center: true transition: slide background-transition: fadeparams: story_prompt:"" story:"" imgs:""---"<Use story and images here for creating slides>"
A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another.
Dockerfile
For an example shiny app:
# Base R Shiny imageFROM rocker/shiny# Make a directory in the containerRUN mkdir /home/shiny-app# Install R dependenciesRUN R -e "install.packages(c('dplyr', 'ggplot2', 'gapminder'))"# Copy the Shiny app codeCOPY app.R /home/shiny-app/app.R# Expose the application portEXPOSE 8180# Run the R Shiny appCMD Rscript /home/shiny-app/app.R