narutoapi / app.py
GalvaoFilho's picture
Upload 4 files
2652b5e verified
from fastapi import FastAPI, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from typing import Optional
import json
import os
app = FastAPI(
title="Naruto API",
description="API didática para consulta de personagens, clãs, vilas e informações do universo Naruto.",
version="1.0.0"
)
# Permite que a API seja consumida por aplicações externas, como React, HTML e JavaScript.
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_PATH = os.path.join(BASE_DIR, "data", "naruto.json")
STATIC_PATH = os.path.join(BASE_DIR, "static")
# Disponibiliza arquivos estáticos, como imagens dos personagens.
app.mount("/static", StaticFiles(directory=STATIC_PATH), name="static")
def carregar_dados():
"""Carrega os dados do arquivo JSON."""
with open(DATA_PATH, "r", encoding="utf-8") as arquivo:
return json.load(arquivo)
@app.get("/")
def inicio():
return {
"mensagem": "Bem-vindo à Naruto API!",
"descricao": "API didática para consulta de dados do universo Naruto.",
"documentacao": "/docs",
"endpoints": {
"informacoes_gerais": "/anime",
"listar_personagens": "/personagens",
"buscar_personagem_por_id": "/personagens/{id}",
"buscar_por_nome": "/buscar?q=naruto",
"listar_clas": "/clas",
"buscar_por_cla": "/clas/Uzumaki",
"listar_vilas": "/vilas",
"buscar_por_vila": "/vilas/Konoha",
"ranking_poder": "/ranking-poder",
"estatisticas": "/estatisticas"
}
}
@app.get("/anime")
def informacoes_gerais():
dados = carregar_dados()
return dados["anime"]
@app.get("/personagens")
def listar_personagens(
cla: Optional[str] = Query(None, description="Filtrar por clã"),
vila: Optional[str] = Query(None, description="Filtrar por vila"),
tipo: Optional[str] = Query(None, description="Filtrar por tipo: ninja, sensei, ninja médica, vilão etc."),
limite: int = Query(20, ge=1, le=100, description="Quantidade máxima de resultados")
):
dados = carregar_dados()
personagens = dados["personagens"]
if cla:
personagens = [
p for p in personagens
if cla.lower() == p["cla"].lower()
]
if vila:
personagens = [
p for p in personagens
if vila.lower() == p["vila"].lower()
]
if tipo:
personagens = [
p for p in personagens
if tipo.lower() == p["tipo"].lower()
]
return {
"total": len(personagens[:limite]),
"resultados": personagens[:limite]
}
@app.get("/personagens/{personagem_id}")
def buscar_personagem_por_id(personagem_id: int):
dados = carregar_dados()
for personagem in dados["personagens"]:
if personagem["id"] == personagem_id:
return personagem
raise HTTPException(status_code=404, detail="Personagem não encontrado.")
@app.get("/buscar")
def buscar_por_nome(q: str = Query(..., min_length=1, description="Nome ou parte do nome do personagem")):
dados = carregar_dados()
resultado = [
personagem for personagem in dados["personagens"]
if q.lower() in personagem["nome"].lower()
]
return {
"termo_pesquisado": q,
"total": len(resultado),
"resultados": resultado
}
@app.get("/clas")
def listar_clas():
dados = carregar_dados()
clas = sorted(
set(personagem["cla"] for personagem in dados["personagens"])
)
return {
"total": len(clas),
"clas": clas
}
@app.get("/clas/{cla}")
def buscar_por_cla(cla: str):
dados = carregar_dados()
resultado = [
personagem for personagem in dados["personagens"]
if cla.lower() == personagem["cla"].lower()
]
if not resultado:
raise HTTPException(
status_code=404,
detail="Nenhum personagem encontrado para este clã."
)
return {
"cla": cla,
"total": len(resultado),
"resultados": resultado
}
@app.get("/vilas")
def listar_vilas():
dados = carregar_dados()
vilas = sorted(
set(personagem["vila"] for personagem in dados["personagens"])
)
return {
"total": len(vilas),
"vilas": vilas
}
@app.get("/vilas/{vila}")
def buscar_por_vila(vila: str):
dados = carregar_dados()
resultado = [
personagem for personagem in dados["personagens"]
if vila.lower() == personagem["vila"].lower()
]
if not resultado:
raise HTTPException(
status_code=404,
detail="Nenhum personagem encontrado para esta vila."
)
return {
"vila": vila,
"total": len(resultado),
"resultados": resultado
}
@app.get("/ranking-poder")
def ranking_poder(limite: int = Query(10, ge=1, le=100, description="Quantidade máxima de personagens no ranking")):
dados = carregar_dados()
ranking = sorted(
dados["personagens"],
key=lambda personagem: personagem["nivel_poder"],
reverse=True
)
return {
"total": len(ranking[:limite]),
"ranking": ranking[:limite]
}
@app.get("/estatisticas")
def estatisticas():
dados = carregar_dados()
personagens = dados["personagens"]
total_personagens = len(personagens)
total_por_vila = {}
total_por_cla = {}
total_por_tipo = {}
for personagem in personagens:
vila = personagem["vila"]
cla = personagem["cla"]
tipo = personagem["tipo"]
total_por_vila[vila] = total_por_vila.get(vila, 0) + 1
total_por_cla[cla] = total_por_cla.get(cla, 0) + 1
total_por_tipo[tipo] = total_por_tipo.get(tipo, 0) + 1
return {
"total_personagens": total_personagens,
"total_por_vila": total_por_vila,
"total_por_cla": total_por_cla,
"total_por_tipo": total_por_tipo
}