diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..1453c54 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1 @@ +**/*.env \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..07ad0f5 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.13-slim-bookworm + +ENV PYTHONPATH=/usr/local/lib + +COPY . /app +WORKDIR /app + +RUN pip3 install -r requirements.txt + +CMD ["/bin/sh", "entrypoint.sh"] \ No newline at end of file diff --git a/backend/entrypoint.sh b/backend/entrypoint.sh new file mode 100755 index 0000000..7f21834 --- /dev/null +++ b/backend/entrypoint.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +python3 -m flask \ +--app /app/src/server.py \ +run --host=0.0.0.0 \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..228de33 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,3 @@ +flask==3.0.2 +mysql-connector-python==9.4.0 +python_dotenv==1.1.1 \ No newline at end of file diff --git a/backend/run.sh b/backend/run.sh new file mode 100755 index 0000000..52def0f --- /dev/null +++ b/backend/run.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Generate a random name for the container using uuidgen +container_name=$(uuidgen) + +# Build the Docker image with your project code and unit tests +docker build -t nyi-backend -f Dockerfile . + +# Run the Docker container with the unit tests and attach the output +docker run --tty --rm --name "$container_name" -p 2027:5000 nyi-backend + +# Exit the script with the exit code of the container +exit $? diff --git a/backend/src/db_client.py b/backend/src/db_client.py new file mode 100644 index 0000000..348499a --- /dev/null +++ b/backend/src/db_client.py @@ -0,0 +1,65 @@ + +#!/usr/bin/env python +# encoding: utf-8 + +''' +db_client.py is the module for managing teh Dungeon's database services. +''' + +import mysql.connector +import os + +class DBClient: + def __init__(self): + self.db_server = os.environ.get('DB_SERVER') + self.db_port = os.environ.get('DB_PORT') + self.user = 'root' + self.password = os.environ.get('ROOT_PWD') + self.database = os.environ.get('DB_NAME') + + if not self.db_server: + raise ValueError("Environment variable 'DB_SERVER' is not set.") + if not self.db_port: + raise ValueError("Environment variable 'DB_PORT' is not set.") + if not self.password: + raise ValueError("Environment variable 'ROOT_PWD' is not set.") + if not self.database: + raise ValueError("Environment variable 'DB_NAME' is not set.") + + self.connection = mysql.connector.connect( + host=self.db_server, + port=self.db_port, + user=self.user, + password=self.password, + database=self.database + ) + + self.cursor = self.connection.cursor() + self.initialize_database() + + def create_database(self, db_name): + query = f"CREATE DATABASE IF NOT EXISTS `{db_name}`;" + self.cursor.execute(query) + + def switch_database(self, db_name): + self.connection.database = db_name + + def initialize_database(self): + self.create_database(self.database) + self.switch_database(self.database) + self.query("""CREATE TABLE IF NOT EXISTS users ( + Name varchar(255), + Attendance bool, + HasCar bool + );""") + + def query(self, query_str, quiet=False): + self.cursor.execute(query_str) + if quiet: + return [] + return self.cursor.fetchall() + + def close(self): + self.cursor.close() + self.connection.close() + diff --git a/backend/src/server.py b/backend/src/server.py new file mode 100644 index 0000000..7493622 --- /dev/null +++ b/backend/src/server.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# encoding: utf-8 + +''' +server.py is the main source file for the Dungeon's backend service. +''' + +from flask import Flask, request, jsonify +from dotenv import load_dotenv +from db_client import DBClient + +load_dotenv() +app = Flask(__name__) +database = DBClient() + +@app.route('/login', methods=['POST']) +def login(): + if request.is_json: + return request.json, 200 + else: + return jsonify({'error': 'Request must contain JSON data'}), 400 + +if __name__ == "__main__": + app.run(debug=True) \ No newline at end of file