diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0681275 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,46 @@ +# Git +.git +.gitignore + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual Environment +venv/ +ENV/ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# Docker +Dockerfile +.dockerignore + +# Logs +*.log + +# Local development +.env +.env.local \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68b389a..acdfed8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,4 +29,4 @@ jobs: - name: Run tests run: | - pytest tests/ \ No newline at end of file + pytest tests/ --ignore=tests/manual \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 586cdfe..df74a89 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,12 +4,21 @@ FROM python:3.11-slim # Set working directory WORKDIR /app -# Copy project files -COPY . . +# Install system dependencies required for OpenCV +RUN apt-get update && apt-get install -y \ + libgl1-mesa-glx \ + libglib2.0-0 \ + && rm -rf /var/lib/apt/lists/* + +# Copy only requirements first to leverage Docker cache +COPY requirements.txt . -# Install dependencies +# Install Python dependencies RUN pip install --no-cache-dir -r requirements.txt +# Copy the rest of the application +COPY . . + # Expose the port the app runs on EXPOSE 5000 diff --git a/Makefile b/Makefile index 7de0b27..27a0ee8 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,13 @@ train: python app/model/train_color_model.py test: - pytest tests/ + pytest tests/ --ignore=tests/manual coverage: - coverage run -m pytest tests/ + coverage run -m pytest tests/ --ignore=tests/manual coverage report coverage html docker-test: docker build -t rubik-api . - docker run --rm rubik-api pytest tests/ + docker run --rm rubik-api pytest tests/ --ignore=tests/manual diff --git a/app/cube_recognition.py b/app/cube_recognition.py index 855c059..608b06f 100644 --- a/app/cube_recognition.py +++ b/app/cube_recognition.py @@ -2,10 +2,6 @@ import numpy as np from .color_detection import detect_colors -# Rubik's cube face labels in standard order -FACE_ORDER = ['U', 'R', 'F', 'D', 'L', 'B'] - - def generate_cube_string(images): cube_string = '' diff --git a/app/routes.py b/app/routes.py index 5098a2b..768c82d 100644 --- a/app/routes.py +++ b/app/routes.py @@ -3,6 +3,10 @@ main = Blueprint('main', __name__) +@main.route('/', methods=['GET']) +def health_check(): + return jsonify({'status': 'API is running'}), 200 + @main.route('/cubeFacesToCubeString', methods=['POST']) def upload_faces(): if 'images' not in request.files: diff --git a/run.py b/run.py index a3fdaf3..8640e59 100644 --- a/run.py +++ b/run.py @@ -3,4 +3,4 @@ app = create_app() if __name__ == '__main__': - app.run(debug=True) + app.run(host='0.0.0.0', debug=True) diff --git a/tests/images/back.png b/tests/images/back.png new file mode 100644 index 0000000..6160782 Binary files /dev/null and b/tests/images/back.png differ diff --git a/tests/images/down.png b/tests/images/down.png new file mode 100644 index 0000000..a65761d Binary files /dev/null and b/tests/images/down.png differ diff --git a/tests/images/front.png b/tests/images/front.png new file mode 100644 index 0000000..47c14cc Binary files /dev/null and b/tests/images/front.png differ diff --git a/tests/images/left.png b/tests/images/left.png new file mode 100644 index 0000000..13f8600 Binary files /dev/null and b/tests/images/left.png differ diff --git a/tests/images/right.png b/tests/images/right.png new file mode 100644 index 0000000..2de6b8f Binary files /dev/null and b/tests/images/right.png differ diff --git a/tests/images/up.png b/tests/images/up.png new file mode 100644 index 0000000..e6e680c Binary files /dev/null and b/tests/images/up.png differ diff --git a/tests/manual/test_api.py b/tests/manual/test_api.py new file mode 100644 index 0000000..abde09a --- /dev/null +++ b/tests/manual/test_api.py @@ -0,0 +1,45 @@ +import requests +import os + +def test_api(): + url = 'http://localhost:5000/cubeFacesToCubeString' + + image_files = [ + 'tests/images/up.png', + 'tests/images/right.png', + 'tests/images/front.png', + 'tests/images/down.png', + 'tests/images/left.png', + 'tests/images/back.png' + ] + + for img_file in image_files: + if not os.path.exists(img_file): + print(f"Erreur: Le fichier {img_file} n'existe pas") + return + + files = [] + for img_file in image_files: + files.append(('images', (os.path.basename(img_file), open(img_file, 'rb'), 'image/png'))) + + try: + response = requests.post(url, files=files) + + if response.status_code == 200: + result = response.json() + print("Succès! Réponse de l'API:") + print(f"Cube string: {result.get('cube_string')}") + else: + print(f"Erreur: {response.status_code}") + print(response.text) + + except requests.exceptions.RequestException as e: + print(f"Erreur de connexion: {e}") + assert False, f"API connection failed: {e}" + + finally: + for _, (_, file, _) in files: + file.close() + +if __name__ == '__main__': + test_api() \ No newline at end of file