Adicionar endpoint: GET /.../pokemon/{pokemonId}

This commit is contained in:
Augusto Gunsch 2021-10-18 17:42:26 -03:00
parent 5fc179d389
commit e02e05ea06
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
4 changed files with 48 additions and 28 deletions

View File

@ -22,5 +22,5 @@ Os endpoints que já estão funcionando marcados:
- [X] GET /trainer/{trainerId} - [X] GET /trainer/{trainerId}
- [X] GET /trainer/{trainerId}/pokemon - [X] GET /trainer/{trainerId}/pokemon
- [X] POST /trainer/{trainerId}/pokemon - [X] POST /trainer/{trainerId}/pokemon
- [ ] GET /trainer/{trainerId}/pokemon/{pokemonId} - [X] GET /trainer/{trainerId}/pokemon/{pokemonId}
- [ ] DELETE /trainer/{trainerId}/pokemon/{pokemonId} - [ ] DELETE /trainer/{trainerId}/pokemon/{pokemonId}

View File

@ -29,3 +29,7 @@ def route_post_pokemons_owned(trainer, trainerId):
if trainer.id != trainerId: if trainer.id != trainerId:
return errors.ForbiddenError("Trainer id mismatch") return errors.ForbiddenError("Trainer id mismatch")
return pokemon_owned.post_pokemon_owned(trainerId) return pokemon_owned.post_pokemon_owned(trainerId)
@app.route("/trainer/<int:trainerId>/pokemon/<int:pokemonId>", methods=["GET"])
def route_get_pokemon_owned(trainerId, pokemonId):
return pokemon_owned.get_pokemon_owned(trainerId, pokemonId)

View File

@ -11,26 +11,26 @@ class HTTPError(Exception):
def __init__(self, message): def __init__(self, message):
self.message = message self.message = message
class TrainerNotFound(Exception): class NotFound(Exception):
pass pass
def get_trainer_fail(id): def get_or_not_found(callback):
try: try:
trainer = Trainer.query.get(id) resource = callback()
if trainer is None: if resource is None:
raise TrainerNotFound() raise NotFound()
return trainer return resource
except: except:
raise TrainerNotFound() raise NotFound()
def get_trainer_fail(id):
return get_or_not_found(lambda : Trainer.query.get(id))
def get_trainer_by_nick_fail(nickname): def get_trainer_by_nick_fail(nickname):
try: return get_or_not_found(lambda : Trainer.query.filter_by(nickname=nickname).one())
trainer = Trainer.query.filter_by(nickname=nickname).one()
if trainer is None: def get_pokemon_fail(trainer, id):
raise TrainerNotFound() return get_or_not_found(lambda : trainer.pokemons_list.filter_by(id=id).one())
return trainer
except:
raise TrainerNotFound()
# authenticação do trainer (decorator) # authenticação do trainer (decorator)
def token_required(f): def token_required(f):
@ -38,13 +38,12 @@ def token_required(f):
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
try: try:
token = request.headers["authorization"] token = request.headers["authorization"]
print(token)
print(app.config["SECRET_KEY"])
data = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"]) data = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"])
print(data["username"])
trainer = get_trainer_by_nick_fail(data["username"]) trainer = get_trainer_by_nick_fail(data["username"])
except (TypeError, KeyError): except (TypeError, KeyError):
return AuthenticationFailure("JWT token required") return AuthenticationFailure("JWT token required")
except NotFound:
return AuthenticationFailure("Trainer not found")
except: except:
return AuthenticationFailure("JWT token is invalid or expired") return AuthenticationFailure("JWT token is invalid or expired")
@ -53,13 +52,19 @@ def token_required(f):
# seguintes funções puxam informações da pokeapi # seguintes funções puxam informações da pokeapi
def set_pokemon_data(pokemon): def set_pokemon_data(pokemon):
try:
response = requests.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id)) response = requests.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id))
if response.status_code != 200: if response.status_code != 200:
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id)) raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
pokemon.pokemon_data = json.loads(response.text) pokemon.pokemon_data = json.loads(response.text)
except:
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
async def async_set_pokemon_data(session, pokemon): async def async_set_pokemon_data(session, pokemon):
try:
response = await session.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id)) response = await session.get("https://pokeapi.co/api/v2/pokemon/{}".format(pokemon.pokemon_id))
if response.status != 200: if response.status != 200:
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id)) raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))
pokemon.pokemon_data = json.loads(await response.text()) pokemon.pokemon_data = json.loads(await response.text())
except:
raise HTTPError("Could not fetch pokemon with id {}".format(pokemon.pokemon_id))

View File

@ -2,7 +2,7 @@ from api.models.pokemon_owned import pokemon_owned_schema, pokemon_owned_schemas
from api.app import db from api.app import db
from .parse_args import parse_limit, parse_offset, ParsingException, parse_json_obj from .parse_args import parse_limit, parse_offset, ParsingException, parse_json_obj
from .errors import ParsingError, FetchError, ConflictingResources from .errors import ParsingError, FetchError, ConflictingResources
from .helper import TrainerNotFound, HTTPError, get_trainer_fail, set_pokemon_data, async_set_pokemon_data from .helper import *
from aiohttp import ClientSession from aiohttp import ClientSession
from asyncio import create_task, gather from asyncio import create_task, gather
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
@ -46,7 +46,7 @@ async def get_pokemons_owned(trainer_id):
try: try:
trainer = get_trainer_fail(trainer_id) trainer = get_trainer_fail(trainer_id)
except TrainerNotFound: except NotFound:
return "", 404 return "", 404
pokemons = trainer.pokemons_list.limit(limit).offset(offset).all() pokemons = trainer.pokemons_list.limit(limit).offset(offset).all()
@ -62,3 +62,14 @@ async def get_pokemons_owned(trainer_id):
return FetchError(e.message) return FetchError(e.message)
return pokemon_owned_schemas.dumps(pokemons) return pokemon_owned_schemas.dumps(pokemons)
def get_pokemon_owned(trainer_id, pokemon_id):
try:
trainer = get_trainer_fail(trainer_id)
pokemon = get_pokemon_fail(trainer, pokemon_id)
set_pokemon_data(pokemon)
return pokemon_owned_schema.dump(pokemon)
except NotFound:
return "", 404
except HTTPError as e:
return FetchError(e.message)