commit 62f3ae7881e4caf3255ff249a1086f2fd743983b Author: Dennis Kerschus Date: Sat Aug 10 20:26:57 2024 +0200 Initial diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4aa6345 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +__pycache__ +*.pyc +*.pyo +*.pyd +*.db +*.sqlite +*.log +*.env diff --git a/.env b/.env new file mode 100644 index 0000000..44a4060 --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ +FLASK_APP=run.py +FLASK_ENV=development +SECRET_KEY=your-secret-key +SQLALCHEMY_DATABASE_URI=sqlite:///development.db diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c48115d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Use the official image as a parent image +FROM python:3.9-slim + +# Set the working directory in the container +WORKDIR /app + +# Copy the current directory contents into the container at /app +COPY . /app + +# Install any needed packages specified in requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +# Make port 5000 available to the world outside this container +EXPOSE 5000 + +# Define environment variable +ENV FLASK_APP wsgi.py + +# Run app.py when the container launches +CMD ["gunicorn", "--bind", "0.0.0.0:5000", "wsgi:app"] diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/app.py b/app/app.py new file mode 100644 index 0000000..afbeeb0 --- /dev/null +++ b/app/app.py @@ -0,0 +1,25 @@ +from flask import Flask +from app.config.config import get_config_by_name +from app.initialize_functions import initialize_route,initialize_db + +def create_app(config=None) -> Flask: + """ + Create a Flask application. + + Args: + config: The configuration object to use. + + Returns: + A Flask application instance. + """ + app = Flask(__name__) + if config: + app.config.from_object(get_config_by_name(config)) + + # Initialize extensions + initialize_db(app) + + # Register blueprints + initialize_route(app) + + return app diff --git a/app/config/__init__.py b/app/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/config/config.py b/app/config/config.py new file mode 100644 index 0000000..15f525e --- /dev/null +++ b/app/config/config.py @@ -0,0 +1,34 @@ +class BaseConfig: + """Base configuration.""" + DEBUG = False + TESTING = False + SQLALCHEMY_TRACK_MODIFICATIONS = False + SECRET_KEY = 'your-secret-key' + +class DevelopmentConfig(BaseConfig): + """Development configuration.""" + DEBUG = True + SQLALCHEMY_DATABASE_URI = 'sqlite:///development.db' + +class TestingConfig(BaseConfig): + """Testing configuration.""" + DEBUG = True + TESTING = True + SQLALCHEMY_DATABASE_URI = 'sqlite:///testing.db' + +class ProductionConfig(BaseConfig): + """Production configuration.""" + DEBUG = False + SQLALCHEMY_DATABASE_URI = 'sqlite:///production.db' + + +def get_config_by_name(config_name): + """ Get config by name """ + if config_name == 'development': + return DevelopmentConfig() + elif config_name == 'production': + return ProductionConfig() + elif config_name == 'testing': + return TestingConfig() + else: + return DevelopmentConfig() diff --git a/app/db/__init__.py b/app/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/db/db.py b/app/db/db.py new file mode 100644 index 0000000..86ff1da --- /dev/null +++ b/app/db/db.py @@ -0,0 +1,9 @@ +from flask_sqlalchemy import SQLAlchemy +from sqlalchemy.orm import DeclarativeBase + + +class Base(DeclarativeBase): + pass + + +db = SQLAlchemy(model_class=Base) diff --git a/app/initialize_functions.py b/app/initialize_functions.py new file mode 100644 index 0000000..2585fa8 --- /dev/null +++ b/app/initialize_functions.py @@ -0,0 +1,14 @@ +from flask import Flask +from app.modules.main.route import main_bp +from app.db.db import db + + +def initialize_route(app: Flask): + with app.app_context(): + app.register_blueprint(main_bp) + + +def initialize_db(app: Flask): + with app.app_context(): + db.init_app(app) + db.create_all() diff --git a/app/modules/__init__.py b/app/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/modules/main/__init__.py b/app/modules/main/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/modules/main/controller.py b/app/modules/main/controller.py new file mode 100644 index 0000000..0d067e4 --- /dev/null +++ b/app/modules/main/controller.py @@ -0,0 +1,3 @@ +class MainController: + def index(self): + return {'message':'Hello, World!'} diff --git a/app/modules/main/main_tests.py b/app/modules/main/main_tests.py new file mode 100644 index 0000000..b04143e --- /dev/null +++ b/app/modules/main/main_tests.py @@ -0,0 +1,10 @@ +import unittest +import json + +from app.modules.main.controller import MainController + + +def test_index(): + main_controller = MainController() + result = main_controller.index() + assert result == {'message': 'Hello, World!'} diff --git a/app/modules/main/route.py b/app/modules/main/route.py new file mode 100644 index 0000000..c693aeb --- /dev/null +++ b/app/modules/main/route.py @@ -0,0 +1,11 @@ +from flask import Blueprint, make_response, jsonify +from .controller import MainController + +main_bp = Blueprint('main', __name__) + +main_controller = MainController() + +@main_bp.route('/') +def index(): + result=main_controller.index() + return make_response(jsonify(data=result)) diff --git a/app/tests/__init__.py b/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/conftest.py b/app/tests/conftest.py new file mode 100644 index 0000000..5d73f5e --- /dev/null +++ b/app/tests/conftest.py @@ -0,0 +1,15 @@ +import pytest + +from app.app import create_app + + +@pytest.fixture +def app(): + app = create_app('testing') + app.config.update({"TESTING": True}) + yield app + + +@pytest.fixture +def client(app): + return app.test_client() \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..03da356 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.8' + +services: + web: + build: . + command: gunicorn --bind 0.0.0.0:5000 wsgi:app + volumes: + - .:/app + ports: + - "5000:5000" + environment: + - FLASK_ENV=production diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..df5dbfd --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Flask +Flask-SQLAlchemy +python-dotenv +pytest +gunicorn diff --git a/run.py b/run.py new file mode 100644 index 0000000..79e6975 --- /dev/null +++ b/run.py @@ -0,0 +1,16 @@ +import os +from dotenv import load_dotenv +from app.app import create_app + +load_dotenv() + +config=os.getenv('FLASK_ENV') or 'development' + +app = create_app(config) + +if __name__ == "__main__": + if config == 'development': + app.run(debug=True) + else: + from werkzeug.serving import run_simple + run_simple('0.0.0.0', 5000, app) diff --git a/wsgi.py b/wsgi.py new file mode 100644 index 0000000..89d6421 --- /dev/null +++ b/wsgi.py @@ -0,0 +1,3 @@ +from app.app import create_app + +app = create_app('production')