Flask app init
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
name: Build, push image, and notify Watchtower
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main # Only triggers the build on the main branch
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Login to Gitea Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: git.matthiasg.dev
|
||||||
|
username: ninluc
|
||||||
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
- name: Cache Docker layers
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: buildx-cache-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
buildx-cache-
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
run: |
|
||||||
|
docker build -t git.matthiasg.dev/ninluc/smartwave-api:latest .
|
||||||
|
docker push git.matthiasg.dev/ninluc/smartwave-api:latest
|
||||||
|
|
||||||
|
notify:
|
||||||
|
needs: build-image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Notify Watchtower
|
||||||
|
run: "curl -i -X POST -H \"Authorization: Bearer ${{ secrets.WATCHTOWER_TOKEN }}\" https://watchtower.beermaker.matthiasg.dev/v1/update"
|
||||||
@@ -1 +1,2 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
|
orchestrateur/db.sqlite-shm
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Use a lightweight Python 3.11 image
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Set the working directory inside the container
|
||||||
|
WORKDIR /cloud
|
||||||
|
|
||||||
|
# Copy the requirements file and install dependencies
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy the rest of the application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Ensure the photo storage directory exists so the app doesn't crash on startup
|
||||||
|
RUN mkdir -p storage/dishPhotos
|
||||||
|
|
||||||
|
# Expose the port the app will run on
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Use Gunicorn to run the application in production
|
||||||
|
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
|
||||||
+89
-2
@@ -1,7 +1,94 @@
|
|||||||
from flask import Flask
|
import os
|
||||||
|
import base64
|
||||||
|
import uuid
|
||||||
|
from flask import Flask, request, jsonify
|
||||||
|
from pymongo import MongoClient
|
||||||
|
|
||||||
|
# Import your shared device types
|
||||||
|
from shared import deviceTypes
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# Configuration & Setup
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
# Configure MongoDB connection (adjust the URI as needed for your environment)
|
||||||
|
client = MongoClient("mongodb://localhost:27017/")
|
||||||
|
db = client["microwave_network_db"]
|
||||||
|
cooking_collection = db["cooking_parameters"]
|
||||||
|
device_network_collection = db["device_network"]
|
||||||
|
|
||||||
|
# Ensure the photo storage directory exists when the app starts
|
||||||
|
PHOTO_DIR = "storage/dishPhotos"
|
||||||
|
os.makedirs(PHOTO_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# Routes
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def hello_world():
|
def hello_world():
|
||||||
return "<p>Hello, World!</p>"
|
return "<p>Hello, World!</p>"
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/cooking-params", methods=["POST"])
|
||||||
|
def cooking_params():
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return jsonify({"error": "Invalid or missing JSON payload"}), 400
|
||||||
|
|
||||||
|
# 1. Handle the Photo
|
||||||
|
photo_b64 = data.get("photo")
|
||||||
|
if photo_b64:
|
||||||
|
# Generate a unique filename using UUID to avoid overwriting
|
||||||
|
filename = f"dish_{uuid.uuid4().hex}.jpg"
|
||||||
|
filepath = os.path.join(PHOTO_DIR, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Decode the base64 string and save it as a binary file
|
||||||
|
with open(filepath, "wb") as f:
|
||||||
|
f.write(base64.b64decode(photo_b64))
|
||||||
|
|
||||||
|
# Replace the giant base64 string in the dictionary with the local file path
|
||||||
|
# so we don't bloat the MongoDB document
|
||||||
|
data["photo"] = filepath
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": f"Failed to save photo: {str(e)}"}), 500
|
||||||
|
|
||||||
|
# 2. Save to MongoDB
|
||||||
|
try:
|
||||||
|
# Insert the dictionary directly into Mongo (it will retain your exact JSON keys)
|
||||||
|
cooking_collection.insert_one(data)
|
||||||
|
|
||||||
|
# Remove the Mongo-injected '_id' object before returning the response
|
||||||
|
data.pop("_id", None)
|
||||||
|
return jsonify({"message": "Cooking parameters saved successfully", "data": data}), 201
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": f"Database error: {str(e)}"}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/device-network", methods=["POST"])
|
||||||
|
def device_network():
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
return jsonify({"error": "Invalid or missing JSON payload"}), 400
|
||||||
|
|
||||||
|
|
||||||
|
# 2. Save to MongoDB
|
||||||
|
try:
|
||||||
|
# Insert the dictionary directly into Mongo (it will retain your exact JSON keys)
|
||||||
|
device_network_collection.insert_one(data)
|
||||||
|
|
||||||
|
return "", 200
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": f"Database error: {str(e)}"}), 500
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(debug=True)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Flask==3.0.2
|
||||||
|
pymongo==4.6.1
|
||||||
|
gunicorn==21.2.0
|
||||||
Reference in New Issue
Block a user