Skip to content

Commit

Permalink
Add GET Endpoints (#6)
Browse files Browse the repository at this point in the history
* Add initial route files for application structure

* Add initial route blueprints

* Add configuration management and database support

* Add route to retrieve all worlds from the database

* Add routes to retrieve player by ID and name

* Refactor response structure to include success status and original data

* Update server time route to use datetime for accurate timestamp

* Update server time response to return ISO 8601 format and refactor tests for consistency

* Add routes to retrieve player's worlds and cities by ID with error handling

* Update get_player_cities procedure call to include world parameter

* Add routes to retrieve world details, active worlds, players, and islands by world ID

* Add routes to retrieve all islands, island by ID, and cities in an island

* Update response structure to return None for empty data in add_status function

* Add routes to retrieve all cities and cities by ID; update world routes for cities in a world

* Fix variable name in get_all_cities function and add route to retrieve buildings for a city

* Add blank lines for improved readability in route files

* Add routes to retrieve all buildings, building by ID, and building prerequisites

* Add routes to retrieve units for a city and all units; include unit by ID retrieval

* Add routes to retrieve all battles, battle by ID, and units for a specific battle; add player battles retrieval

* Fix parameter name in get_player_cities route and update error handling for missing world_id

* Add unit tests for player routes including retrieval and error handling

* Add unit tests for world routes including retrieval of worlds, players, islands, and cities

* Add unit tests for island routes including retrieval of all islands, island by ID, and cities for a specific island

* Add unit tests for city routes including retrieval of all cities, city by ID, city buildings, and city units

* Remove unneccesary comments

* Add unit tests for building routes including retrieval of all buildings, building by ID, and building prerequisites

* Add unit tests for unit routes including retrieval of all units and unit by ID

* Add unit tests for battle routes including retrieval of all battles, battle by ID, and battle units

* Add testing configuration to all test modules

* Refactor test setup by consolidating fixtures into conftest.py and updating test files to use the new structure

* Remove unused 'request' import from route modules
  • Loading branch information
Vianpyro authored Nov 14, 2024
1 parent 22978bf commit 3d3ba31
Show file tree
Hide file tree
Showing 21 changed files with 896 additions and 9 deletions.
20 changes: 16 additions & 4 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
Description: This file contains a simple Flask application with two routes.
"""

import time
import datetime

from flask import Flask, jsonify, redirect

from config import Config
from routes import register_routes

app = Flask(__name__)
app.config.from_object(Config)


@app.route("/", methods=["GET"])
Expand All @@ -19,15 +23,23 @@ def home():

@app.route("/time", methods=["GET"])
def server_time():
return jsonify(server_time=time.strftime("%H:%M:%S %d/%m/%Y"))
return jsonify(server_time=datetime.datetime.now().isoformat())


# Register all routes
register_routes(app)


# Add a status field to all JSON responses
@app.after_request
def add_status(response):
if response.is_json:
original_data = response.get_json()
original_data["success"] = response.status_code == 200
response.set_data(jsonify(original_data).data)
new_response = {
"success": response.status_code == 200,
"data": original_data if original_data != [] else None,
}
response.set_data(jsonify(new_response).data)
return response


Expand Down
15 changes: 15 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import os

from dotenv import load_dotenv


# Load environment variables from .env file
load_dotenv()


class Config:
MYSQL_HOST = os.getenv("DB_HOST", "host.docker.internal")
MYSQL_USER = os.getenv("DB_USERNAME", "root")
MYSQL_PASSWORD = os.getenv("DB_PASSWORD", "myrootpassword")
MYSQL_DB = os.getenv("DB_NAME", "0ce")
MYSQL_CURSORCLASS = "DictCursor"
12 changes: 12 additions & 0 deletions db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import pymysql.cursors
from flask import current_app


def get_db_connection():
return pymysql.connect(
host=current_app.config["MYSQL_HOST"],
user=current_app.config["MYSQL_USER"],
password=current_app.config["MYSQL_PASSWORD"],
database=current_app.config["MYSQL_DB"],
cursorclass=pymysql.cursors.DictCursor,
)
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
flask>=3.0.3
pymysql>=1.1.1
pytest>=8.3.3
python-dotenv>=1.0.1
17 changes: 17 additions & 0 deletions routes/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .battle import battles_blueprint
from .building import buildings_blueprint
from .city import cities_blueprint
from .island import islands_blueprint
from .player import players_blueprint
from .unit import units_blueprint
from .world import worlds_blueprint


def register_routes(app):
app.register_blueprint(battles_blueprint, url_prefix="/battles")
app.register_blueprint(buildings_blueprint, url_prefix="/buildings")
app.register_blueprint(cities_blueprint, url_prefix="/cities")
app.register_blueprint(islands_blueprint, url_prefix="/islands")
app.register_blueprint(players_blueprint, url_prefix="/players")
app.register_blueprint(units_blueprint, url_prefix="/units")
app.register_blueprint(worlds_blueprint, url_prefix="/worlds")
38 changes: 38 additions & 0 deletions routes/battle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from flask import Blueprint, jsonify

from db import get_db_connection

battles_blueprint = Blueprint("battles", __name__)


@battles_blueprint.route("", methods=["GET"])
def get_all_battles():
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_all_battles")
battles = cursor.fetchall()
db.close()

return jsonify(battles)


@battles_blueprint.route("/<int:battle_id>", methods=["GET"])
def get_battle_by_id(battle_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_battle_by_id", (battle_id,))
battle = cursor.fetchone()
db.close()

return jsonify(battle)


@battles_blueprint.route("/<int:battle_id>/units", methods=["GET"])
def get_battle_units(battle_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_battle_units", (battle_id,))
units = cursor.fetchall()
db.close()

return jsonify(units)
38 changes: 38 additions & 0 deletions routes/building.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from flask import Blueprint, jsonify

from db import get_db_connection

buildings_blueprint = Blueprint("buildings", __name__)


@buildings_blueprint.route("", methods=["GET"])
def get_all_buildings():
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_all_buildings")
buildings = cursor.fetchall()
db.close()

return jsonify(buildings)


@buildings_blueprint.route("/<int:building_id>", methods=["GET"])
def get_building_by_id(building_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_building_by_id", (building_id,))
building = cursor.fetchone()
db.close()

return jsonify(building)


@buildings_blueprint.route("/<int:building_id>/prerequisites", methods=["GET"])
def get_building_prerequisites(building_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_building_prerequisites", (building_id,))
prerequisites = cursor.fetchall()
db.close()

return jsonify(prerequisites)
49 changes: 49 additions & 0 deletions routes/city.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from flask import Blueprint, jsonify

from db import get_db_connection

cities_blueprint = Blueprint("cities", __name__)


@cities_blueprint.route("", methods=["GET"])
def get_all_cities():
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_all_cities")
cities = cursor.fetchall()
db.close()

return jsonify(cities)


@cities_blueprint.route("/<int:city_id>", methods=["GET"])
def get_city_by_id(city_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_city_by_id", (city_id,))
city = cursor.fetchone()
db.close()

return jsonify(city)


@cities_blueprint.route("/<int:city_id>/buildings", methods=["GET"])
def get_city_buildings(city_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_city_buildings", (city_id,))
buildings = cursor.fetchall()
db.close()

return jsonify(buildings)


@cities_blueprint.route("/<int:city_id>/units", methods=["GET"])
def get_city_units(city_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_city_units", (city_id,))
units = cursor.fetchall()
db.close()

return jsonify(units)
38 changes: 38 additions & 0 deletions routes/island.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from flask import Blueprint, jsonify

from db import get_db_connection

islands_blueprint = Blueprint("islands", __name__)


@islands_blueprint.route("", methods=["GET"])
def get_all_islands():
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_all_islands")
islands = cursor.fetchall()
db.close()

return jsonify(islands)


@islands_blueprint.route("/<int:island_id>", methods=["GET"])
def get_island_by_id(island_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_island_by_id", (island_id,))
island = cursor.fetchone()
db.close()

return jsonify(island)


@islands_blueprint.route("/<int:island_id>/cities", methods=["GET"])
def get_island_cities(island_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_island_cities", (island_id,))
cities = cursor.fetchall()
db.close()

return jsonify(cities)
82 changes: 82 additions & 0 deletions routes/player.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from flask import Blueprint, jsonify, request

from db import get_db_connection

players_blueprint = Blueprint("players", __name__)


@players_blueprint.route("", methods=["GET"])
def get_all_players():
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_all_players")
players = cursor.fetchall()
db.close()

return jsonify(players)


@players_blueprint.route("/<int:player_id>", methods=["GET"])
def get_player_by_id(player_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_player_by_id", (player_id,))
player = cursor.fetchone()
db.close()

return jsonify(player)


@players_blueprint.route("/<string:player_name>", methods=["GET"])
def get_player_by_name(player_name):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_player_by_name", (player_name,))
player = cursor.fetchone()
db.close()

return jsonify(player)


@players_blueprint.route("/<int:player_id>/worlds", methods=["GET"])
def get_player_worlds(player_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_player_worlds", (player_id,))
worlds = cursor.fetchall()
db.close()

return jsonify(worlds)


@players_blueprint.route("/<int:player_id>/cities", methods=["GET"])
def get_player_cities(player_id):
world_id = request.args.get("world_id")

if not world_id:
return jsonify({"error": "Missing 'world_id' parameter"}), 400

db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc(
"get_player_cities",
(
world_id,
player_id,
),
)
cities = cursor.fetchall()
db.close()

return jsonify(cities)


@players_blueprint.route("/<int:player_id>/battles", methods=["GET"])
def get_player_battles(player_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_player_battles", (player_id,))
battles = cursor.fetchall()
db.close()

return jsonify(battles)
27 changes: 27 additions & 0 deletions routes/unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from flask import Blueprint, jsonify

from db import get_db_connection

units_blueprint = Blueprint("units", __name__)


@units_blueprint.route("", methods=["GET"])
def get_all_units():
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_all_units")
units = cursor.fetchall()
db.close()

return jsonify(units)


@units_blueprint.route("/<int:unit_id>", methods=["GET"])
def get_unit_by_id(unit_id):
db = get_db_connection()
with db.cursor() as cursor:
cursor.callproc("get_unit_by_id", (unit_id,))
unit = cursor.fetchone()
db.close()

return jsonify(unit)
Loading

0 comments on commit 3d3ba31

Please sign in to comment.