1

I am trying to make a website that allows a user to create their own "to-watch" list and also can randomly select a title from the created list, showing the movie's plot, genre, and IMDb rating using an API. I've encountered a "NoneType' object is not subscriptable" error message when trying to run this function and am not sure how to overcome it. Here are the relevant parts of my code:

application.py

import os

from cs50 import SQL
from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash

from helpers import apology, login_required, imdb

app = Flask(__name__)

app.config["TEMPLATES_AUTO_RELOAD"] = True

@app.after_request
def after_request(response):
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response
    
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

db = SQL("sqlite:///project.db")
    @app.route("/select", methods=["GET", "POST"])
    @login_required
    def select():

        if request.method == "POST":
            """Randomly pick a movie to watch"""
            
            therearemovies = db.execute("SELECT uniqueid FROM movies WHERE id=:id", id=session["user_id"])
            
            if therearemovies:
                chosen = db.execute("SELECT * FROM movies WHERE id=:id ORDER BY RANDOM() LIMIT 1", id=session["user_id"])
                
                for uniqueindex in chosen:
                    suggestion = uniqueindex["title"]
                    
                    **info = imdb(suggestion)
                    plot = info["plot"]
                    genre = info["genre"]
                    rating = info["rating"]**
                    
                    return render_template("select.html", suggestion=suggestion, plot=plot, genre=genre, rating=rating)
            
            else:
                return apology("You don't have any movies in your list")
                
        else:
            return render_template("/")

helper.py:

import os
import requests
import urllib.parse
    
def imdb(title):
try:
    response=requests.get(f"http://www.omdbapi.com/?t={urllib.parse.quote_plus(title)}&apikey=12345678")
    response.raise_for_status()
except requests.RequestException:
    return None

try:
    data = response.json()
    return 
    {
        "plot": data["plot"],
        "genre": data["genre"],
        "rating": data["imdbRating"]
    }
except (KeyError, TypeError, ValueError):
    return None

Error Message:

File "/home/ubuntu/finalproject/helpers.py", line 32, in decorated_function
    return f(*args, **kwargs)
File "/home/ubuntu/finalproject/application.py", line 126, in select
    plot = info["plot"]
TypeError: 'NoneType' object is not subscriptable
ddinh9978
  • 11
  • 4
  • Sounds like the request is raising an exception - trying printing it out: `except requests.RequestException as e: print(e)` – costaparas Dec 24 '20 at 04:56
  • 1
    `imdb()` is returning None. – John Gordon Dec 24 '20 at 04:58
  • 1
    A side piece of advice: **Never post your API keys on Stack Overflow, or *anywhere else online* for that matter** – costaparas Dec 24 '20 at 05:15
  • You were right, turns out the exception was causing imdb() to return None, but I still don't know why that is since I also got back a 200 status code. My terminal is showing `ERROR: Exception on /select [POST]` Is there a problem with how I'm contacting the API or is it another issue entirely? – ddinh9978 Dec 24 '20 at 05:54
  • first you should check `print( response.text )` . Status `200` doesn't have to mean it sends you correct data. Status `200` only means that server knows how to answer for request but It could send something different - ie. warning for bots/script or captcha. Besides server first sends status `200` and later it starts to sending data - and if it have problem after sending status then you may get `200` and wrong data. And `print( response.text )` should show you what you really get. – furas Dec 24 '20 at 07:10

0 Answers0