# Chapter 15: Web Development with Python

Web development is one of the most popular applications of Python. Frameworks like Flask and Django make it easy to build robust web applications and APIs. This chapter provides an overview of these frameworks and introduces key concepts for web development.

#### Flask: A Lightweight Web Framework

Flask is a microframework that provides the essentials for building web applications without additional overhead.

**Installing Flask**

```bash
pip install flask
```

**Creating a Basic Flask App**

```python
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello, Flask!"

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

* `@app.route("/")`: Defines the URL path for the route.
* `app.run(debug=True)`: Runs the development server with debugging enabled.

**Handling Routes and Parameters**

```python
@app.route("/greet/<name>")
def greet(name):
    return f"Hello, {name}!"
```

#### Django: A Full-Featured Web Framework

Django is a high-level framework that includes built-in support for databases, authentication, and more.

**Installing Django**

```bash
pip install django
```

**Creating a Django Project**

1. Start a project:

   ```bash
   django-admin startproject myproject
   ```
2. Navigate to the project directory and run the server:

   ```bash
   cd myproject
   python manage.py runserver
   ```

**Creating a Django App**

1. Create an app:

   ```bash
   python manage.py startapp myapp
   ```
2. Register the app in `INSTALLED_APPS` (in `settings.py`):

   ```python
   INSTALLED_APPS = [
       'myapp',
   ]
   ```
3. Define a view in `myapp/views.py`:

   ```python
   from django.http import HttpResponse

   def home(request):
       return HttpResponse("Hello, Django!")
   ```
4. Map the view to a URL in `myapp/urls.py`:

   ```python
   from django.urls import path
   from . import views

   urlpatterns = [
       path('', views.home, name='home'),
   ]
   ```
5. Include the app's URL configuration in `myproject/urls.py`:

   ```python
   from django.urls import include, path

   urlpatterns = [
       path('', include('myapp.urls')),
   ]
   ```

#### Building REST APIs

REST (Representational State Transfer) APIs allow communication between client and server applications.

**Flask API Example**

```python
from flask import Flask, jsonify, request

app = Flask(__name__)

data = ["item1", "item2", "item3"]

@app.route("/api/items", methods=["GET"])
def get_items():
    return jsonify(data)

@app.route("/api/items", methods=["POST"])
def add_item():
    new_item = request.json.get("item")
    data.append(new_item)
    return jsonify({"message": "Item added", "items": data})

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

**Django API Example with Django REST Framework**

1. Install Django REST Framework:

   ```bash
   pip install djangorestframework
   ```
2. Add it to `INSTALLED_APPS`:

   ```python
   INSTALLED_APPS = [
       'rest_framework',
   ]
   ```
3. Define a serializer in `myapp/serializers.py`:

   ```python
   from rest_framework import serializers

   class ItemSerializer(serializers.Serializer):
       name = serializers.CharField(max_length=100)
   ```
4. Define a view in `myapp/views.py`:

   ```python
   from rest_framework.response import Response
   from rest_framework.views import APIView

   class ItemView(APIView):
       def get(self, request):
           return Response(["item1", "item2", "item3"])

       def post(self, request):
           return Response({"message": "Item added", "item": request.data})
   ```
5. Add a URL mapping in `myapp/urls.py`:

   ```python
   from django.urls import path
   from .views import ItemView

   urlpatterns = [
       path('api/items/', ItemView.as_view(), name='item-list'),
   ]
   ```

#### Templates in Flask and Django

Both frameworks support templates for rendering HTML dynamically.

**Flask Template Example**

```python
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("home.html", title="Welcome")
```

* `templates/home.html`:

  ```html
  <!DOCTYPE html>
  <html>
  <head>
      <title>{{ title }}</title>
  </head>
  <body>
      <h1>Welcome to Flask!</h1>
  </body>
  </html>
  ```

**Django Template Example**

* Create a template in `myapp/templates/myapp/home.html`:

  ```html
  <!DOCTYPE html>
  <html>
  <head>
      <title>{{ title }}</title>
  </head>
  <body>
      <h1>Welcome to Django!</h1>
  </body>
  </html>
  ```
* Update the view in `myapp/views.py`:

  ```python
  from django.shortcuts import render

  def home(request):
      return render(request, 'myapp/home.html', {"title": "Welcome"})
  ```

#### Exercises

**Exercise 1:**

Create a Flask application with routes for displaying a list of items and adding a new item.

**Solution:**

```python
from flask import Flask, jsonify, request

app = Flask(__name__)
data = []

@app.route("/items", methods=["GET"])
def get_items():
    return jsonify(data)

@app.route("/items", methods=["POST"])
def add_item():
    item = request.json.get("item")
    data.append(item)
    return jsonify({"message": "Item added", "items": data})

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

**Exercise 2:**

Create a Django project and app to display a "Hello, World!" message on the homepage.

**Solution:**

1. Create a Django project and app (`helloapp`).
2. Define a view in `helloapp/views.py`:

   ```python
   from django.http import HttpResponse

   def home(request):
       return HttpResponse("Hello, World!")
   ```
3. Map the view in `helloapp/urls.py` and include it in the project URL configuration.

#### Best Practices

1. Use virtual environments to isolate project dependencies.
2. Keep your code organized using the MVC (Model-View-Controller) pattern.
3. Secure your web applications with proper input validation and error handling.
4. Use environment variables for sensitive data like API keys and database credentials.
5. Follow REST principles when designing APIs.

In the next chapter, we will explore data science and machine learning with Python, including libraries like `numpy`, `pandas`, and `scikit-learn`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://py.d19.in/chapter-15-web-development-with-python.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
