I will retire from my current SIer this month, and I am thinking of becoming an engineer around infrastructure. When building an infrastructure and CI / CD environment that makes full use of the public cloud in recent years, even a legacy engineer like me should avoid building apps in various languages or creating apps for communication confirmation. It is around this time that I feel that I can no longer pass.
I wanted to do my best to build various languages and make a little web application, so this time I described the procedure to create a Flask application (just touching it) with Python and Pipenv and make it a Docker container.
In recent years, Python environment construction seems to be built using a tool called Pipenv, so I tried using it. It's like JavaScript npm and easy to use.
pip install pipenv
mkdir flask-app
cd flask-app
This time I will use Python 3.8.
pipenv --python 3.8
pipenv install flask
pipenv install --dev autopep8
Create an empty file to be created.
mkdir src
touch src/main.py
touch Dockerfile
touch .dockerignore
Add to the scripts
section of the Pipfile
.
[scripts]
start = "python src/main.py"
It will be a code written by a Python amateur, but I created it like the following.
src/main.py
import sqlite3
import flask
app = flask.Flask(__name__)
def get_db():
db = getattr(flask.g, '_database', None)
if db is None:
db = flask.g._database = sqlite3.connect('mydb.sqlite')
return db
@app.teardown_appcontext
def close_conn(exception):
db = getattr(flask.g, '_database', None)
if db is not None:
db.close()
@app.route('/todos/<id>', methods=['GET'])
@app.route('/todos', methods=['GET', 'POST'])
def todos(id=None):
db = get_db()
#Create a table when you receive a request
curs = db.cursor()
curs.execute(
'create table if not exists todos('
'id integer primary key autoincrement, title string)'
)
id = flask.request.values.get('id', id)
if flask.request.method == 'GET' and id is not None:
curs.execute('select * from todos where id = {}'.format(id))
response = curs.fetchone()
if response is not None:
id, title = response
return flask.jsonify(todo={"id": id, "title": title}), 200
return flask.jsonify(message='resource not found'), 400
if flask.request.method == 'GET':
curs.execute('select * from todos')
response = curs.fetchall()
todos = []
for todo in response:
id, title = todo
todos.append({"id": id, "title": title})
return flask.jsonify(todos=todos), 200
if flask.request.method == 'POST':
title = flask.request.json['title']
curs.execute('insert into todos(title) values("{}")'.format(title))
db.commit()
return flask.jsonify(message='created new toto')
def main():
app.debug = True
app.run(host='0.0.0.0', port=5000)
if __name__ == "__main__":
main()
At this point it should work in your local environment.
pipenv run start
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 208-926-045
Hit the curl command to check.
curl -XPOST -H 'Content-Type: application/json' localhost:5000/todos -d '{"title": "new task1"}'
curl -XPOST -H 'Content-Type: application/json' localhost:5000/todos -d '{"title": "new task2"}'
curl localhost:5000/todos
curl localhost:5000/todos/1
I don't know the practice when combined with Pipenv, but I made it with Simple Is Best.
FROM python:3.8
ENV LC_ALL=C.UTF-8 \
LANG=C.UTF-8
WORKDIR /app
COPY . .
RUN pip install pipenv
RUN pipenv install
CMD ["pipenv", "run", "start"]
EXPOSE 5000
Also create a .dockerignore
file.
.dockerignore
*.sqlite
.git
Build.
docker image build -t flaskapp:latest .
Start the container (starting the local port as 15000).
docker container run -it -p 15000:5000 --rm flaskapp:latest
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 954-331-726
It's OK if you can confirm by hitting the curl command.
curl -XPOST -H 'Content-Type: application/json' localhost:15000/todos -d '{"title": "new task1"}'
curl -XPOST -H 'Content-Type: application/json' localhost:15000/todos -d '{"title": "new task2"}'
curl localhost:15000/todos
curl localhost:15000/todos/1
I was accustomed to npm and yarn with nodejs, so I avoided building a python environment, but I found Pipenv useful. I didn't know Pipenv, so I felt like I had lost it.
For the time being, from the perspective of an infrastructure engineer (subjective), I'm satisfied because I've done so far. We will do our best to provide the environment without bothering the application engineer.
However, although I didn't remember much until about five years ago, the changes in the environment surrounding IT technology these days are tremendous. It has been left behind, but I am desperately trying to catch up with it.