Reputation: 107
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
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