The Pokémon detail page (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Navi-27/Proyecto-UPC/llms.txt
Use this file to discover all available pages before exploring further.
GET /pokemon/<nombre>) is the richest view in the application. It presents a full profile card for a single Pokémon — sprite, National Dex number, types, physical measurements, and a complete base-stat breakdown rendered as progress bars. Logged-in users also see an Add to Team button, and the visit is silently recorded in their personal Pokédex history the moment the page loads.
Example URL
<nombre> segment is the lowercase slug used by PokéAPI (e.g. charizard, bulbasaur, mr-mime).
Data Lookup and Cache Fallback
When the route is hit,PokeAPI.obtener_pokemon(nombre_o_id) is called. It follows a two-step lookup:
- SQLite cache first — queries
cache_pokemonwithWHERE nombre = ? OR id = ?. If a matching row is found, aPokemonobject is constructed from it and returned immediately, with no network call. - Live PokéAPI fallback — if the Pokémon is not in the cache (for example, a Pokémon above 1025 or one that wasn’t bulk-loaded), the app calls
https://pokeapi.co/api/v2/pokemon/<nombre_o_id>. A successful response is parsed, returned, and also saved tocache_pokemonviaINSERT OR IGNOREso future lookups are instant.
Pokémon Data Fields
ThePokemon class exposes the following attributes, all of which are rendered on the detail page:
| Field | Type | Description |
|---|---|---|
id | int | National Pokédex number (e.g. 6 for Charizard) |
nombre | str | Pokémon name in lowercase (e.g. charizard) |
tipos | list[str] | Ordered list of type slugs (e.g. ["fire", "flying"]) |
altura | int | Height in decimeters — divide by 10 for metres (e.g. 17 → 1.7 m) |
peso | int | Weight in hectograms — divide by 10 for kilograms (e.g. 905 → 90.5 kg) |
imagen | str | Absolute URL to the official front sprite from the PokéAPI sprites CDN |
stats | dict | Base stats keyed by stat name (see table below) |
Base Stats
Thestats dictionary contains six entries corresponding to the standard competitive stat set:
| Key | Stat |
|---|---|
hp | Hit Points |
attack | Physical Attack |
defense | Physical Defense |
special-attack | Special Attack |
special-defense | Special Defense |
speed | Speed |
(value / 255) * 100 as the bar width percentage.
Viewed Tracking
Every time a logged-in user visits a detail page, the application automatically records that Pokémon in the user’s personal history — no button click required. This happens at the top of the route handler, before the template is rendered:PokedexUsuario.registrar_visto() inserts a row into pokedex_usuario using INSERT OR IGNORE, so repeated visits to the same Pokémon never create duplicate entries — only the first visit is recorded.
Add to Team Button
When a user is logged in, a green ➕ Agregar a mi equipo button appears at the bottom of the stat card. Clicking it navigates to:- Team is full (6 Pokémon already in the roster) → flash message:
El equipo ya esta completo (6 Pokemones) - Pokémon already in team → flash message:
El pokemon ya se encuentra en tu equipo
The
tipos field is stored as a JSON string (e.g. '["fire", "flying"]') in both the cache_pokemon and equipos database tables. The detail template accesses pokemon.tipos as a native Python list (already parsed by PokeAPI.obtener_pokemon()), but other templates that read tipos directly from database rows use the custom parse_tipos Jinja2 filter — registered in application.py — to deserialise the string back into a list before iterating over it.