Search code examples
pythonapisslurllib

Can't retrieve image from API - SSL certificate error


I'm trying to fetch an image from Nasa's APOD API and save it to my computer, but when the request gets sent, I get an SSL certificate error. I'm not sure how to fix it since I've never dealt with this before.

This is what i get:

raise SSLError(e)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1124)

Here's my code:

import nasapy
import os
from datetime import datetime
import urllib.request
from IPython.display import Image,display,Audio
import ssl

def nasa_apod(ctx):
    key = "#####################"
    nasa = nasapy.Nasa(key=key)

    dtm = datetime.today().strftime("%Y-%m-%d")
    apod = nasa.picture_of_the_day(date=dtm, hd=True)

    print(apod)
    if apod["media_type"] == "image":
        title = dtm + "_" + apod["title"].replace(" ", "_").replace(":", "_") + ".jpg"
        image_dir = "Astro_images"

        dir_res = os.path.exists(image_dir)

        if dir_res == False:
            os.makedirs(image_dir)
        else:
            print("Directory already exists! ")

    filename =os.path.join(image_dir, title)
    with urllib.request.urlopen(url=apod["hdurl"], context=ctx) as u, \
        open(filename, 'wb') as f:
            f.write(u.read())

    if ("date" in apod.keys()):
        print("Date image released: ", apod["date"])
        print("\n")
    if ("copyright" in apod.keys()):
        print("This image is owned by: ", apod["copyright"])
        print("\n")
    if ("title" in apod.keys()):
        print("Title of the image: ", apod["title"])
        print("\n")
    if ("explanation" in apod.keys()):
        print("Description for the image: ", apod["explanation"])
        print("\n")
    if ("hdurl" in apod.keys()):
        print("URL for this image: ", apod["hdurl"])
        print("\n")

    display(Image(os.path.join(image_dir, title)))


ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

nasa_apod(ctx)

I've hidden the key for security reasons.

Any help is appreciated!


Solution

  • you need to replace urllib.request.urlretrieve by urllib.request.urlopen and determine a custom ssl context before you call nasa_apod method, then your program should look like this:

    def nasa_apod(ctx):
        key = "#####"
        nasa = nasapy.Nasa(key=key)
    
        dtm = datetime.today().strftime("%Y-%m-%d")
        apod = nasa.picture_of_the_day(date=dtm, hd=True)
    
        print(apod)
        if apod["media_type"] == "image":
            title = dtm + "_" + apod["title"].replace(" ", "_").replace(":", "_") + ".jpg"
            image_dir = "Astro_images"
    
            dir_res = os.path.exists(image_dir)
    
            if dir_res == False:
                os.makedirs(image_dir)
            else:
                print("Directory already exists! ")
    
        filename=os.path.join(image_dir, title) 
        with urllib.request.urlopen(url=apod["hdurl"], context=ctx) as u, \
            open(file_name, 'wb') as f:
        f.write(u.read())
    
        if ("date" in apod.keys()):
            print("Date image released: ", apod["date"])
            print("\n")
        if ("copyright" in apod.keys()):
            print("This image is owned by: ", apod["copyright"])
            print("\n")
        if ("title" in apod.keys()):
            print("Title of the image: ", apod["title"])
            print("\n")
        if ("explanation" in apod.keys()):
            print("Description for the image: ", apod["explanation"])
            print("\n")
        if ("hdurl" in apod.keys()):
            print("URL for this image: ", apod["hdurl"])
            print("\n")
    
        display(Image(os.path.join(image_dir, title)))
    
    
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    
    nasa_apod(ctx)