Tehtäväanto
h6
a) Tietokanta wepissä. Tee oma yksinkertainen, tietokantaa käyttävä ohjelma. Ohjelmalla tulee olla jokin käyttötarkoitus. Voit tehdä ohjelman muokkaamalla Teron koodia (muista lähdeviite).
b) Laita tietokantaohjelmasi toimimaan mod_wsgi:n kanssa
Esivalmistelut, asensin päivitykset sekä tehtävässä vaadittavat paketit.
- sudo apt-get update
- sudo apt-get install -y python3-flask apache2 libapache2-mod-wsgi-py3 curl
Wsgikäyttäjän ja ryhmän luonti, jotta ei tarvitsisi sudoilla säädellä.
- sudo adduser jaaniwsgi
- sudo usermod –lock jaaniwsgi
- sudo adduser xubuntu jaaniwsgi
- su – xubuntu (group policyn päivitys)
Apachen site conffi ja WSGI-asetukset
Lisäsin konffitiedoston apachen sits-availableihin
- sudoedit /etc/apache2/sites-available/jaaniwsgi.conf
<VirtualHost *:80>
ServerName jaanionparas.com
WSGIDaemonProcess jaaniwsgi user=jaaniwsgi group=jaaniwsgi threads=5
WSGIScriptAlias / /home/jaaniwsgi/public_wsgi/jaani.wsgi
<Directory /home/jaaniwsgi/public_wsgi/>
WSGIScriptReloading On
WSGIProcessGroup jaaniwsgi
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
</VirtualHost>
- sudo a2ensite jaaniwsgi.conf
- sudo a2dissite 000-default.conf
- apache2ctl configtest
- sudo systemctl restart apache2
Configtesti ok, Testasin localhostissa toimintaa ja sain forbidden herjan, odotetusti.
jaaniwsgin hakemistojen ryhmät kuntoon
Lisäsin käyttäjälleni käyttökansiot mistä pyörittää palveluita sekä asetin ryhmäasetukset kuntoon jotta jokainen ryhmän jäsen voisi muokata tiedostoja ja kansioita.
- sudo mkdir /home/jaaniwsgi/public_wsgi
- sudo chown jaaniwsgi:jaaniwsgi /home/jaaniwsgi/public_wsgi/
- sudo chmod g=rwxs /home/jaaniwsgi/public_wsgi/
- ls -ld /home/jaaniwsgi/public_wsgi/
WSGI Filun luontia
Loin WSGI filun ja tänne sisällön
nano /home/jaaniwsgi/public_wsgi/jaani.wsgi
import sys
assert sys.version_info.major >= 3, "Python version too old in jaani.wsgi!"
sys.path.insert(0, '/home/jaaniwsgi/public_wsgi/')
from hello import app as application
Tämän jälkeen loin python filun jotta jotakin saataisiin pyörimään. Pohjana käytin tehtävänannossa mainittua materiaalia. Asensin myös koodin vaatimat kirjastot etukäteen oman tietoni ja lähdemateriaalin pohjalta. Turha esittää tyhmää ja tietämätöntä jos nämä on jo aikaisemmin tehnyt ja tiennyt.
- nano /home/jaaniwsgi/public_wsgi/hello.py
- sudo apt-get install -y python3-flask-sqlalchemy python3-wtforms python3-flaskext.wtf
hello.py
from flask import Flask, render_template, flash, redirect
from flask_sqlalchemy import SQLAlchemy
from wtforms.ext.sqlalchemy.orm import model_form
from flask_wtf import FlaskForm
import wtforms
app = Flask(__name__)
db = SQLAlchemy(app)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///autoformed.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECRET_KEY"] = "dUCF)mtd9MAoZ?;R|8*iB^.+TCV//0"
class Reply(db.Model):
id = db.Column(db.Integer, primary_key=True)
coming = db.Column(db.Boolean, nullable=False)
email = db.Column(db.String, nullable=False)
name = db.Column(db.String, nullable=False)
field_args = { "email": {"validators": [wtforms.validators.Email()]} }
ReplyForm = model_form(model=Reply, base_class=FlaskForm, db_session=db.session, field_args=field_args)
@app.before_first_request
def beforeFirstRequest():
db.create_all()
@app.route("/", methods=["GET", "POST"])
def index():
form = ReplyForm()
if form.validate_on_submit():
reply = Reply()
form.populate_obj(reply)
db.session.add(reply)
db.session.commit()
flash("Your reply has been added. Welcome!")
return redirect("/")
replies = db.session.query(Reply)
return render_template("replies.html", form=form, replies=replies)
def main():
app.run(debug=True)
if __name__ == "__main__":
main()
Tämän jälkeen loin html sivustot, base.html ja tätä extendaava replies.html
templates/base.html – Base template
<!doctype html>
<html lang=en>
<head>
<title>Joining an Event Example</title>
<meta charset="utf-8">
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block body %}
<h1>Hello Tero</h1>
{% endblock %}
<p>Learn Flask automatic forms at <a href="TeroKarvinen.com">TeroKarvinen.com</a>
</body>
</html>
templates/replies.html – Form and List Template
{% extends "base.html" %}
{% block body %}
<h1>Replies</h1>
<form method=post action="/">
{{ form.csrf_token }}
{% for field in form if not field.name in ["csrf_token"] %}
<p>{{ field.label }}: {{ field }} <b>{{ " ".join(field.errors) }}</b></p>
{% endfor %}
<input type="submit">
</form>
<h2>Replies</h2>
{% for reply in replies %}
<p>{{ reply.name }}</p>
{% endfor %}
{% endblock %}
Tämän jälkeen testasin localhostin toiminnan ja sain formsin näkymään. Lisäsin repliesin ja tämä näkyi formilla.
Muokkaaminen omiin tarkoituksiin
Tavoitteenani oli luoda anonyymi ikägalluppi ja tämän myötä tallentaa tietokantaan pelkästään käyttäjän ikä. Koska arvostamme anonyymiutta niin muita tietoja käyttäjästä ei kerätty.
hello.py , replyn muokkaus
class Reply(db.Model):
id = db.Column(db.Integer, primary_key=True)
age= db.Column(db.Integer, nullable=False)
ja sitten muokkasin base.html ja replies.html oman näköisekseni. Lopulta touch jaani.wsgi sekä localhostin refreshaus ja lopulta hieno ikägalluppini oli toiminnassa!

Lähteet
http://terokarvinen.com/2020/flask-automatic-forms/
http://terokarvinen.com/2020/deploy-python-flask-to-production/