user13641095
user13641095

Reputation: 107

API no longer connecting

Project: I'm building a restful API that's taking data from one API and using another API to translate part of that data, the description, into some other lexicon.

Problem: All was working fine until a few days back I stopped getting connection with the translation API. I've changed nothing in the code relating to the request. I can also replicate the problem when I use VCS to go back to earlier versions of my code. I've tried this in two different environments but I encounter the same issue. I've also tried my web browser and POSTMAN but they seem to be getting the appropriate responses. I'm a receiving a HTTP code of 200 when I when running a test file but not getting the response I want from the translation API.

Code explanation: So I'm taking some nested information, flavor_text_entries from my first API (data) and using that as my description, setting that as a variable and sending it to my translation API to translate and return only the translation of the description.

def extract_descriptive_text(json_blob, language='en', version='sword'):
    text = ""
    for f in json_blob['flavor_text_entries']:
        if f['language']['name'] == language and f['version']['name'] == version:
            text = f['flavor_text'] 
    return text


def extract_useful_info(translated):
    text = []
    wanted_info = translated['contents']['translated']
    text.append(wanted_info)
    return text


@app.route('/pokemon/<string:name>/', methods=['GET'])
def get_translation(name):
    descrip_url = f"https://pokeapi.co/api/v2/pokemon-species/{name}"
    r = requests.get(descrip_url)
    json_blob = r.json()
    text_trans = extract_descriptive_text(json_blob)
    trans_url = f"https://api.funtranslations.com/translate/shakespeare.json?text={text_trans}"
    shakespeare = requests.get(trans_url)
    translated = shakespeare.json()
    useful_info = extract_useful_info(translated)
    return jsonify({'name': name, 'description': useful_info})

if __name__ == '__main__':
    app.run(debug=True)

Error I get when I try to return everything from translation API:

ERROR:
{
  "name": "charizard", 
  "description": {
    "error": {
      "code": 404, 
      "message": "Not Found"
    }
  }
}

Traceback I receive when I try return just the translation:

Traceback (most recent call last):
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask_restful/__init__.py", line 272, in error_router
    return original_handler(e)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask_restful/__init__.py", line 272, in error_router
    return original_handler(e)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/swapneel/Library/Python/3.8/lib/python/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/swapneel/Desktop/projects/foobar/main.py", line 58, in get_translation
    useful_info = extract_useful_info(translated)
  File "/Users/swapneel/Desktop/projects/foobar/main.py", line 21, in extract_useful_info
    wanted_info = translated['contents']['translated']
KeyError: 'contents'

Libraries and Packages used:

from flask import Flask, jsonify
from flask_restful import Api
import requests

Any help would be massively appreciated!

Upvotes: 1

Views: 62

Answers (1)

Simeon Nedkov
Simeon Nedkov

Reputation: 1094

The translation API can't find the search term charizard and is returning a different JSON then the one you are expecting and are able to handle.

In extract_useful_info() you are retrieving translated['contents'] but as you can see in the API response you are getting that key is not present when there's an API error. Instead, the response contains 'name' and 'description'.

You'll need to implement a check for when the API errors out. You can do that by e.g. wrapping wanted_info in a try/except:

def extract_useful_info(translated):
    text = []
    try:
        wanted_info = translated['contents']['translated']
    except KeyError:
        wanted_info = ''

    text.append(wanted_info)
    return text

As a side note: I can't see why text needs to be a list. The code becomes much simpler if it's just a string i.e.

def extract_useful_info(translated):
    try:
        return translated['contents']['translated']
    except KeyError:
        return '' # return None is better but I don't know if your app can handle that.

If that's the case, though, we we can get rid of extract_useful_info() altogether and do

...
try: 
    useful_info = shakespeare.json()['contents']['translated']
except KeyError:
    useful_info = '' # or return None
...

Upvotes: 1

Related Questions