Commit f255ed5a authored by Markus Mößler's avatar Markus Mößler
Browse files

added step by step guide doc

parent ce1c7bdb
Loading
Loading
Loading
Loading
+93 −169
Original line number Diff line number Diff line

# Tornado backend stage 01

This document explains the architecture of the current stage of the Tornado-based blogging web application.

---

## **Architecture Overview**

### **Components**:
- **Tornado Web Framework**:
  - Powers the backend HTTP server.
  - Handles routing, request handling, and web template rendering.
- **PostgreSQL Database**:
  - Stores persistent data for the application (blog entries, authors, etc.).
  - Interacts with the backend via `aiopg` for asynchronous database operations.
- **Docker**:
  - Encapsulates the application and database in containers to ensure consistency and portability.
  - Defined via `Dockerfile` and orchestrated with `docker-compose`.

---

## **File Structure**

- `blog.py`: Main application logic.
- `templates/`: HTML templates for rendering UI.
- `static/`: CSS and other static assets.
- `schema.sql`: SQL schema to set up the database.
- `requirements.txt`: Lists Python dependencies.
- `docker-compose.yml` and `Dockerfile`: Configure and build the Dockerized environment.

---

## **Core Application Functionality**

### **Routing**
- URL paths are mapped to handler classes defined in `blog.py`. Examples:
  - `/``HomeHandler`: Displays the latest blog posts.
  - `/compose``ComposeHandler`: Allows authenticated users to create or edit posts.
  - `/auth/*` → Authentication handlers for user management.

### **Database Interaction**
- **Asynchronous Access**:
  - `aiopg` enables non-blocking communication with PostgreSQL.
- **Dynamic Queries**:
  - Methods like `query` and `queryone` abstract SQL queries, allowing reusable patterns for CRUD operations.

### **Template Rendering**
- HTML templates are rendered using Tornado's template engine.
- Templates are located in `templates/` and support features like inheritance (e.g., `base.html`).

### **User Authentication**
- Secure user authentication is implemented using cookies:
  - `get_secure_cookie` for fetching session information.
  - `set_signed_cookie` for creating signed cookies.
- Passwords are hashed using `bcrypt`.

### **Security Features**
- XSRF protection (`xsrf_cookies=True`) defends against cross-site request forgery.
- `cookie_secret` ensures secure encryption for cookies.

---

## **Database Design**

The database schema is defined in `schema.sql` (presumably includes tables like `authors` and `entries`):
- **Authors Table**:
  - Stores user credentials and profile details.
- **Entries Table**:
  - Contains blog posts with metadata like `author_id`, `title`, `content`, and timestamps.

---

## **Handlers and Modules**

### **Request Handlers**
- **BaseHandler**:
  - Shared functionality (e.g., SQL execution and user preparation) for all handlers.
- **Specific Handlers**:
  - **HomeHandler**: Fetches and displays recent posts.
  - **ComposeHandler**: Handles blog post creation/editing (requires authentication).
  - **AuthCreateHandler** and **AuthLoginHandler**: Manage user signup and login.
  - **AuthLogoutHandler**: Handles user logout.

### **UI Modules**
- `EntryModule`:
  - Encapsulates reusable UI components for blog entries.

---

## **Deployment and Environment**

### **Dockerization**
- `Dockerfile` defines the Tornado backend:
  - Python 3.7 image is used as a base.
  - App dependencies are installed via `requirements.txt`.
- `docker-compose.yml` orchestrates:
  - A PostgreSQL service (`postgres`) with user credentials.
  - A Tornado backend service (`blog`) linked to the database.

### **Local Server**
- The application listens on port `8888` (mapped via Docker Compose).
- The database runs on PostgreSQL's default port `5432`.

---

## **Execution Flow**

1. **Application Start**:
   - The `main()` coroutine sets up the database pool and initializes the Tornado application.
   - The database schema is checked and initialized (if necessary) using `maybe_create_tables()`.

2. **Request Handling**:
   - Tornado routes incoming HTTP requests to the appropriate handler.
   - Handlers interact with the database to fetch/update data and render templates for the response.

3. **User Interaction**:
   - Unauthenticated users can view public content (e.g., posts).
   - Authenticated users can manage their content through secure routes like `/compose`.

---

## **Key Features at This Stage**

- **Functional Blog Backend**:
  - Supports viewing, creating, and editing posts.
  - Basic user authentication and session management.

- **Asynchronous Programming**:
  - Enhances performance for I/O-bound tasks (e.g., database queries).

- **Separation of Concerns**:
  - Modular structure with clear distinctions between backend logic, templates, and static assets.
# Tornado Backend (Stage 01)

Starting point is the GitHub Tronado blog demo [see](https://github.com/tornadoweb/tornado/tree/master/demos/blog)

## Web App Architecture

### Docker compose file

```yml
postgres:
  image: postgres:10.3
  environment:
    POSTGRES_USER: blog
    POSTGRES_PASSWORD: blog
    POSTGRES_DB: blog
  ports:
    - "3306"
blog:
  build: .
  links:
    - postgres
  ports:
    - "8888:8888"
  command: --db_host=postgres
```

- **Scalable Deployment**:
  - Dockerized environment ensures consistency and ease of deployment.
Note, the exposer of port 3306 is probably a mistake. The PostgrSQL default port is 5432 which is also used in `./tornado-backend/blog.py` to connect to the database.

## Visualization of This Stage
### Visualization

```mermaid
graph TD
    subgraph Application
    subgraph Blog Service
        TornadoServer["Tornado Server"]
        Templates["HTML Templates (Jinja-like)"]
        StaticAssets["Static Assets (CSS/JS)"]
    end

    subgraph Database
    subgraph Database Service 
        PostgreSQL["PostgreSQL Database"]
    end

    subgraph Docker
        BlogService["Blog Service (Python/Tornado)"]
        DatabaseService["Database Service (PostgreSQL)"]
    end

    User["User"] -->|HTTP Requests| TornadoServer
    User["User"] -->|HTTP Requests<br>Port 8888| TornadoServer
    TornadoServer -->|Renders| Templates
    TornadoServer -->|Serves| StaticAssets
    TornadoServer -->|Async Queries| PostgreSQL
    TornadoServer -->|Renders| Responses
    TornadoServer -->|Async Queries<br>Port 5432| PostgreSQL
```

Note, Tornado is used as web server and web framework e.g. with frontend and backend

    BlogService -->|Links To| DatabaseService
## Launch Web App

    TornadoServer -->|Port 8888| BlogService
    PostgreSQL -->|Port 5432| DatabaseService
### Step 1) Change to `tornado-backend` directory

```bash
cd tornado-backend/
```

---
### Step 2) Build multi-container app

This architecture provides a solid foundation for building a more complex web application. Future enhancements might include additional user roles, improved UI, or REST API support.
```bash
docker-compose up --build
```

## Additional Notes
### Step 3) Check container status and restart blog container

Enter the postgres database container using,
```bash
docker-compose ps
NAME                         IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
tornado-backend-postgres-1   postgres:10.3       "docker-entrypoint.s…"   postgres            52 seconds ago      Up 52 seconds       5432/tcp, 0.0.0.0:32768->3306/tcp, :::32768->3306/tc
```

The blog container will most likely not start the first time. Restart the blog container,

```bash
docker exec -it tornado-backend_postgres_1 psql -U blog -d blog
docker-compose restart blog
[+] Restarting 1/1
 ✔ Container tornado-backend-blog-1  Started                                                                                           0.2s 
```

1) Check the entries of the authors table,
### Step 4) Use the blog web app

* Visit [http://localhost:8888](http://localhost:8888)
* Enter Email, Name and Password, e.g.,
  * Email: `first-blogger@blog.com`
  * Name: `First Blogger`
  * Password: `blogger-01`
* Write your first blog entry
  * `First blog of first blogger`
  * `This is the first blog post of the first blogger...`

### Step 5) Enter the postgres container and check the entries

Enter the postgres database container using,

```bash
docker exec -it tornado-backend-postgres-1 psql -U blog -d blog
```

Check the entries of the authors table,

```psql
SELECT * from authors;
```

Which results in, e.g., 
which results in e.g.,

```psql
blog=# SELECT * from authors;
 id |         email          |     name      |                       hashed_password                        
----+-----------------------+---------------+--------------------------------------------------------------
  1 | first-blogger@blog.de | First Blogger | $2b$12$G0JKWQT7Tx1DoVqjze2mruM.kxmhP0EeiltKesZT5ZpqWlNnu3dOe
----+------------------------+---------------+--------------------------------------------------------------
  1 | first-blogger@blog.com | First Blogger | $2b$12$Zc.M1yvB598t1b8j2F1nEeJ.dsegUTmVsk262OwtFtJIrkxOZIRu.
(1 row)
```

2) Check the entries of the entries table,
Check the entries of the entries table

```psql
SELECT * from entries;
```

Which results in, e.g., 
which results in e.g.,

```psql
blog=# SELECT * from entries;
id | author_id |            slug             |            title            |                      markdown                       |                            html           
                 |         published          |          updated           
----+-----------+-----------------------------+-----------------------------+------------------------------------------------+----------------------------------
---------------------+----------------------------+----------------------------
  1 |         1 | first-post-by-first-blogger | First post by first blogger | This is the first post by the first blogger... | <p>This is the first post by the 
first blogger...</p> | 2024-12-06 17:23:18.595355 | 2024-12-06 17:23:18.595355
----+-----------+-----------------------------+-----------------------------+-----------------------------------------------------+-------------------------------------------
-----------------+----------------------------+----------------------------
  1 |         1 | first-blog-of-first-blogger | First blog of first blogger | This is the first blog post of the first blogger... | <p>This is the first blog post of the firs
t blogger...</p> | 2024-12-18 22:30:51.994281 | 2024-12-18 22:30:51.994281
(1 row)
```

### Step 6) Stop the container

```bash
docker-compose down
```