Skip to content

Commit e42aa27

Browse files
Merge pull request #594 from DefangLabs/jordan/strands-dockerfile
Create a Dockerfile for strands sample
0 parents  commit e42aa27

7 files changed

Lines changed: 328 additions & 0 deletions

File tree

.github/workflows/deploy.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
deploy:
10+
environment: playground
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
id-token: write
15+
16+
steps:
17+
- name: Checkout Repo
18+
uses: actions/checkout@v4
19+
20+
- name: Deploy
21+
uses: DefangLabs/defang-github-action@v1.3.2

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Flask & Form Submission
2+
3+
[![1-click-deploy](https://raw.githubusercontent.com/DefangLabs/defang-assets/main/Logos/Buttons/SVG/deploy-with-defang.svg)](https://portal.defang.dev/redirect?url=https%3A%2F%2Fgithub.com%2Fnew%3Ftemplate_name%3Dsample-python-form-template%26template_owner%3DDefangSamples)
4+
5+
This Flask application provides a basic example of handling form submissions. It displays an HTML form where users can input their first name. Upon submission, the application greets the user by name on a new page. Note that alognside your .py file, include a requirements.txt so that the Dockerfile can install the necessary packages with pip.
6+
7+
## Essential Setup Files
8+
9+
1. A [Dockerfile](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).
10+
2. A [compose file](https://docs.defang.io/docs/concepts/compose) to define and run multi-container Docker applications (this is how Defang identifies services to be deployed). (compose.yaml file)
11+
12+
## Prerequisite
13+
14+
1. Download [Defang CLI](https://github.com/DefangLabs/defang)
15+
2. If you are using [Defang BYOC](https://docs.defang.io/docs/concepts/defang-byoc), make sure you have properly [authenticated your AWS account (optional)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)
16+
17+
## A Step-by-Step Guide
18+
19+
1. Open the terminal and type `defang login`
20+
2. Type `defang compose up` in the CLI
21+
3. Your app should be up and running with Defang in minutes!
22+
23+
---
24+
25+
Title: Python & Form
26+
27+
Short Description: A short Python example for form submission in Flask.
28+
29+
Tags: Python, Flask, Form
30+
31+
Languages: python

app/.gitignore

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
2+
# --- Python ---
3+
# Byte-compiled / optimized / DLL files
4+
__pycache__/
5+
*.py[cod]
6+
*$py.class
7+
8+
# C extensions
9+
*.so
10+
11+
# Distribution / packaging
12+
.Python
13+
build/
14+
develop-eggs/
15+
dist/
16+
downloads/
17+
eggs/
18+
.eggs/
19+
lib/
20+
lib64/
21+
parts/
22+
sdist/
23+
var/
24+
wheels/
25+
share/python-wheels/
26+
*.egg-info/
27+
.installed.cfg
28+
*.egg
29+
MANIFEST
30+
31+
# PyInstaller
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.nox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
*.py,cover
50+
.hypothesis/
51+
.pytest_cache/
52+
cover/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-cache
67+
68+
# Scrapy stuff:
69+
.scrapy
70+
71+
# Sphinx documentation
72+
docs/_build/
73+
74+
# PyBuilder
75+
.pybuilder/
76+
target/
77+
78+
# Jupyter Notebook
79+
.ipynb_checkpoints
80+
81+
# IPython
82+
profile_default/
83+
ipython_config.py
84+
85+
# pdm
86+
.pdm.toml
87+
.pdm-python
88+
.pdm-build/
89+
90+
# PEP 582
91+
__pypackages__/
92+
93+
# Celery stuff
94+
celerybeat-schedule
95+
celerybeat.pid
96+
97+
# SageMath parsed files
98+
*.sage.py
99+
100+
# Environments
101+
.env
102+
.venv
103+
env/
104+
venv/
105+
ENV/
106+
env.bak/
107+
venv.bak/
108+
109+
# Spyder project settings
110+
.spyderproject
111+
.spyproject
112+
113+
# Rope project settings
114+
.ropeproject
115+
116+
# mkdocs documentation
117+
/site
118+
119+
# mypy
120+
.mypy_cache/
121+
.dmypy.json
122+
dmypy.json
123+
124+
# Pyre type checker
125+
.pyre/
126+
127+
# pytype static type analyzer
128+
.pytype/
129+
130+
# Cython debug symbols
131+
cython_debug/
132+
133+
# PyCharm
134+
.idea/

app/Dockerfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Use an official Python runtime as a parent image
2+
FROM python:3.11-slim
3+
4+
# Set the working directory to /app
5+
WORKDIR /app
6+
7+
# Install required C++11 libraries and ca-certificates
8+
RUN apt-get update -qq \
9+
&& apt-get install -y \
10+
build-essential \
11+
python3-dev \
12+
ca-certificates \
13+
curl \
14+
&& apt-get clean \
15+
&& rm -rf /var/lib/apt/lists/*
16+
17+
# Install any needed packages specified in requirements.txt
18+
COPY requirements.txt /app/
19+
RUN pip install --no-cache-dir -r requirements.txt
20+
21+
# Copy the current directory contents into the container at /app
22+
COPY . /app
23+
24+
# Make port 5000 available to the world outside this container
25+
EXPOSE 5000
26+
27+
# Run main when the container launches
28+
ENTRYPOINT ["uwsgi", "--http", "0.0.0.0:5000", "--master", "-p", "2", "-w", "main:app"]
29+
USER nobody

app/main.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
2+
3+
from flask import Flask
4+
from flask import request
5+
6+
7+
app = Flask(__name__)
8+
9+
10+
@app.route("/")
11+
def index():
12+
# Set response header to HTML
13+
headers = {
14+
"Content-Type": "text/html",
15+
}
16+
17+
# Declare the HTML to return via the response
18+
content = """
19+
<!DOCTYPE html>
20+
<html>
21+
<head>
22+
<title>Simple form post</title>
23+
<style>
24+
body {
25+
font-family: Arial, sans-serif;
26+
margin: 20px;
27+
}
28+
29+
label {
30+
font-weight: bold;
31+
}
32+
33+
input[type="text"] {
34+
padding: 5px;
35+
margin-bottom: 10px;
36+
width: 200px;
37+
}
38+
39+
input[type="submit"] {
40+
padding: 10px 20px;
41+
background-color: #4CAF50;
42+
color: white;
43+
border: none;
44+
cursor: pointer;
45+
}
46+
</style>
47+
</head>
48+
<body>
49+
<h1>Simple form post</h1>
50+
<form action="/submit" method="post">
51+
<label for="first_name">First name:</label><br>
52+
<input type="text" id="first_name" name="first_name"><br>
53+
<input type="submit" value="Submit">
54+
</form>
55+
</body>
56+
</html>
57+
"""
58+
59+
# Return the HTML
60+
return content, 200, headers
61+
62+
63+
64+
@app.route("/submit", methods=["POST"])
65+
def submit():
66+
# Set response header to HTML
67+
headers = {
68+
"Content-Type": "text/html",
69+
}
70+
71+
# Get the form data
72+
first_name = request.form.get('first_name')
73+
74+
# Declare the HTML to return via the response
75+
content = """
76+
<html>
77+
<head>
78+
<title>Simple form post</title>
79+
</head>
80+
<body>
81+
<h1>Hello {}!</h1>
82+
</body>
83+
</html>
84+
""".format(first_name)
85+
86+
# Return the HTML
87+
return content, 200, headers
88+
89+
90+
if __name__ == '__main__':
91+
app.run(debug=True, host='0.0.0.0')

app/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
uwsgi
2+
flask

compose.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: python-form
2+
services:
3+
app:
4+
restart: unless-stopped
5+
build:
6+
context: ./app
7+
dockerfile: Dockerfile
8+
ports:
9+
- mode: ingress
10+
target: 5000
11+
deploy:
12+
resources:
13+
reservations:
14+
memory: 256M
15+
healthcheck:
16+
test:
17+
- CMD
18+
- curl
19+
- -f
20+
- http://localhost:5000/

0 commit comments

Comments
 (0)