Python Web Project Examples
This page provides examples of using Mill as a build tool for Python web applications. It includes setting up a basic "Hello, World!" application and developing a fully functional TodoMVC app with Flask and Django, showcasing best practices for project organization, scalability, and maintainability.
Flask Hello World App
This example uses Mill to manage a Flask app that serves "Hello, Mill!"
at the root URL (/
), with Flask installed as a dependency
and tests enabled using unittest
.
package build
import mill._, pythonlib._
object foo extends PythonModule {
def mainScript = Task.Source { millSourcePath / "src/foo.py" }
def pythonDeps = Seq("flask==3.1.0")
object test extends PythonTests with TestModule.Unittest
}
Running these commands will test and run the Flask server with desired outputs.
The app is ready to serve at http://localhost:5000
.
> ./mill foo.test
...
test_hello_flask (test.TestScript...)
Test the '/' endpoint. ... ok
...
Ran 1 test...
OK
...
> ./mill foo.runBackground
> curl http://localhost:5000
...<h1>Hello, Mill!</h1>...
> ./mill clean foo.runBackground
Flask TodoMVC App
This is a Flask
-based TodoMVC application managed and built using Mill
.
It allows users to add
, edit
, delete
, and view
tasks stored in a Python Data Structure.
Tasks can be filtered as all
, active
, or completed
based on their state.
The application demonstrates dynamic rendering using Flask’s routing and templating features.
package build
import mill._, pythonlib._
object todo extends PythonModule {
def mainScript = Task.Source { millSourcePath / "src/app.py" }
def pythonDeps = Seq("flask==3.1.0", "Flask-SQLAlchemy==3.1.1", "Flask-WTF==1.2.2")
object test extends PythonTests with TestModule.Unittest
object itest extends PythonTests with TestModule.Unittest
}
Apart from running a web server, this example demonstrates:
-
Serving HTML templates using Jinja2 (Flask’s default templating engine).
-
Managing static files such as JavaScript, CSS, and images.
-
Filtering and managing tasks in-memory using Python data structures.
-
Unit testing using unittest for testing task operations.
-
Integration testing using unittest for end-to-end application behavior.
This example also utilizes Mill for managing dependencies
, builds
, and tests
,
offering an efficient development workflow.
The app is ready to serve at http://localhost:5001
.
> ./mill todo.test
...
test_add_todo (test.TestTodoApp...) ... ok
test_delete_todo (test.TestTodoApp...) ... ok
test_edit_todo (test.TestTodoApp...) ... ok
test_filter_todos (test.TestTodoApp...) ... ok
test_toggle_all (test.TestTodoApp...) ... ok
test_toggle_todo (test.TestTodoApp...) ... ok
...Ran 6 tests...
OK
...
> ./mill todo.itest
...
test_add_and_list_todos (test.TestTodoAppIntegration...) ... ok
test_delete_todo (test.TestTodoAppIntegration...) ... ok
test_edit_and_list_todos (test.TestTodoAppIntegration...) ... ok
test_toggle_all_todos (test.TestTodoAppIntegration...) ... ok
test_toggle_and_list_todos (test.TestTodoAppIntegration...) ... ok
...Ran 5 tests...
OK
...
> ./mill todo.runBackground
> curl http://localhost:5001
...What needs to be done...
> ./mill clean todo.runBackground
Django Hello World App
This example demonstrates a minimal Django
application managed with Mill.
It features a simple view that returns <h1>Hello, Mill!</h1>
and
includes Django’s
core functionality for testing
and running
a development server.
package build
import mill._, pythonlib._
object foo extends PythonModule {
def mainScript = Task.Source { millSourcePath / "src/manage.py" }
def pythonDeps = Seq("django==5.1.4")
}
Using Mill
, we can easily manage dependencies, run Django tests
, and launch the server
.
With just a few commands, the app is ready to serve at http://localhost:5002
.
> ./mill foo.run test main -v 2 # using inbuilt `django test`, `main` is the app name, `-v 2` is verbosity level 2
...
System check identified no issues (0 silenced).
test_index_view (main.tests.TestScript...)
Test that the index view returns a 200 status code ... ok
...
Ran 1 test...
OK
...
> ./mill foo.runBackground runserver 5002
> curl http://localhost:5002
...<h1>Hello, Mill!</h1>...
> ./mill clean foo.runBackground
Django TodoMVC App
This Django
TodoMVC example is a task management application built using Mill
Build Tool.
It features dynamic HTML
rendering with Django’s
template engine, CRUD
operations with
Django ORM
, and efficient form handling for managing tasks.
package build
import mill._, pythonlib._
object todo extends PythonModule {
def mainScript = Task.Source { millSourcePath / "src/manage.py" }
def pythonDeps = Seq("django==5.1.4")
}
Apart from running a web server
, this example demonstrates:
-
Serving HTML templates using Django’s template engine.
-
Managing static files such as JavaScript, CSS, and images.
-
Querying a SQL database using Django ORM with an SQLite backend.
-
Filtering and managing tasks using SQLite database.
-
Unit + Integration testing using Django’s inbuilt testing framework.
-
URL routing and views for CRUD operations.
This Mill Build File simplifies dependency management
, database migrations
, and testing workflows
.
Running these commands will test
and run
the Django Todo App
.
The app is ready to serve at http://localhost:5003
.
> ./mill todo.run makemigrations
...Migrations for 'main'...
...+ Create model Todo...
> ./mill todo.run migrate
...Operations to perform...
...Apply all migrations: admin, auth, contenttypes, main, sessions...
...Running migrations...
...OK...
> ./mill todo.run test main -v 2
...Found 8 test(s)...
test_add_todo_view (main.tests.TodoAppTests...) ... ok
test_clear_completed_view (main.tests.TodoAppTests...) ... ok
test_delete_todo_view (main.tests.TodoAppTests...) ... ok
test_edit_todo_view (main.tests.TodoAppTests...) ... ok
test_index_view (main.tests.TodoAppTests...) ... ok
test_list_todos_view (main.tests.TodoAppTests...) ... ok
test_toggle_all_view (main.tests.TodoAppTests...) ... ok
test_toggle_todo_view (main.tests.TodoAppTests...) ... ok
...Ran 8 tests...
...OK...
> ./mill todo.runBackground runserver 5003
> curl http://localhost:5003
...What needs to be done...
> ./mill clean todo.runBackground