Welcome to the World of Server-Side Programming!

Ever wondered how a website "remembers" your login details or how a search engine processes your queries? While HTML and CSS handle the "look" of a website (the front-end), Flask handles the "brains" (the back-end). In this chapter, we will learn how to use Python and the Flask framework to build dynamic web applications that can talk to databases and respond to users in real-time.

1. What is Flask?

Flask is a Web Framework. Think of it as a set of pre-built tools that helps you build a website without having to write every single detail from scratch. It acts as the Server in the Client-Server architecture.

Analogy: Imagine a restaurant. The Client (the customer) sits at a table and asks for a menu. The Flask Server is the waiter who takes the order, goes to the kitchen (the database) to get the food, and brings it back to the customer. Without the waiter, the customer and the kitchen can't communicate!

2. The Basic Structure of a Flask App

To start a Flask application, you need a few essential lines of Python code. Don't worry if this looks a bit strange at first; it becomes second nature with practice!

from flask import Flask, render_template, request
app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, Welcome to my Website!"

if __name__ == '__main__':
    app.run(debug=True)

Key Components:
1. Importing Flask: You must bring in the Flask library to use its powers.
2. The App Instance: app = Flask(__name__) creates your web application object.
3. Routes: The @app.route('/') part tells Flask which URL should trigger which function. The \( / \) symbol represents the home page.
4. The View Function: The function immediately below the route (like home()) defines what happens when the user visits that URL.

3. Routing: Navigating Your App

Routing is how we map different URLs to different parts of our Python code. You can even capture information from the URL itself!

Static Routes: @app.route('/about') leads to an "About Us" page.
Dynamic Routes: @app.route('/user/<name>') allows you to greet a specific person. If the URL is /user/Alice, the variable \( name \) becomes "Alice".

Quick Tip: Remember that every route function must return something—usually a string of text or a rendered HTML template.

4. Handling User Input with Forms

Web applications aren't very useful if they can't take data from users. In Flask, we handle this using HTTP Methods.

GET: Used to request data from the server (e.g., clicking a link or searching). Data is visible in the URL.
POST: Used to send data to the server (e.g., submitting a password or uploading a file). Data is hidden from the URL, making it more secure for sensitive info.

The Flask Request Object:
To get data from a form in Python, we use request.form. For example:
username = request.form.get('user_input_name')

5. Dynamic Templates with Jinja2

We don't want to write a separate HTML file for every single user. Instead, we use Templates. Flask uses a template engine called Jinja2 which allows us to stick Python-like logic inside HTML.

Common Jinja2 Syntax:
1. Variables: {{ variable_name }} — This "prints" the value of a variable into the HTML.
2. For Loops: {% for item in list %} ... {% endfor %} — Great for displaying tables of data.
3. If Statements: {% if condition %} ... {% endif %} — Show content only if a condition is met.

Prescribed Filters:
- length: Returns the size of a list. Usage: {{ my_list | length }}
- safe: Tells Flask the string is safe and should be rendered as HTML (not just plain text). Usage: {{ my_html_string | safe }}

6. Connecting to a Database (SQL)

A "real" web app needs to store data permanently. We use the sqlite3 module in Python to talk to an SQL database.

The Workflow:
1. Connect: db = sqlite3.connect('database.db')
2. Cursor: Create a "cursor" to execute commands: cursor = db.cursor()
3. Execute: Run your SQL (e.g., SELECT * FROM users). Use \( ? \) placeholders to prevent SQL Injection attacks!
4. Commit & Close: Save your changes with db.commit() and always db.close() when done.

Example: To show a table of results on a webpage, you would fetch data in Python, pass it to render_template, and use a Jinja2 for loop in your HTML to create <tr> and <td> tags.

7. Handling File Uploads

The syllabus requires you to know how to handle text and image file uploads. To do this:
1. Ensure your HTML form has the attribute enctype="multipart/form-data".
2. In Flask, use request.files['file_name'] to grab the uploaded file.
3. Use the .save() method to store the image on your local server.

Did you know? If you forget the enctype attribute in your HTML, your server will never receive the file, and request.files will be empty!

8. Summary and Key Takeaways

- Flask is the "Server": It processes requests and returns responses.
- Routing: Links URLs to Python functions.
- Request Object: Used to access form data (request.form) and files (request.files).
- Templates: Use Jinja2 ({{ }} and {% %}) to make HTML dynamic.
- Database: Use sqlite3 to store and retrieve data for the website.
- Security: Always use Input Validation and Prepared Statements (the \( ? \) syntax) to protect against SQL Injection.

9. Common Mistakes to Avoid

1. Wrong Method: Trying to access request.form on a GET request will often cause an error. Ensure your route includes methods=['GET', 'POST'].
2. Forgetting to Commit: If you INSERT or UPDATE data in SQL but forget db.commit(), your changes will vanish when the program ends!
3. Indentation: In Python, indentation is everything. Make sure your route functions are properly indented under the @app.route decorator.
4. Missing Templates Folder: Flask looks for HTML files in a folder named templates. If you name it "Template" or "html", Flask won't find them!

Don't worry if this seems like a lot of moving parts! Building a Flask app is like building with LEGO blocks. Once you understand how to connect the "Route block" to the "Database block" and the "Template block", you can build almost anything!