Building a Powerful Recommendation System with Palm 2 Model and Streamlit: A Step-by-Step Guide
Tags: deeplearning, chatgpt, beginners, ai
Published: 2023-07-03 18:07:18

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 😊.

{% embed https://youtu.be/zRGySIj96xA %}

**What is PaLM 2 Large Language Model API ?**

![Google's palm 2 model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4awyso37pg6tvycemhxd.png)

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](https://developers.generativeai.google/products/palm) to get your API key via MakerSuite and start prototyping quickly .

**What is [TMDB](https://www.themoviedb.org/) 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.


![TMDB API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ej9j1r0tvs8cbd3ukuhd.png)

**Steps to get API key for TMDB API :**

1. Create account on TMDB website ([https://www.themoviedb.org/](https://www.themoviedb.org/)) or log in if you already have an account.
2. Go to profile [settings](https://www.themoviedb.org/settings/profile) page .
3. Go to API tab ( [https://www.themoviedb.org/settings/api](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 .
4. You can find more details about how we can use TMDB API and it’s endpoints at [https://developer.themoviedb.org/docs](https://developer.themoviedb.org/docs) 😎.

**Little bit about Streamlit 🔥**

Streamlit ([https://streamlit.io/](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](https://docs.streamlit.io/) .

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](https://github.com/google/generative-ai-python) to interact with their generative models.

let’s import required python modules which are necessary .

```python
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 .

```python
dotenv.load_dotenv()
```
Now we are going to create class by the name of **Recommend_movies** .

```python
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.

```python
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 .

```python
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 .

```python
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 .

```python
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 🌐.

```python
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 .

```python
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 .


![Data Prompt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/to353mym5zflguqs120z.png)

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 🐍.

```python
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 .

```python
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.

```python
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.

```python
st.title("Recommendation System Using Palm 🎞️")
```
Now we need text box such that user can able to insert movie name .

```python
text_box = st.text_input("Your movie goes here 🎥")
```
Now we are going to create object for Recommend_movies class .

```python
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.

```python
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/](http://localhost:8501/) . You will see web app like this :


![Project Interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d6jxdf57tcvosnfyfwwe.png)

You just need to insert movie name in text box and hit enter . You should see output like this :


![Project Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7j4mcoerxspf5mwbe7f9.png)

That’s it ! . Congratulations 😎! You have created recommendation system using PaLM model . Source code is available on [Github](https://github.com/Tanmaypatil123/Recommend-Palm) .

Thanks for reading this article 😊. If you liked content in blog then please like 👍it . Also checkout my [youtube channel](https://www.youtube.com/@NeuralNetworksTV) here .If you have any question then feel free to comment down .

You can connect with me through [linkedin](https://www.linkedin.com/in/mlwithtanmay/) and also from [portfolio website](https://tanmaypatil123.github.io/).

Thank You 😃!