generated from nyu-software-engineering/containerized-app-exercise
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
744 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: CI/CD Workflow | ||
name: Web App (CI/CD) | ||
|
||
on: | ||
pull_request: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,21 @@ | ||
version: 'version 1.0.0' | ||
services: | ||
webapp: | ||
|
||
web: | ||
build: ./web-app | ||
ports: | ||
- "5000:5000" | ||
depends_on: | ||
- mongodb | ||
networks: | ||
- mongonetwork | ||
mlc: | ||
|
||
build: ./machine-learning-client | ||
|
||
mongodb: | ||
|
||
volumes: | ||
mongodata: | ||
|
||
networks: | ||
mongonetwork: | ||
#driver: bridge |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,9 @@ name = "pypi" | |
[packages] | ||
pylint = "*" | ||
black = "*" | ||
flask = "*" | ||
pymongo = "*" | ||
cv2 = "*" | ||
|
||
[dev-packages] | ||
|
||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,70 @@ | ||
""" | ||
Pymongo: Connecting to MongoDB via Python | ||
Flask: Python web framework | ||
Werkzeug: WSGI utility library for Python | ||
Base64: Encode and decode images | ||
""" | ||
import base64 | ||
from flask import Flask, render_template, request, jsonify | ||
from pymongo import MongoClient | ||
from werkzeug.utils import secure_filename | ||
import os | ||
|
||
|
||
app = Flask(__name__) | ||
app.config['SECRET_KEY'] = 'you-will-never-guess' | ||
db = MongoClient('mongodb://localhost:27017/')['webapp'] | ||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} | ||
app.config["SECRET_KEY"] = "you-will-never-guess" | ||
app.config["MONGO_CONN"] = MongoClient("mongodb://localhost:27017/") | ||
|
||
client = app.config["MONGO_CONN"] | ||
db = client["emotion_detection"] | ||
collection = db["emotion_images"] | ||
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif"} | ||
|
||
|
||
def allowed_file(filename): | ||
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | ||
"""Check if the file extension is allowed""" | ||
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS | ||
|
||
@app.route('/') | ||
|
||
@app.route("/") | ||
def index(): | ||
return render_template('index.html') | ||
#can u edit the upload files method to insert the image, probably encoded, into the db | ||
@app.route('/upload', methods=['POST']) | ||
"""Render the index.html template""" | ||
return render_template("index.html") | ||
|
||
count = 0 | ||
@app.route("/upload", methods=["POST"]) | ||
def upload_file(): | ||
if 'photo' in request.files: | ||
photo = request.files['photo'] | ||
if photo.filename == '': | ||
return jsonify({'message': 'No file selected'}) | ||
if photo and allowed_file(photo.filename): | ||
filename = secure_filename(photo.filename) | ||
# Process and store the photo | ||
photo_data = photo.read() | ||
encoded_photo = Binary(photo_data) | ||
db.photos.insert_one({'photo': encoded_photo}) | ||
|
||
#Placeholder: send photo to ML model and get results | ||
results = "results from ml model" | ||
return jsonify({'message': 'File uploaded successfully', 'results': results}) | ||
"""Upload image file and send it to the ML model for processing""" | ||
print(request) | ||
global count | ||
if "photo" in request.files: | ||
photo = request.files["photo"] | ||
name = request.form.get("name") | ||
if not name: | ||
name = f"image_{count}" | ||
count += 1 | ||
print(photo.filename, name) | ||
if photo.filename == "": | ||
return jsonify({"message": "No file selected"}) | ||
if photo: #and allowed_file(photo.filename): | ||
image_data = photo.read() | ||
encoded = base64.b64encode(image_data).decode('utf-8') | ||
ins = { | ||
"name": name, | ||
"emotion": "", | ||
"is_processed": False, | ||
"photo": encoded, | ||
} | ||
collection.insert_one(ins) | ||
while collection.find_one({"processed": True}) is None: | ||
pass | ||
retrieved = collection.find_one_and_delete({}) | ||
name, emotion_message = retrieved["name"], retrieved["emotion"] | ||
result = f"Image: {name}\nEmotion: {emotion_message}" | ||
|
||
else: | ||
return jsonify({'message': 'Invalid file type'}) | ||
return jsonify({'message': 'No file Uploaded'}) | ||
return jsonify({"message": "Invalid file type"}) | ||
return jsonify({"message": "No file Uploaded"}) | ||
|
||
|
||
|
||
if __name__ == '__main__': | ||
if __name__ == "__main__": | ||
app.run(debug=True) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,5 @@ Jinja2==3.1.3 | |
MarkupSafe==2.1.5 | ||
pymongo==4.6.3 | ||
Werkzeug==3.0.2 | ||
base64==1.0.0 | ||
zipp==3.18.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# test_main.py | ||
import pytest | ||
from flask import url_for | ||
from io import BytesIO | ||
from web_app.main import app | ||
|
||
|
||
@pytest.fixture | ||
def client(): | ||
app.config['TESTING'] = True | ||
with app.test_client() as client: | ||
yield client | ||
|
||
def test_index(client): | ||
response = client.get(url_for('index')) | ||
assert response.status_code == 200 | ||
|
||
def test_upload_file_no_file(client): | ||
response = client.post(url_for('upload_file')) | ||
assert response.status_code == 200 | ||
assert response.get_json() == {'message': 'No file uploaded'} | ||
|
||
def test_upload_file_with_file(client): | ||
data = { | ||
'photo': (BytesIO(b'my file contents'), 'test.jpg') | ||
} | ||
response = client.post(url_for('upload_file'), content_type='multipart/form-data', data=data) | ||
assert response.status_code == 200 | ||
assert 'message' in response.get_json() | ||
assert 'results' in response.get_json() | ||
@pytest.fixture | ||
def client(): | ||
app.config['TESTING'] = True | ||
with app.test_client() as client: | ||
yield client | ||
|
||
def test_index(client): | ||
response = client.get(url_for('index')) | ||
assert response.status_code == 200 | ||
|
||
def test_upload_file_no_file(client): | ||
response = client.post(url_for('upload_file')) | ||
assert response.status_code == 200 | ||
assert response.get_json() == {'message': 'No file uploaded'} | ||
|
||
def test_upload_file_with_file(client): | ||
data = { | ||
'photo': (BytesIO(b'my file contents'), 'test.jpg') | ||
} | ||
response = client.post(url_for('upload_file'), content_type='multipart/form-data', data=data) | ||
assert response.status_code == 200 | ||
assert 'message' in response.get_json() | ||
assert 'results' in response.get_json() |