In this article, I’m going to illustrate my experience building a real time recommendation system with the help of Palm2 LLM model , TMDB API and Streamlit.
My goal is to talk about how to design a movie recommendation system using integration of multiple API’s and components.
This blog is written guide for following youtube video 🎥. Like👍 the video and subscribe to the channel . So let’s get started 😊.
What is PaLM 2 Large Language Model API ?
Large Language Models (LLMs) are a powerful, versatile type of machine learning model that enables computers to comprehend and generate natural language better than ever. They can be used to build all sorts of applications, from chat bots to virtual assistants to translation apps and much more. Plus, you don’t have to be an AI expert or even write code to use them. All it takes are a few sentences or “prompts” to get started designing your own custom LLM app.
The PaLM API is based on Google’s next generation model, PaLM 2, which excels at a variety of capabilities. PaLM 2 has been optimized for ease of use on key developer use cases and the ability to follow instructions with precision and nuance. It has variations that are trained for text and chat generation as well as text embeddings. This guide provides information about each variation to help you decide which is the best fit for your use case.
You can join waitlist to get your API key via MakerSuite and start prototyping quickly .
What is TMDB API ?
The Movie Database (TMDB) is a community built movie and TV database. Every piece of data has been added by the amazing community dating back to 2008.
Steps to get API key for TMDB API :
- Create account on TMDB website (https://www.themoviedb.org/) or log in if you already have an account.
- Go to profile settings page .
- Go to API tab ( https://www.themoviedb.org/settings/api ) . You will find your API key and API read access token . We are going to use API read access token for our project .
- You can find more details about how we can use TMDB API and it’s endpoints at https://developer.themoviedb.org/docs 😎.
Little bit about Streamlit 🔥
Streamlit (https://streamlit.io/) is an open-source Python library that makes it easy to create and share beautiful, custom web apps for machine learning and data science. In just a few minutes you can build and deploy powerful data apps
You can find more details about how to use streamlit at official documentation .
You can install it by using pip as following :
$pip install streamlit
Let’s get into coding 🧑💻.
let’s install required libraries for project .
$pip install google-generativeai streamlit
Google provides python library called google-generativeai to interact with their generative models.
let’s import required python modules which are necessary .
import os
import dotenv
import google.generativeai as palm
import requests
import time
import urllib.parse
import streamlit as st
Now we are going to add API keys for Palm model and TMDB API into .env
file 🔑.
PALM_API_KEY="Your Palm API key here"
TMDB_API_KEY="Your TMDB API access token here"
Now our environment variable is set . Time to import API keys into python code . We can do by following line of code .
dotenv.load_dotenv()
Now we are going to create class by the name of Recommend_movies .
class Recommend_movies:
def __init__(self) -> None:
self.model = palm
self.model.configure(api_key=os.getenv("PALM_API_KEY"))
self.session = requests.Session()
self.session.headers = {
"accept": "application/json",
"Authorization": f"Bearer {os.getenv('TMDB_API_KEY')}"
}
self.defaults = {
'model': 'models/text-bison-001',
'temperature': 0.7,
'candidate_count': 1,
'top_k': 40,
'top_p': 0.95,
'max_output_tokens': 1024,
'stop_sequences': [],
'safety_settings': [
{"category":"HARM_CATEGORY_DEROGATORY","threshold":1},
{"category":"HARM_CATEGORY_TOXICITY","threshold":1},
{"category":"HARM_CATEGORY_VIOLENCE","threshold":2},
{"category":"HARM_CATEGORY_SEXUAL","threshold":2},
{"category":"HARM_CATEGORY_MEDICAL","threshold":2},
{"category":"HARM_CATEGORY_DANGEROUS","threshold":2}
],
}
def urlify_string(self,string):
url_encoded = urllib.parse.quote(string)
return url_encoded
def generate(self,movie_name :str):
result = []
prompt = f"""input: Th Dark Knight
output: Batman Begins
The Prestige
Se7en
Fight Club
The Shawshank Redemption
input: {movie_name}
output:"""
response = self.model.generate_text(
**self.defaults,
prompt=prompt
)
recommendations = response.result.split("\n")
time.sleep(0.1)
for i in recommendations:
movie = self.urlify_string(i)
url = f"https://api.themoviedb.org/3/search/movie?query={movie}&include_adult=false&language=en-US&page=1"
res = self.session.get(url).json()
result.append(res["results"])
return result
Now we will discuss above code method by method. Let’s start with initializer method.
def __init__(self) -> None:
self.model = palm
self.model.configure(api_key=os.getenv("PALM_API_KEY"))
self.session = requests.Session()
self.session.headers = {
"accept": "application/json",
"Authorization": f"Bearer {os.getenv('TMDB_API_KEY')}"
}
self.defaults = {
'model': 'models/text-bison-001',
'temperature': 0.7,
'candidate_count': 1,
'top_k': 40,
'top_p': 0.95,
'max_output_tokens': 1024,
'stop_sequences': [],
'safety_settings': [
{"category":"HARM_CATEGORY_DEROGATORY","threshold":1},
{"category":"HARM_CATEGORY_TOXICITY","threshold":1},
{"category":"HARM_CATEGORY_VIOLENCE","threshold":2},
{"category":"HARM_CATEGORY_SEXUAL","threshold":2},
{"category":"HARM_CATEGORY_MEDICAL","threshold":2},
{"category":"HARM_CATEGORY_DANGEROUS","threshold":2}
],
}
First we are going to assign our palm model by following line of code and we are configuring palm api key to model .
self.model = palm
self.model.configure(api_key=os.getenv("PALM_API_KEY"))
Now we going to create session object to call TMDB API and we are going to configure TMDB API key with session object .
self.session = requests.Session()
self.session.headers = {
"accept": "application/json",
"Authorization": f"Bearer {os.getenv('TMDB_API_KEY')}"
}
Our Palm model needs some default configurations at the time of generation like which model we are going to use , what will be temperature at the time of text generation .
self.defaults = {
'model': 'models/text-bison-001',
'temperature': 0.7,
'candidate_count': 1,
'top_k': 40,
'top_p': 0.95,
'max_output_tokens': 1024,
'stop_sequences': [],
'safety_settings': [
{"category":"HARM_CATEGORY_DEROGATORY","threshold":1},
{"category":"HARM_CATEGORY_TOXICITY","threshold":1},
{"category":"HARM_CATEGORY_VIOLENCE","threshold":2},
{"category":"HARM_CATEGORY_SEXUAL","threshold":2},
{"category":"HARM_CATEGORY_MEDICAL","threshold":2},
{"category":"HARM_CATEGORY_DANGEROUS","threshold":2}
],
}
Next , we need to convert string into it’s url form . By using urlify_string method to convert string into it’s url form 🌐.
def urlify_string(self,string):
url_encoded = urllib.parse.quote(string)
return url_encoded
Now we are going to generate results from model . We are going to use output from palm model to fetch movie poster and movie name from TMDB API .
def generate(self,movie_name :str):
result = []
prompt = f"""input: Th Dark Knight
output: Batman Begins
The Prestige
Se7en
Fight Club
The Shawshank Redemption
input: {movie_name}
output:"""
response = self.model.generate_text(
**self.defaults,
prompt=prompt
)
recommendations = response.result.split("\n")
time.sleep(0.1)
for i in recommendations:
movie = self.urlify_string(i)
url = f"https://api.themoviedb.org/3/search/movie?query={movie}&include_adult=false&language=en-US&page=1"
res = self.session.get(url).json()
result.append(res["results"])
return result
If you take closer look to our prompt . It looks different from normal prompt as you use with ChatGPT .
PaLM Model comes in three flavours as following :
1 . Text Prompt
2 . Data Prompt
3 . Chat Prompt
For our project purpose we are going to use Data prompt .
What exactly is Data prompt 🤔?
Data prompt is some what similar to fine tunning model . Here we need to give palm model some examples for training and then it generates similar output for particular input .
As you can see in above image example we need to give example input and output to the model . In examples I have given input as The Dark Knight and in output column , there are movies similar to The Dark Knight .
By the way The Dark Knight is my favourite movie 🃏🦇.
Back to the topic , Now we are going to test our prompt .So in input we are going to add Iron man as a movie and then it will generate output movies 🎥.
Now we need to give such input and output in python code 🐍.
prompt = f"""input: Th Dark Knight
output: Batman Begins
The Prestige
Se7en
Fight Club
The Shawshank Redemption
input: {movie_name}
output:"""
Here in above python code , we are formatting new string by using f-string in python .We have modified out prompt to give output for particular movie .
response = self.model.generate_text(
**self.defaults,
prompt=prompt
)
recommendations = response.result.split("\n")
Then we are going parse our prompt and default configurations to generate_text method which will generate output . After text generation we going to split output by new line character because movie names in output are on new lines.
for i in recommendations:
movie = self.urlify_string(i)
url = f"https://api.themoviedb.org/3/search/movie?query={movie}&include_adult=false&language=en-US&page=1"
res = self.session.get(url).json()
result.append(res["results"])
return result
Then we are going to loop through the recommendation generated by palm model and we are going to make GET request to TMDB API to get information of particular movie . Then we are going to store this into result list and at last we are going to return result .
Now our model text generation code is complete .Now we are going to implement user interface by using streamlit .
First we are going to give title to our web app . It is similar to h1 tag in HTML .Following code will create title by calling st.title(“Title name”) method.
st.title("Recommendation System Using Palm 🎞️")
Now we need text box such that user can able to insert movie name .
text_box = st.text_input("Your movie goes here 🎥")
Now we are going to create object for Recommend_movies class .
r_m = Recommend_movies()
To manage layout in streamlit , we are going to use columns . We will add fetched image in column 1 if index of image is even or else we will add fetched image into column 2.
col1, col2 = st.columns(2)
for i in range(len(result)) :
if result[i] != []:
if i % 2 == 0 :
col1.image(f"https://image.tmdb.org/t/p/w300_and_h450_bestv2{result[i][0]['poster_path']}")
col1.write(result[i][0]['title'])
else :
col2.image(f"https://image.tmdb.org/t/p/w300_and_h450_bestv2{result[i][0]['poster_path']}")
col2.write(result[i][0]['title'])
We can add image in column by calling col.image method . We need to pass image path as parameter in col.image .
That’s It now let’s run our application 😊.If you have installed streamlit correctly the you can run cli commands for streamlit as follows :
$streamlit run filename.py
After running python file for project , New browser tab will open at http://localhost:8501/ . You will see web app like this :
You just need to insert movie name in text box and hit enter . You should see output like this :
That’s it ! . Congratulations 😎! You have created recommendation system using PaLM model . Source code is available on Github .
Thanks for reading this article 😊. If you liked content in blog then please like 👍it . Also checkout my youtube channel here .If you have any question then feel free to comment down .
You can connect with me through linkedin and also from portfolio website.
Thank You 😃!
Top comments (0)