A simple ToDo application created to practice Python skills and expand my programming portfolio.
This directory contains three versions, a desktop app built with PySide6, a console app written in pure Python and a web version built with Vite + React + TypeScript, all connected to a Django REST backend. Depending on which one you wish to run, choose desktop/ directory for the desktop version, console/ directory for the console version or web/ directory for the web version.
This project was built to practice structuring multi-layered Python applications (backend + desktop + CLI + web) and to demonstrate understanding of REST APIs, database migrations, and GUI design.
Note: All the versions have their own tests if you wish to run them you can!
- Automated Environment: Introduced a robust
start.shbash script that drastically improves Developer Experience (DX). It runs the API and Web frontend concurrently, automatically handles dependency installations (poetry&npm), runs database migrations, and safely cleans up ports and background processes on exit. - Modernization & Refactoring: Ongoing process of splitting monolithic React structures into smaller, reusable components, and upgrading overall application security.
- π How to Start
- π³ Docker Support
- ποΈ API Setup
- π§ͺ Tests
- π§ About App Files
- π¦ Structure
- β Example Features
- π‘ Future Improvements
- π§ͺ Build & Run with Docker Compose
- π GitHub Actions CI/CD
- π License
The absolute easiest way to start the web application and backend API is by using the automated startup script.
- Give the script execution permissions (only needed once):
chmod +x start.sh
Run the application:
./start.shThis script will automatically check and install all required Python and Node.js packages, apply database migrations, and spin up both the Django API and the Vite React App. Press Ctrl+C in the terminal to gracefully stop all services and free the ports.
API uses Django REST Framework for the API layer. Requirements: Poetry must be installed. Python 3.10+ recommended.
If you prefer to start services manually, or if you want to run the Desktop or Console versions:
Start the API: Go to the api/src directory and run:
poetry install
poetry run python manage.py runserverStart a Client (Choose one):
Web version: Go to the web/ directory and run:
npm i
npm run devDesktop version: Go to the desktop directory and run:
poetry install
poetry run python main.pyConsole version: Go to the console/ directory and run:
poetry install
poetry run python ToDo.pyYou can also run the entire app using Docker!
Build & Run with Docker Compose Make sure you have Docker and Docker Compose installed.
cd docker
docker-compose up --buildThis will spin up the following services:
-
π backend (Django API)
-
π web (Vite + React)
-
π₯οΈ desktop (PySide6 GUI)
-
π» console (CLI version)
Note: Desktop and Console services run in containers and are mainly useful for debugging and CI β local use is still easier outside Docker.
To stop the containers, use Docker Desktop or run:
docker-compose downIf you are not using start.sh or Docker, and running the project for the very first time manually, you need to set up the database:
cd api/src
poetry run python manage.py makemigrations
poetry run python manage.py migrateThis will generate the database and create the required tables. All backend endpoints are located in api/src/api/views.py. The app provides standard CRUD operations via REST.
This project includes tests for each part of the application:
- Web:
web/src/App.test.tsxβ unit tests for frontend logic and UI - Desktop:
desktop/tests/β unit tests for GUI components and business logic - Console:
console/- unit tests for CLI logic - Backend:
api/src/api/tests/β Django tests for API endpoints
To run the tests, go to the corresponding directory and use:
# For web
npm run test
# For backend
poetry run python manage.py test
# For console
poetry run python test.py
# For desktop
poetry run pytestThe App.tsx file contains the web frontend and all the logic that handles API requests and responses.
App- Main function responsible for running every other part of this codefetchTasks- gets the tasks from the API so that the data can be used in the rest of the codehandleSubmit- function that handles code behaviour after user submits the form for adding tasksdisplayTasks- displays all the tasks that have been fetched from the API in the table on the webAddTask- handles adding a task via an API requestUpdateTask- handles changing task status in the database via an API request (βDoneβ β βUndoneβ)DeleteTask- handles deleting tasks from the database via an API request
The main_window.py file contains the main layout and logic of the app. It includes:
- All the visual elements of the app that you are able to see and interact with once the app starts
display_menu()β Displays the menu and handles user inputload_data()β Utility function for fetching data from the backend.add_task(),display_tasks(),mark_task_as_done(),delete_task()β Main task-handling functions that interact with the backend
The ToDo.py file contains the CLI logic and handles communication with the backend. It includes functions for API requests and the main application loop.
display_menu()β Displays the menu and handles user inputload_data()β Utility function for fetching data from the backend.add_task(),display_tasks(),mark_task_as_done(),delete_task()β Main task-handling functions that interact with the backend
.
βββ .github/
β βββ workflows/
β βββ docker-build.yml # GitHub Actions workflow for building Docker images
βββ README.md # Project documentation
βββ LICENSE # Project license
βββ pyproject.toml # Poetry project configuration
βββ poetry.lock # Exact versions of installed dependencies
βββ main.py # Main entry point for the desktop application
βββ api/
β βββ src/
β β βββ api/ # Django app for API
β β β βββ __init__.py
β β β βββ admin.py # Django admin config (optional)
β β β βββ apps.py # App configuration
β β β βββ models.py # Database models
β β β βββ serializers.py # DRF serializers
β β β βββ tests/ # Unit tests for the app
β β β βββ urls.py # App-specific URL routes
β β β βββ views.py # API views/endpoints
β β βββ myapi/ # Django project configuration
β β β βββ __init__.py
β β β βββ asgi.py
β β β βββ settings.py # Main project settings
β β β βββ urls.py # Project URL routing
β β β βββ wsgi.py
β β βββ db.sqlite3 # SQLite database
β β βββ manage.py # Django management script
β βββ tests/
β βββ __init__.py # Placeholder for tests
βββ desktop/
β βββ assets/ # Static assets like icons, images or styles
β βββ tests/ # Unit tests for GUI
β βββ models/ # Business logic and data layer for the desktop app
β β βββ __init__.py
β β βββ api_client.py # Handles API communication
β βββ ui/ # User interface components
β βββ __init__.py
β βββ main_window.py # Main application window UI
βββ console/
β βββ ToDo.py # Console CLI version of the application
β βββ test.py # Unit tests for the CLI
βββ web/ # Frontend React + Vite application
β βββ node_modules/ # Node.js dependencies
β βββ public/ # Static public assets (favicon, etc.)
β βββ src/ # Source code of the frontend
β β βββ assets/ # Images, icons, fonts used by React app
β β βββ App.css # App component styles
β β βββ App.test.tsx # Unit tests for logic and web display elements
β β βββ App.tsx # Main App component
β β βββ index.css # Global styles
β β βββ main.tsx # React entry point
β β βββ vite-env.d.ts # Vite TypeScript environment declarations
β βββ .gitignore # Files and folders to ignore by Git
β βββ eslint.config.js # ESLint configuration
β βββ index.html # HTML template
β βββ package.json # NPM project metadata and scripts
β βββ package-lock.json # Exact versions of installed npm dependencies
β βββ tsconfig.json # Base TypeScript configuration
β βββ tsconfig.app.json # TypeScript config for app compilation
β βββ tsconfig.node.json # TypeScript config for Node tools
β βββ vite.config.ts # Vite configuration file
βββ docker/
βββ docker-compose.yml # Main Docker Compose file to run all services
βββ dockerfile.backend # Dockerfile for the Django backend
βββ dockerfile.web # Dockerfile for the web frontend
βββ dockerfile.desktop # Dockerfile for the desktop GUI app
βββ dockerfile.console # Dockerfile for the console CLI version
- Task title, description, deadline
- Marking tasks as completed
- Deleting tasks
- Filtering tasks by status
- All data stored in a database via Django backend
- CLI
- Categories/tags
- Search options
- Sorting by deadline
- User Authentication
Make sure you have Docker and Docker Compose installed.
You can install Docker Desktop here: Install Docker Desktop
cd docker
docker-compose up --buildThis will spin up the following services:
- π backend (Django API)
- π web (Vite + React)
- π₯οΈ desktop (PySide6 GUI)
- π» console (CLI version)
Note: Desktop and Console services run in containers and are mainly useful for debugging and CI β local use is still easier outside Docker.
To Stop the container you can either do so manually in docker desktop or by:
docker-compose down *container-name*This repository includes a GitHub Actions workflow at:
.github/workflows/docker-build.ymlThis workflow automatically builds and validates all Docker images on every push to ensure your containers stay in a working state.
Licensed under CC0 1.0 Universal.

