Python API Problem


#1

I’ve been trying to create a basic program that get the current value of BTC from the coindesk api but I keep getting this error, wondering if anyone could lend a hand.

#Program to get the current value of BTC via an API call.
import urllib.request as url
import json

base_url = "https://api.coindesk.com/v1/bpi/currentprice/x.json"
currency = ""

currency_input = input("What currency do you want to have? \neur (Euro) \ngbp (Great British Pound) \nusd (United States Dollar) \n:")
if currency_input == 'eur':
    print("Selected EUR as the currency")
    api_url = "https://api.coindesk.com/v1/bpi/currentprice/%s.json" % currency_input
if currency_input == 'gbp':
    print("Selected GBP as the currency")
    api_url = "https://api.coindesk.com/v1/bpi/currentprice/%s.json" % currency_input
if currency_input == 'usd':
    print("Selected USD as the currency")
    api_url = "https://api.coindesk.com/v1/bpi/currentprice/%s.json" % currency_input
else:
    print("Invalid Currency, please look at the selection list for further ideas!")

print("The current API URL that will be called is: \n%s" % api_url)

request = url.urlopen(url.Request(api_url, headers={'User-Agent' : "Mozilla/5.0"}))
data = request.read()
data = data.decode("utf-8")

print(data['bpi'])

The main problem is that I can get the information from the API however I’m not able to print the data out.

I want to print the current value with variable[‘bpi’].

Thanks in advance, bois.


#2
data = data.decode("utf-8")
// Now we have decoded data
// but what is the data type?
print(data['bpi'])

see comment in code.


#3

(OP from actual account)

In the YouTube video I was following (python 2.4) they said that it’s a dictionary, isn’t it?

Assuming it is a dictionary shouldn’t that be the correct way to gather and print that select bit of data?


#4

python has a built-in type() function, go use it to see what data type you are having. Although you could deduce it from the error as well


#5

Ok, just called type on it and it returned string. If I plan on doing stuff with it later isn’t it good that it’s a string?


#6

that explains the error, strings can only be accessed by index. Accessing by keys is for dictionaries. You would need to convert the string into a dictionary


#7

So what would be the best datatype for converting API data? wouldn’t calling a dictionary the way above be the most effective?

Also I can’t find anywhere how to convert this data to a dictionary, how would I do this?


#8

unless the API offers you the option to get a dictionary, you will have to make due with what you get and the conversion yourself.

i searched on google: python convert string to dictionary and instantly got good results


#9

Yes, was going to edit but then you replied, I used <ast.literal_eval(data)> to convert it.

The new problem is that I’ve got it to print ‘bpi’ and it returns this:
{‘USD’: {‘code’: ‘USD’, ‘rate’: ‘9,332.9450’, ‘description’: ‘United States Dollar’, ‘rate_float’: 9332.945}}

I don’t know how to select code, description, rate or any other individual piece of data because I can’t seem to find a way to print a value within a value within a dictionary. Again, could you assist?


#10

nothing changed, you will just need to another key to retrieve the next nested value


#11

I don’t quite understand, how would I retrieve the description (for example) value?


#12

you use the key like you always do: [key]


#13

ok so I’m trying to select ‘code’, ‘description’ and ‘rate’ from the response but I don’t know how to and I can get my head around “use it like I usually do”.

I saw an example using a for loop so this is now my code at the bottom:
for item in data[‘bpi’]:
print(item[‘usd’])

but it’s returning this:
TypeError: string indices must be integers

Would this even work and why am I getting this error, I thought I converted it so it could be read like that.


#14

just because you saw an example doesn’t mean you have to use a loop as well, why would you want to use a loop? You can just chain keys together:

dict[key1][key2]

#15

Ah, I didn’t know it worked on levels like that. Thanks for the help.


#16

well, the value is a dictionary, as such, we can again use a key to delve deeper


#17

Hey, an unrelated problem (can’t find the section to help with this).

I’m trying to update my payment method (and I have updated it) but it still says last payment about a month ago and doesn’t give me the option to renew it, any suggestions?

Also actually I do have a problem but it’s with somthing else, here’s my code:

#Program to get the current value of BTC via an API call.
import urllib.request as url
import json
import ast

api_url = ''

currency_input = input("What currency do you want to have? \neur (Euro) \ngbp (Great British Pound) \nusd (United States Dollar) \n:")

def currency_selection(currency_input,api_url):
    base_url = "https://api.coindesk.com/v1/bpi/currentprice/x.json"
    currency_input.upper()
    
    if currency_input == 'EUR':
        print("Selected EUR as the currency")
        api_url = (base_url + currency_input)
        return(api_url)
    
    if currency_input == 'GBP':
        print("Selected GBP as the currency")
        api_url = (base_url + currency_input)
        return(api_url)
    
    if currency_input == 'USD':
        print("Selected USD as the currency")
        api_url = (base_url + currency_input)
        return(api_url)
    
    else:
        print("Invalid Currency!")
        exit()
        
print("The current API URL that will be called is: \n%s" % api_url)

def DataGet(api_url,data):
    request = url.urlopen(url.Request(api_url, headers={'User-Agent' : "Mozilla/5.0"}))
    data = request.read()
    data = data.decode("utf-8")
    data = ast.literal_eval(data)
    return data

print("The current price of BTC in %s (%s) is %s!" % (DataGet(data['bpi'][str(currency_selection(currency_input.upper()))]['code'],DataGet(data['bpi'][str(currency_selection(currency_input.upper()))]['rate'],DataGet(data['bpi'][str(currency_selection(currency_input.upper()))]['description'])))))

I’m looking for the codecademy section where it deals with functions (input & output), thanks.


#18

Please see guidelines:

http://discuss.codecademy.com/guidelines

you made a question, i answered. I helped you a bit further, but if you have more questions, please make a new topic so someone else can help you. Continuing a topic with constant new questions is a violation of the guidelines


#19

I actually had another problem that was on topic relating to the same program we worked on not an hour earlier. I feel that falls under “on-topic” otherwise I would have to open up 8 different threads for every individual error I have with the same program.

As for the comment relating to my codecademy subscription I don’t quite see the section on help with subscriptions so I don’t know what section I should put it into.

While c + ping me the guidelines might help if I’m spamming or other “unacceptable” behaviour I don’t feel that either of my above statements actually fall under that category. That being said I will start another topic for every error I have from now on, thanks for the help.