Spaces:
Sleeping
Sleeping
| 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) | |
| 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" | |
| } | |
| } | |
| def informacoes_gerais(): | |
| dados = carregar_dados() | |
| return dados["anime"] | |
| 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] | |
| } | |
| 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.") | |
| 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 | |
| } | |
| def listar_clas(): | |
| dados = carregar_dados() | |
| clas = sorted( | |
| set(personagem["cla"] for personagem in dados["personagens"]) | |
| ) | |
| return { | |
| "total": len(clas), | |
| "clas": clas | |
| } | |
| 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 | |
| } | |
| def listar_vilas(): | |
| dados = carregar_dados() | |
| vilas = sorted( | |
| set(personagem["vila"] for personagem in dados["personagens"]) | |
| ) | |
| return { | |
| "total": len(vilas), | |
| "vilas": vilas | |
| } | |
| 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 | |
| } | |
| 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] | |
| } | |
| 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 | |
| } | |