Κυριακή 15 Νοεμβρίου 2020

Python και Flask για αρχάριους – δημιουργία εφαρμογής – πρόχειρο τετράδιο

Scratchpad - Web app for dummies with Python and Flask .

 Python και Flask για αρχάριους – δημιουργία εφαρμογής – πρόχειρο τετράδιο 

 


Έχουμε συνηθίσει να ανεβάζουμε σχόλια στα κοινωνικά δίκτυα, να απαντάμε σε μηνύματα, να κρατάμε σημειώσεις. Πώς άραγε λειτουργούν αυτά; Τι κώδικας βρίσκεται από πίσω; Ως εντελώς αρχάριος αναρωτιέμαι όχι μόνο πώς λειτουργεί, αλλά και πώς θα φτιάξω και εγώ μια εφαρμογή. 

Θα δημιουργήσουμε ένα σημειωματάριο που θα κρατάει τις σημειώσεις μας για πάντα (μέχρι να τις διαγράψουμε), θα είναι προσβάσιμο από οποιαδήποτε συσκευή και από οπουδήποτε σημείο στον κόσμο γιατί θα «τρέχει» στο σύννεφο (cloud). Προφανώς μιλάμε για μια εφαρμογή ιστού web app. 

Θα χρειαστούμε λίγες γραμμές κώδικα σε Python, τον πυρήνα Flask (που είναι πλαίσιο εφαρμογών βασισμένο σε WSGI -Web Server Gateway Interface - διάβαζε: «ουίσκι!») και μια υπηρεσία φιλοξενίας στον ιστό (web hosting) το PythonAnywhere (που ταυτόχρονα είναι ένα ολοκληρωμένο περιβάλλον ανάπτυξης IDE - Integrated Development Environment). Επίσης χρειαζόμαστε ένα εργαλείο-αποθήκη , όπως το Git, αλλά μην ανησυχείτε, είναι ενσωματωμένο στο PythonAnywhere. 

Δημιουργία λογαριασμού και Είσοδος στο PythonAnywhere. Διαβάστε αυτό το άρθρο.

Τα βήματα με απλές εξηγήσεις: 

Μετά την είσοδο μας πατάμε την καρτέλα Web και δημιουργούμε ένα νέο web app.

 


Πατάμε Add a new web app (ο δωρεάν λογαριασμός επιτρέπει μόνο μία εφαρμογή).


 

 Το παράθυρο που ανοίγει, ενημερώνει για τη δικτυακή διεύθυνση της εφαρμογής και πατάμε Next. (στο δωρεάν λογαριασμό δεν μπορώ να διαλέξω domain name, βγαίνει αυτόματα). 

 

Στο επόμενο παράθυρο πρέπει να διαλέξω πλαίσιο εφαρμογών (web framework). Τα πιο εύχρηστα είναι το Flask και το Django, εδώ θα διαλέξω Flask. Πατάω Next. 

 

Στο επόμενο παράθυρο διαλέγω την έκδοση της Python που θα χρησιμοποιήσω. Αν είναι η πρώτη φορά που ασχολούμαι, διαλέγω την πιο πρόσφατη. Αν όμως έχω ήδη γραμμένο κώδικα από το παρελθόν, διαλέγω την έκδοση με την οποία είχα γράψει το σκριπτάκι. Πατάω Next. 

 

Στο επόμενο παράθυρο ρωτάει που να τοποθετήσει το αρχείο flak_app.py και η αυτόματα προτεινόμενη θέση είναι μια χαρά, Πατάω Next. 


 

Μέσα σε λίγα δευτερόλεπτα το PythonAnywhere δημιουργεί αυτόματα τα βασικά πράγματα και μας φέρνει σε αυτή τη σελίδα.

 


Εδώ χρειαζόμαστε δύο πράγματα: το σύνδεσμο όπου φιλοξενείται η εφαρμογή μας (δίπλα στο Configuration for) και το Reload. Επειδή έχουμε δωρεάν λογαριασμό, ο σύνδεσμος (όχι η εφαρμογή) θα είναι ενεργός για 3 μήνες, απλά στο μεσοδιάστημα πρέπει να επισκεφθούμε το PythonAnywhere και σε αυτή τη σελίδα να πατήσουμε το Run until 3 months from today, για να διατηρηθεί. Επίσης αν πατήσω το Add a new web app, θα μου θυμίσει ότι έχω τον απλό- δωρεάν λογαριασμό και δεν έχω δικαίωμα για δεύτερη εφαρμογή. 

Εν πάση περιπτώση εδώ τώρα πρέπει να πατήσω δεξί κλικ – άνοιγμα σε νέα καρτέλα, στο σύνδεσμο myname.pythonanywhere.com και να δω τι μου ετοίμασε αυτόματα το PythonAnywhere: τρέχει μια εφαρμογή Flask (θα τη δούμε αμέσως μετά) και παρουσιάζει στη σχετική ιστοσελίδα (εδώ που είμαστε = myname.pythonanywhere.com) το μήνυμα «Hello from Flask!» 

 


Στην προηγούμενη καρτέλα (που έχουμε κρατήσει ανοιχτή) χαμηλά κάτω από τη λέξη Code εμφανίζεται ο κατάλογος με τα αρχεία μας. Δίπλα στο Source code πατήστε Go to directory και θα βρεθείτε μπροστά στα αρχεία. Αν χάσουμε το δρόμο, μπορούμε εύκολα να ξαναβρούμε τα αρχεία μας στην καρτέλα Files. Βλέπουμε το αυτόματα δημιουργημένο αρχείο flask_app.py και πατάμε επάνω του. 

Βρισκόμαστε μπροστά σε αυτό το γιγάντιο κώδικα:


from flask import Flask  σημαίνει από το φλασκί εισάγεις το Flask
app = Flask(__name__) σημαίνει δημιούργησε μια εφαρμογή  που θα είναι Flask και θα έχει όνομα αυτόματο.
@app.route('/') σημαίνει ότι η δικτυακή διεύθυνση της εφαρμογής είναι η διεύθυνση home (η αρχική μας δηλαδη η myname.pythonanywhere.com).
def hello_world(): σημαίνει δημιούργησε μια λειτουργία με όνομα hello_world
   (η εσοχή εδώ σημαίνει όταν τρέξεις την από πάνω λειτουργία)     

         return 'Hello from Flask!' σημαίνει γράψε «'Hello from Flask!»
 

Προσοχή στις εσοχές indentation (θα επιμείνουμε και παρακάτω). Αν στοιχίσουμε το return κάτω ακριβώς από το def  δε θα τρέξει.


Για εξάσκηση δοκιμάστε να αλλάξετε τον κώδικα που βλέπετε στο αρχείο flask_app.py με αυτό:
from flask import Flask  
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'H πρώτη μου χειροκίνητη επέμβαση στο αρχείο πέτυχε!!!'


Τώρα πατάμε Save, μετά πατάμε την ανακύκλωση δεξιά από το Run 


 

και επιτέλους πάμε στην καρτέλα που δείχνει τη σελίδα μας (myname.pythonanywhere.com), τη φορτώνουμε ξανά (reload - F5) και βλέπουμε να γράφει:
'H πρώτη μου χειροκίνητη επέμβαση στο αρχείο πέτυχε!!!'

Αν χάσατε την ιστοσελίδα μην ανησυχείτε, βρίσκεται πάντα εδώ: πατάμε Web και βλέπουμε το σύνδεσμο:


 

Πάρτε μιαν ανάσα, τελείωσε το πρώτο βήμα!
 

 Ένα πλαίσιο εφαρμογών, όπως το Flask, συνδυάζει δύο πράγματα: τον πηγαίο κώδικα (στην περίπτωσή μας σε γλώσσα Python) και κάποια πρότυπα με τα οποία δουλεύει ο ιστός (στην περίπτωσή μας HTML). Ουσιαστικά ο κώδικας λέει στην εφαρμογή τι να κάνει και το πρότυπο λέει πώς θα προβληθούν στον ιστό.


Τώρα θα δημιουργήσουμε έναν κατάλογο και μέσα θα βάλουμε το απαραίτητο πρότυπο.
Μέσα στη σελίδα μας στο PythonAnywhere πατάμε Files πάνω αριστερά στα Directories πατάμε mysite ώστε να βρισκόμαστε στο κατάλληλο μονοπάτι: /home/(username)/mysite.

 Στο λευκό πεδίο (Enter new directory here) γράφουμε templates και πατάμε το κουμπί New directory. Αμέσως εμφανίζεται ο νέος φάκελος templates κάτω από τα Directories. Πατάμε επάνω στο φάκελο templates και στο νέο παράθυρο κάτω από τη λέξη Files γράφουμε στο λευκό πεδίο (Enter new file name,..)

 main_page.html και πατάμε το κουμπί New file.
Στον editor που άνοιξε, πρέπει να γράψουμε τον ακόλουθο κώδικα (πάλι χρειάζεται απόλυτη προσοχή στη στοίχιση - indentation):


<!--

<html>

    <head>

        <meta charset="utf-10">

        <meta http-equiv="X-UA-Compatible" content="IE=edge">

        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">

        <title>Γράφω ό,τι μου κατέβει στο κεφάλι.</title>

    </head>

 

    <body>

        <nav class="navbar navbar-inverse">

            <div class="container">

                <div class="navbar-header">

                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">

                        <span class="sr-only">Toggle navigation</span>

                        <span class="icon-bar"></span>

                        <span class="icon-bar"></span>

                        <span class="icon-bar"></span>

                    </button>

                    <a class="navbar-brand" href="#">ό,τι μου κατέβει</a>

                </div>

            </div>

        </nav>

        <div class="container">

        <div class="row">

            <b>Προσοχή: Γράφω ό,τι μου κατέβει στο κεφάλι κι αν θέλετε, κάνετε το ίδιο!</b>

        </div>

        <div class="row">

            1. Το πρώτο μου σχόλιο είναι ότι το ανωτέρω "ό,τι" είναι αναφορική αντωνυμία γένους ουδετέρου και σημαίνει "οτιδήποτε".

        </div>

        <div class="row">

            2. Δεύτερο σχόλιο: το πρώτο ότι στο πρώτο σχόλιο είναι ειδικός σύνδεσμος και εισάγει ειδικές προτάσεις (προφανώς το αναφορικό "ό,τι" εισάγει αναφορικές προτάσεις).

        </div>

        <div class="row">

            3. Τρίτο σχόλιο: δεν ξέρω τι άλλο να σχολιάσω!

        </div>

        {% for comment in comments %}

            <div class="row">

                {{ comment }}

            </div>

        {% endfor %}

        <div class="row">

            <form action="." method="POST">

                <textarea name="contents" placeholder="Γράψε κάτι..." class="form-control"></textarea>

                <input type="submit" class="btn btn-success" value="Ανέβασέ το!">

            </form>

        </div>

        <div>

            Αν δεν έχετε όρεξη να σχολιάσετε, επισκεφθήτε την κανονική σελίδα μου!

        </div>

        <div>&nbsp;</div><div><a href="http://tiemathasimera.blogspot.com" target="_blank">Τι έμαθα σήμερα!</a>!</div><div>&nbsp;</div>

        </div><!-- /.container -->

        <nav class="navbar navbar-inverse">

            <div class="container">

                <div class="navbar-header">

                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">

                        <span class="sr-only">Toggle navigation</span>

                        <span class="icon-bar"></span>

                        <span class="icon-bar"></span>

                        <span class="icon-bar"></span>

                    </button>

                    <a class="navbar-brand" href="#">δημιουργός Φιλομαθής</a>

                </div>

            </div>

        </nav>

    </body>

</html>

-->

(ΠΡΟΣΟΧΗ εσείς πρέπει να παραλείψετε το <!-- στην αρχή και το --> στο τέλος!)

 Μια αναλυτική ερμηνεία του κώδικα html θα βρούμε σε άλλο tutorial.

Τώρα πατάμε Save, μετά πατάμε την ανακύκλωση δεξιά από το Run. 


 

Μην βιαστείτε να πάτε να δείτε πώς φαίνεται η ιστοσελίδα διότι παρότι τη στήσαμε και τη μακιγιάραμε με το template, δεν έχουμε ενημερώσει το Flask για τις επιθυμίες μας.

Πατάμε το mysite και μετά πατάμε στο αρχείο flask_app.py.

Πρέπει να αλλάξουμε αυτό

from flask import Flask

Με το παρακάτω για να μπορέσει να δει και να επεξεργαστεί το template

from flask import Flask, render_template

 Πρέπει να αλλάξουμε αυτό

@app.route('/')
def hello_world():
    return 'This is my new shiny Flask app'

με το παρακάτω για να μπορέσει να προβάλει το template

@app.route("/")
def index():
    return render_template("main_page.html")

 

Επίσης για να γλυτώσουμε από προβλήματα σε περίπτωση που πληκτρολογήσαμε κάτι λαθός, προσθέτουμε αυτή τη γραμμή ακριβώς κάτω από τη γραμμή

app = Flask(__name__)

app.config["DEBUG"] = True

 

 Τώρα πατάμε Save, μετά πατάμε την ανακύκλωση δεξιά από το Run 


 

και επιτέλους πάμε στην καρτέλα που δείχνει τη σελίδα μας (myname.pythonanywhere.com).

 


 

Σε αυτό το σημείο, αν γράψουμε ένα σχόλιο και πατήσουμε Post comment, θα λάβουμε αυτό το μήνυμα:

 


 

Αυτό συμβαίνει επειδή δεν έχουμε κάνει τις κατάλληλες αλλαγές στο Flask.

Αλλαγή 1 πρέπει να του πούμε να δέχεται και να στέλνει δεδομένα

Αλλαγή 2 πρέπει να του πούμε να αποθηκεύει τα νέα δεδομένα

 

Πατάμε το mysite και μετά πατάμε στο αρχείο flask_app.py.

Στον editor που άνοιξε, πρέπει να φορτώσουμε στο Flask νέες λειτουργίες για να υποστηρίζονται οι απαιτήσεις μας. Οπότε αλλάζουμε αυτό

from flask import Flask, render_template

 

με το παρακάτω

from flask import Flask, redirect, render_template, request, url_for

 

Μετά προσθέτουμε μια μεταβλητή για να αποθηκεύει νέα δεδομένα

Οπότε ακριβώς πάνω από αυτό

@app.route("/")

Πρέπει να προσθέσουμε αυτό

comments = []

 

Επίσης πρέπει  να αλλάξουμε αυτό

@app.route("/")

 

Με το παρακάτω για να μπορεί να λαμβάνει και να στέλνει δεδομένα

@app.route("/", methods=["GET", "POST"])

 

Για να επιτευχθεί η αλληλεπίδραση του χρήστη με τη σελίδα μας πρέπει να προσθέσουμε δύο παραμέτρους στο def index(): συγκεκριμένα αυτές:

def index():
    if request.method == "GET":
        return render_template("main_page.html", comments=comments)
 
    comments.append(request.form["contents"])
    return redirect(url_for('index'))

 

Δηλαδή τελικά το αρχείο flask_app.py πρέπει να έχει αυτόν τον κώδικα:

from flask import Flask, redirect, render_template, request, url_for

app = Flask(__name__)

app.config["DEBUG"] = True

comments = []

@app.route('/',  methods=['GET', 'POST'])

def index():

    if request.method == "GET":

        return render_template("main_page.html", comments=comments)

    comments.append(request.form["contents"])

    return redirect(url_for('index'))

Τώρα πατάμε Save, μετά πατάμε την ανακύκλωση δεξιά από το Run 


 

και επιτέλους πάμε στην καρτέλα που δείχνει τη σελίδα μας (myname.pythonanywhere.com).

Συγχαρητήρια που φτάσατε έως εδώ!

Αυτή τη στιγμή η εφαρμογή σας είναι διαθέσιμη στη σελίδα pythonanywhere.com.

Πατάμε την καρτέλα Web και βρίσκουμε το σύνδεσμο (link).

Παίξτε μαζί της και διαδώστε τη σε φίλους σας. Προσοχή όλοι θα μπορούν να βλέπουν τα γραπτά όλων! Στην αρχή θα έχει πλάκα, αλλά αργότερα...

Η δική μου εφαρμογή βρίσκεται εδώ

http://nicktremoulis.pythonanywhere.com/

Η εφαρμογή χρειάζεται τρεις βελτιώσεις

1. Να απαιτεί όνομα χρήστη και κωδικό για εξατομικευμένη είσοδο,

2. Να αποθηκεύει τα σχόλια σε έναν πραγματικό server (σχετικό άρθρο εδώ) και

3. Να δίνει στο χρήστη τη δυνατότητα διαγραφής  σχολίων και ίσως

4. Να καταγράφει ημερομηνία και ώρα δημιουργίας σχολίου.

Ανάλογα με την όρεξή σας προχωρήστε στα σχετικά βήματα!

 

2 σχόλια:

dpetrianos είπε...

Πολύ ωραία. Κατατοπιστικότατα !!!
Ευχαριστώ.

NickTrem είπε...

Ευχαριστώ κι εγώ, καλωσήρθες!
Πολύ ωραία δουλειά στο blog σου!