Skip to main content

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.

The project is structured around object-oriented design principles, separating concerns into three distinct layers: the Flask web layer (application.py), the data models (models/), and the external service client (services/). This separation keeps routing logic, domain objects, and third-party API communication cleanly independent, making each layer easy to understand, test, and extend.

Directory Tree

Proyecto-UPC/
├── application.py        # Flask app factory, routes, template filters
├── requirements.txt      # Python dependencies
├── Procfile              # Gunicorn deployment config
├── pokedex.db            # SQLite database (auto-created)
├── models/
│   ├── database.py       # DB connection and schema init
│   ├── pokemon.py        # Pokemon data class
│   ├── pokedex.py        # Pokedex collection class
│   ├── pokedex_usuario.py# Per-user viewed Pokémon tracking
│   ├── usuario.py        # User auth model
│   └── equipo.py         # Team management model
├── services/
│   └── poke_api.py       # PokéAPI HTTP client with caching
├── templates/
│   ├── index.html        # Pokédex listing page
│   ├── detalle.html      # Individual Pokémon detail
│   ├── equipo.html       # User team page
│   ├── mi-pokedex.html   # Viewed Pokémon history
│   ├── login.html        # Login form
│   └── registro.html     # Registration form
└── static/
    └── css/style.css     # Custom styles

Layer Descriptions

Web Layer — application.py

application.py is the entry point for the entire application. It creates the Flask app instance, sets the session secret key, and initializes the database schema on startup using init_db() inside an app_context() block. All nine routes are registered here:
RouteMethod(s)Description
/GETMain Pokédex listing with optional tipo and busqueda query parameters
/pokemon/<nombre>GETIndividual Pokémon detail; records view if user is logged in
/mi-pokedexGETAuthenticated user’s viewed Pokémon history
/registroGET, POSTNew user registration form and handler
/loginGET, POSTUser login form and handler
/logoutGETClears the session and redirects to index
/equipoGETAuthenticated user’s team page
/equipo/agregar/<pokemon_id>/...GETAdds a Pokémon to the user’s team
/equipo/eliminar/<pokemon_id>GETRemoves a Pokémon from the user’s team
The file also registers the parse_tipos Jinja2 template filter, which deserializes the JSON-encoded tipos strings stored in SQLite into Python lists so they render correctly in templates. It tries json.loads first, falling back to ast.literal_eval for robustness.
@application.template_filter('parse_tipos')
def parse_tipos(value):
    import ast
    import json
    try:
        return json.loads(value)
    except:
        return ast.literal_eval(value)

Model Layer — models/

Each class in models/ is responsible for a specific domain object. The layer is deliberately self-contained — models do not know about Flask or HTTP:
  • database.py — Provides get_connection() (returns a sqlite3.Row-factored connection) and init_db() (creates all four tables via executescript if they do not exist). Every model that needs database access imports get_connection from here and opens/closes its own connection per operation.
  • pokemon.py — A pure data class. Holds all fields for a single Pokémon (id, name, types, height, weight, sprite URL, base stats). Contains no database logic.
  • pokedex.py — A collection class that wraps a list of Pokemon objects. Provides search, filtering, and bulk persistence methods.
  • usuario.py — Handles user creation and authentication using Werkzeug password hashing. Exposes only static methods.
  • equipo.py — Manages a per-user team of up to six Pokémon. Enforces the MAX_POKEMONES = 6 constraint and uniqueness in static methods.
  • pokedex_usuario.py — Tracks which Pokémon a given user has viewed, with a timestamp. Also uses static methods exclusively.
Because models open and close their own database connections, they can be used safely from any context — inside or outside a Flask request — without requiring the application to manage connection lifecycles.

Service Layer — services/

services/poke_api.py contains the PokeAPI class, the only component that communicates with the external PokéAPI REST API. It abstracts all HTTP request logic behind clean Python methods and implements a cache-first strategy: on startup the application checks whether the local cache_pokemon SQLite table is already populated, and only hits the network if the cache is empty. Subsequent calls for individual Pokémon also query the cache before making an outbound request.

OOP Design Principles

The Pokédex Web App demonstrates three foundational object-oriented principles in practice:
  • Encapsulation — Each class bundles its data and the operations on that data together. Pokemon owns its attributes; Equipo owns the rules for team membership; PokeAPI owns the HTTP and caching logic.
  • AbstractionPokeAPI hides all network and SQLite details behind descriptive method names. Routes in application.py call api.obtener_pokemon("pikachu") without knowing anything about HTTP, JSON parsing, or cache lookups.
  • Separation of concerns — Flask routes handle user input and template rendering only. Models handle data persistence. The service layer handles external I/O. No layer reaches into another’s responsibility.

Build docs developers (and LLMs) love