From 74a1a8458e34b0bf6c333da256381242155bba0a Mon Sep 17 00:00:00 2001 From: dede- Date: Thu, 31 Aug 2023 15:15:50 -0300 Subject: [PATCH 1/3] =?UTF-8?q?S=C3=B3=20ta=20funfando=20o=20status=20e=20?= =?UTF-8?q?o=20blur=20por=20enqunato?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FlaskAPI/.idea/.gitignore | 8 +++ FlaskAPI/.idea/FlaskAPI.iml | 19 ++++++ .../inspectionProfiles/profiles_settings.xml | 6 ++ FlaskAPI/.idea/misc.xml | 4 ++ FlaskAPI/.idea/modules.xml | 8 +++ FlaskAPI/.vscode/launch.json | 17 ++++++ FlaskAPI/.vscode/settings.json | 0 FlaskAPI/__pycache__/app.cpython-310.pyc | Bin 0 -> 394 bytes FlaskAPI/app.py | 12 ++++ FlaskAPI/blurred_temp_image.jpeg | Bin 0 -> 37339 bytes .../__pycache__/image.cpython-310.pyc | Bin 0 -> 1333 bytes .../__pycache__/status.cpython-310.pyc | Bin 0 -> 868 bytes FlaskAPI/controllers/image.py | 37 ++++++++++++ FlaskAPI/controllers/status.py | 19 ++++++ .../__pycache__/image.cpython-310.pyc | Bin 0 -> 2120 bytes FlaskAPI/services/image.py | 57 ++++++++++++++++++ .../__pycache__/image_helper.cpython-310.pyc | Bin 0 -> 549 bytes FlaskAPI/static/image_helper.py | 15 +++++ FlaskAPI/temp_image.jpeg | Bin 0 -> 44871 bytes 19 files changed, 202 insertions(+) create mode 100644 FlaskAPI/.idea/.gitignore create mode 100644 FlaskAPI/.idea/FlaskAPI.iml create mode 100644 FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 FlaskAPI/.idea/misc.xml create mode 100644 FlaskAPI/.idea/modules.xml create mode 100644 FlaskAPI/.vscode/launch.json create mode 100644 FlaskAPI/.vscode/settings.json create mode 100644 FlaskAPI/__pycache__/app.cpython-310.pyc create mode 100644 FlaskAPI/app.py create mode 100644 FlaskAPI/blurred_temp_image.jpeg create mode 100644 FlaskAPI/controllers/__pycache__/image.cpython-310.pyc create mode 100644 FlaskAPI/controllers/__pycache__/status.cpython-310.pyc create mode 100644 FlaskAPI/controllers/image.py create mode 100644 FlaskAPI/controllers/status.py create mode 100644 FlaskAPI/services/__pycache__/image.cpython-310.pyc create mode 100644 FlaskAPI/services/image.py create mode 100644 FlaskAPI/static/__pycache__/image_helper.cpython-310.pyc create mode 100644 FlaskAPI/static/image_helper.py create mode 100644 FlaskAPI/temp_image.jpeg diff --git a/FlaskAPI/.idea/.gitignore b/FlaskAPI/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/FlaskAPI/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/FlaskAPI/.idea/FlaskAPI.iml b/FlaskAPI/.idea/FlaskAPI.iml new file mode 100644 index 0000000..15b7777 --- /dev/null +++ b/FlaskAPI/.idea/FlaskAPI.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml b/FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/FlaskAPI/.idea/misc.xml b/FlaskAPI/.idea/misc.xml new file mode 100644 index 0000000..4bdfec8 --- /dev/null +++ b/FlaskAPI/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/FlaskAPI/.idea/modules.xml b/FlaskAPI/.idea/modules.xml new file mode 100644 index 0000000..6fa8fc8 --- /dev/null +++ b/FlaskAPI/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/FlaskAPI/.vscode/launch.json b/FlaskAPI/.vscode/launch.json new file mode 100644 index 0000000..6a28b4c --- /dev/null +++ b/FlaskAPI/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.0.1", + "configurations": [ + + { + "name": "Python: Flask", + "type": "python", + "request": "launch", + "module": "flask", + "env": { "FLASK_APP": "app.py", "FLASK_DEBUG": "1" }, + "args": ["run", "--no-debugger", "--no-reload"], + "jinja": true, + "justMyCode": true + } + + ] +} diff --git a/FlaskAPI/.vscode/settings.json b/FlaskAPI/.vscode/settings.json new file mode 100644 index 0000000..e69de29 diff --git a/FlaskAPI/__pycache__/app.cpython-310.pyc b/FlaskAPI/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c38168b178e75f1281a8c3bb36648202bc5e1e78 GIT binary patch literal 394 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

v~a-# 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 E0fM?laR2}S literal 0 HcmV?d00001 diff --git a/FlaskAPI/controllers/__pycache__/status.cpython-310.pyc b/FlaskAPI/controllers/__pycache__/status.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eb22a46e7922439bf9b533a18f31fedb246318e GIT binary patch literal 868 zcmZ`%y>8n;48A-4SW+C<8C&!PJT%#hwn$^NK{^-)+%AHEgKM4}+xkiGq`@9*uXzx^ zNuJ@>Oqn`#>r_&LowP;?kRT}@zmKGfsCMj;fAew96&T;y`u;0$9lrH z=BCJJ)1?hB(n{UvSzg+%DaU1HUJIOtx;C+(venid$o;)5;Qa_btEPPLEO+Wdaof1P|WN}B`}s8`8w zIk_I|Y^aO5nv^E_n2ycj{qQQ8?7>XZ40C$3w1Jefd{#=?A~2f4<*Voa(mUN%9q@GU z1@ZhvH!JZNAa41HZJoix9cFsm`VH8YYwE5E=aIe+F|?spWuE@1|%jYsLh0;W;W=B)|=9in*C5eO+}h6 oU-OAi8andvgx1qVRjU8aW`j4)O5V|rWQbOmMWW;QLC5LvKPCvg1^@s6 literal 0 HcmV?d00001 diff --git a/FlaskAPI/controllers/image.py b/FlaskAPI/controllers/image.py new file mode 100644 index 0000000..19322be --- /dev/null +++ b/FlaskAPI/controllers/image.py @@ -0,0 +1,37 @@ +import io +from services.image import ImageService +from static.image_helper import ImageHelper +from flask import request, Response, Blueprint, jsonify, send_file + +image_blueprint = Blueprint('image_blueprint', __name__) +image_service = ImageService() + + +@image_blueprint.route('/image/blur', methods=['POST']) +def blur_image(): + radius = int(request.form.get('radius')) + image = request.files.get('file') + + if radius and image: + return send_file(image_service.box_blur_image(image, radius), + mimetype='image/jpeg', + as_attachment=True, + download_name='blurred_image.jpeg') + + return jsonify(status=400, message="Bad request") + + +@image_blueprint.route('/image/load-image', methods=['POST']) +def get_simple_image(): + pass + + +@image_blueprint.route('/image/load-big-image', methods=['GET']) +def get_big_image(): + pass + + +@image_blueprint.route('/image/save-big-image', methods=['POST']) +def save_big_image(): + pass + diff --git a/FlaskAPI/controllers/status.py b/FlaskAPI/controllers/status.py new file mode 100644 index 0000000..5d777ad --- /dev/null +++ b/FlaskAPI/controllers/status.py @@ -0,0 +1,19 @@ +from flask import jsonify, Blueprint + +status_blueprint = Blueprint('status_blueprint', __name__) + + +class StatusController: + def __init__(self): + pass + + def return_ok(self): + return jsonify(status=200) + + +status_controller = StatusController() + + +@status_blueprint.route('/status/ok', methods=['GET']) +def return_ok(): + return jsonify(status=200) diff --git a/FlaskAPI/services/__pycache__/image.cpython-310.pyc b/FlaskAPI/services/__pycache__/image.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ba3a5e6771bfa8460bc807e6150668a73e74344 GIT binary patch literal 2120 zcma)7-D~4U5Z^D^vMf7}FS#U5@1beh;)j|RuJnUaQc|uQ1rs>RQQ;zF@5WK$udI}F zY*tW6UXP>yLGpNiM*j`H_9;(&xQ9Y%OK0TRiIWz(VrO=CX0)?E&5Q=6l0#tp^4D+j z=R6_5qHud~5O!cj?*oxU(k|&yk5VF;BpWu z*x!#J=<$4Y>REj?f)g_~_U7i@fxZbZd&g^{mjH=BKHvSK`F*5x)Rao951V`A_CcU~ zdwOuF+Hur;(hZ`culJrd!RAHSR#7v%U41xC*IR>AA1^Y!upg;mpo3OdVX8)TAU1`E zRjI=SU4aMX$0%oyP1#TE_iC|B%d|oT)63w}hPf~pNINj2$3PVEsDyfvR5GX=F1ZxI zp>|{rxFz$_2A-1z=>X5mB7Au_b+ZzBHoZX`GhjAwjWeqxj9U`$pp6V1C_WLX?tUgr zNd-(&+xNqM82kPfND&4o=w$Ww8TFY(8%uvSuw-qR*d& zhy4!R$KDUSsvq>!6^1=|ILpID!y1Q+2QQSy=snDJUCZee5VQ*<%}rC=D`alNAU^PT z*z0)93$MfdyU>*vbLKsGTZEVj$OxCYR8W^Py8Y*5a{qKSMg<=NVbq{Bf)?3El{vKYD`UC1@aEe2y@@YrpE1}ZMi(tG-|?gMnPZJ gGo-VU$vRo4{kIpU_LtMJzQWEEVOMa8&8v_80Y|{}wg3PC literal 0 HcmV?d00001 diff --git a/FlaskAPI/services/image.py b/FlaskAPI/services/image.py new file mode 100644 index 0000000..35da64c --- /dev/null +++ b/FlaskAPI/services/image.py @@ -0,0 +1,57 @@ +from wand.image import Image + + +def box_blur_image_separable(image, blurred_image, radius_x, radius_y): + pixels = image.get_pixels() + blurred_pixels = blurred_image.get_pixels() + + for pixel in pixels: + x, y = pixel[0], pixel[1] + + r_total, g_total, b_total = 0, 0, 0 + pixel_count = 0 + for offset_y in range(-radius_y, radius_y + 1): + for offset_x in range(-radius_x, radius_x + 1): + new_x = x + offset_x + new_y = y + offset_y + + if 0 <= new_x < image.width and 0 <= new_y < image.height: + pixel_color = pixels[new_y * image.width + new_x] + r_total += pixel_color.red + g_total += pixel_color.green + b_total += pixel_color.blue + pixel_count += 1 + + blurred_pixel = blurred_pixels[y * image.width + x] + blurred_pixel.red = int(r_total / pixel_count) + blurred_pixel.green = int(g_total / pixel_count) + blurred_pixel.blue = int(b_total / pixel_count) + + return blurred_image + + +class ImageService: + def __init__(self): + pass + + def box_blur_image(self, image, radius): + temp_path = 'temp_image.png' + image.save(temp_path) + + with Image(filename=temp_path) as img: + img.blur(radius, 2) # Apply blur directly to the image object + blurred_temp_path = 'blurred_temp_image.png' + img.save(filename=blurred_temp_path) # Save the modified image + return blurred_temp_path + + + def save_image(self, file_stream): + with open("image.png", "wb") as file: + file.write(file_stream.read()) + file.close() + + def get_simple_image(self): + return Image(filename='path_to_simple_image.png') + + def get_big_image(self): + return Image(filename='path_to_big_image.png') diff --git a/FlaskAPI/static/__pycache__/image_helper.cpython-310.pyc b/FlaskAPI/static/__pycache__/image_helper.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f8b5084a0d466eebf641cd9d2b42ad42d652de70 GIT binary patch literal 549 zcmZ`$y-ve05I#FjiJG)4D-%)&`Tz)3K*dj&s#3*bMY61()drHL#HmnO%Y(qk$b0Yv zS(#XP048ilf*{06ce+1+_uV<~blPC#_2mQ42*8^Sn&O$@*r?t&1_4P58R3M$1t3N5 z0npo0P8EIho`3+dDfIkz(+fRP`J+tE)yzgs`NrHcSp}RRaEgR`Mw#+!+%4fPBnFLD zp@X?p=}HyjKWK(E42^1L41#$<#?MgL=*N5xhKKQ$R)vmHp*n~so7qAZ*`&y?)vVO< zc`EhI$z&AkQkKaqPAqe=a5MX>O%ZN>}vxl^MYWs%)Fv19> lUE=a%bGY`MTw>pmE-YVH_!q7Uj%tcvk=b literal 0 HcmV?d00001 diff --git a/FlaskAPI/static/image_helper.py b/FlaskAPI/static/image_helper.py new file mode 100644 index 0000000..d566946 --- /dev/null +++ b/FlaskAPI/static/image_helper.py @@ -0,0 +1,15 @@ +from wand.image import Image + + +class ImageHelper: + SimpleImage = None + BigImage = None + + @staticmethod + def load_images(): + # ImageHelper.SimpleImage = Image(filename="simpleimage.png") + # ImageHelper.BigImage = Image(filename="bigimage.png") + pass + + +ImageHelper.load_images() diff --git a/FlaskAPI/temp_image.jpeg b/FlaskAPI/temp_image.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..25783da8f0a2940f339282693325054aad791752 GIT binary patch literal 44871 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 Date: Sun, 17 Sep 2023 21:55:40 -0300 Subject: [PATCH 2/3] Add load image, Dockerfile e requirements --- FlaskAPI/Dockerfile | 45 +++++++++++++++++++++++++++++++++ FlaskAPI/controllers/image.py | 18 ++++++++----- FlaskAPI/requirements.txt | 3 +++ FlaskAPI/services/image.py | 34 +++++++++++++++++-------- FlaskAPI/static/image_helper.py | 10 +++++--- 5 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 FlaskAPI/Dockerfile create mode 100644 FlaskAPI/requirements.txt diff --git a/FlaskAPI/Dockerfile b/FlaskAPI/Dockerfile new file mode 100644 index 0000000..b6a5924 --- /dev/null +++ b/FlaskAPI/Dockerfile @@ -0,0 +1,45 @@ +# syntax=docker/dockerfile:1 + +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Dockerfile reference guide at +# https://docs.docker.com/engine/reference/builder/ + +ARG PYTHON_VERSION=3.10.12 +FROM python:${PYTHON_VERSION}-slim as base + +# Prevents Python from writing pyc files. +ENV PYTHONDONTWRITEBYTECODE=1 + +# Keeps Python from buffering stdout and stderr to avoid situations where +# the application crashes without emitting any logs due to buffering. +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +# Copy the source code into the container. +COPY . . + +RUN apt-get update && apt-get install -y imagemagick && apt-get install -y wget && ls + +RUN wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \ + wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \ + wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \ + rm -rf runtimes && \ + mkdir -p ./static && \ + mv small-image.png ./static && \ + mv big-image.png ./static && \ + mv video.mp4 ./static + +# Download dependencies as a separate step to take advantage of Docker's caching. +# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds. +# Leverage a bind mount to requirements.txt to avoid having to copy them into +# into this layer. +RUN --mount=type=cache,target=/root/.cache/pip \ + --mount=type=bind,source=requirements.txt,target=requirements.txt \ + python -m pip install -r requirements.txt + +# Expose the port that the application listens on. +EXPOSE 5000 + +# Run the application. +CMD gunicorn 'app:app' --bind=0.0.0.0:5000 diff --git a/FlaskAPI/controllers/image.py b/FlaskAPI/controllers/image.py index 19322be..4083088 100644 --- a/FlaskAPI/controllers/image.py +++ b/FlaskAPI/controllers/image.py @@ -1,4 +1,3 @@ -import io from services.image import ImageService from static.image_helper import ImageHelper from flask import request, Response, Blueprint, jsonify, send_file @@ -18,20 +17,25 @@ def blur_image(): as_attachment=True, download_name='blurred_image.jpeg') - return jsonify(status=400, message="Bad request") + return "Bad request", 400 -@image_blueprint.route('/image/load-image', methods=['POST']) +@image_blueprint.route('/image/load-small-image', methods=['GET']) def get_simple_image(): - pass + return send_file(image_service.get_simple_image(), + mimetype='image/png', + as_attachment=True, + download_name='small-image.png') @image_blueprint.route('/image/load-big-image', methods=['GET']) def get_big_image(): - pass + return send_file(image_service.get_big_image(), + mimetype='image/png', + as_attachment=True, + download_name='big-image.png') @image_blueprint.route('/image/save-big-image', methods=['POST']) -def save_big_image(): +def save_image(): pass - diff --git a/FlaskAPI/requirements.txt b/FlaskAPI/requirements.txt new file mode 100644 index 0000000..20ce748 --- /dev/null +++ b/FlaskAPI/requirements.txt @@ -0,0 +1,3 @@ +Flask>=1.0 +gunicorn>=19.9.0 +Wand \ No newline at end of file diff --git a/FlaskAPI/services/image.py b/FlaskAPI/services/image.py index 35da64c..6dea1da 100644 --- a/FlaskAPI/services/image.py +++ b/FlaskAPI/services/image.py @@ -1,5 +1,7 @@ from wand.image import Image +from static.image_helper import ImageHelper + def box_blur_image_separable(image, blurred_image, radius_x, radius_y): pixels = image.get_pixels() @@ -30,28 +32,38 @@ def box_blur_image_separable(image, blurred_image, radius_x, radius_y): return blurred_image +def save_image(file_stream): + with open("image.png", "wb") as file: + file.write(file_stream.read()) + file.close() + + class ImageService: def __init__(self): pass - def box_blur_image(self, image, radius): + def box_blur_image(self, img, radius): temp_path = 'temp_image.png' - image.save(temp_path) + img.save(temp_path) with Image(filename=temp_path) as img: - img.blur(radius, 2) # Apply blur directly to the image object + img.blur(radius, 2) blurred_temp_path = 'blurred_temp_image.png' - img.save(filename=blurred_temp_path) # Save the modified image + img.save(filename='blurred_temp_image.png') return blurred_temp_path - def save_image(self, file_stream): - with open("image.png", "wb") as file: - file.write(file_stream.read()) - file.close() - def get_simple_image(self): - return Image(filename='path_to_simple_image.png') + with ImageHelper.SimpleImage as img: + img = ImageHelper.SimpleImage + simple_image = 'simple_image.png' + img.save(filename='simple_image.png') + return simple_image + def get_big_image(self): - return Image(filename='path_to_big_image.png') + with ImageHelper.BigImage as img: + img = ImageHelper.BigImage + big_image = 'big_image.png' + img.save(filename='big_image.png') + return big_image diff --git a/FlaskAPI/static/image_helper.py b/FlaskAPI/static/image_helper.py index d566946..63aba27 100644 --- a/FlaskAPI/static/image_helper.py +++ b/FlaskAPI/static/image_helper.py @@ -7,9 +7,11 @@ class ImageHelper: @staticmethod def load_images(): - # ImageHelper.SimpleImage = Image(filename="simpleimage.png") - # ImageHelper.BigImage = Image(filename="bigimage.png") + ImageHelper.SimpleImage = Image(filename="./static/small-image.png") + #ImageHelper.SimpleImage.save(filename="./static/small-image.png") + + ImageHelper.BigImage = Image(filename="./static/big-image.png") + #ImageHelper.BigImage.save(filename="./static/big-image.png") pass - -ImageHelper.load_images() +ImageHelper.load_images() \ No newline at end of file From 8d9c1598a25fa30137cad32de6ee201467dd3276 Mon Sep 17 00:00:00 2001 From: dede- Date: Sun, 17 Sep 2023 22:37:18 -0300 Subject: [PATCH 3/3] Add load image, Dockerfile e requirements --- .idea/.gitignore | 8 +++ .../inspectionProfiles/profiles_settings.xml | 6 +++ .idea/misc.xml | 4 ++ .idea/modules.xml | 8 +++ .idea/tcc.iml | 8 +++ .idea/vcs.xml | 6 +++ FlaskAPI/.dockerignore | 34 +++++++++++++ FlaskAPI/compose.yaml | 49 +++++++++++++++++++ 8 files changed, 123 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/tcc.iml create mode 100644 .idea/vcs.xml create mode 100644 FlaskAPI/.dockerignore create mode 100644 FlaskAPI/compose.yaml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..dc9ea49 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..69b43c1 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/tcc.iml b/.idea/tcc.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/tcc.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/FlaskAPI/.dockerignore b/FlaskAPI/.dockerignore new file mode 100644 index 0000000..3edb0b5 --- /dev/null +++ b/FlaskAPI/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/FlaskAPI/compose.yaml b/FlaskAPI/compose.yaml new file mode 100644 index 0000000..94e7d9c --- /dev/null +++ b/FlaskAPI/compose.yaml @@ -0,0 +1,49 @@ +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Docker compose reference guide at +# https://docs.docker.com/compose/compose-file/ + +# Here the instructions define your application as a service called "server". +# This service is built from the Dockerfile in the current directory. +# You can add other services your application may depend on here, such as a +# database or a cache. For examples, see the Awesome Compose repository: +# https://github.com/docker/awesome-compose +services: + server: + build: + context: . + ports: + - 5000:5000 + +# The commented out section below is an example of how to define a PostgreSQL +# database that your application can use. `depends_on` tells Docker Compose to +# start the database before your application. The `db-data` volume persists the +# database data between container restarts. The `db-password` secret is used +# to set the database password. You must create `db/password.txt` and add +# a password of your choosing to it before running `docker compose up`. +# depends_on: +# db: +# condition: service_healthy +# db: +# image: postgres +# restart: always +# user: postgres +# secrets: +# - db-password +# volumes: +# - db-data:/var/lib/postgresql/data +# environment: +# - POSTGRES_DB=example +# - POSTGRES_PASSWORD_FILE=/run/secrets/db-password +# expose: +# - 5432 +# healthcheck: +# test: [ "CMD", "pg_isready" ] +# interval: 10s +# timeout: 5s +# retries: 5 +# volumes: +# db-data: +# secrets: +# db-password: +# file: db/password.txt +