Masonite 3.0 to 4.0
Masonite 4 is the biggest change in a Masonite release we have ever had. Smaller applications may benefit from creating a new app and then copying and pasting controllers, routes and views to the new installation.
For medium to large scale applications, you will need to go through the codebase and upgrade everything to use the new structures we have available in Masonite 4.
It is highly recommended that you start at Masonite 3 before upgrading to Masonite 4. If you are running any version less than Masonite 3 then please use the upgrade guide to upgrade to each version first.

Python Version

Masonite 4 drops support for Python 3.6. You will have to upgrade to Python 3.7+ in order to run Masonite

Install Masonite 4

First step of the upgrade guide is to uninstall Masonite 3 and install Masonite 4:
1
$ pip uninstall masonite
2
$ pip install masonite==4.0.0
Copied!

Craft File

The next step of the upgrade guide is to replace your craft file. This is a basic file in the root of your project that will be used whenever you run python craft. We will use this to keep testing our server:
Go to this file and copy and paste it into your own craft file in the root of your project. If you are running Masonite 3 then you should already have this file.

Kernel File

Masonite 4 has a new Kernel.py file which is used to customize your application and contains necessary bootstrapping to start your application.
You will also need to put this into the base of your project.
Go to this file and paste it into your own Kernel.py file in the root of your project.
Now go through this file and customize any of the locations. Masonite 4 uses a different file structure than Masonite 3. For example, Masonite 3 put all views in resources/templates while Masonite 4 has them just in templates.
Because of this, you can either change where the files are located by moving the views to a new templates directory or you can change the path they are registered in your Kernel:
Go to your register_configurations method in your Kernel and inside your register_templates method you can change it to
1
def register_templates(self):
2
self.application.bind("views.location", "resources/templates")
Copied!
Go through the rest of the methods and make sure the paths are set correctly.

Providers

Add the following providers to your project:
1
from masonite.providers import FrameworkProvider, HelpersProvider, ExceptionProvider, EventProvider, HashServiceProvider
2
3
PROVIDERS = [
4
FrameworkProvider,
5
ExceptionProvider,
6
EventProvider,
7
HashServiceProvider,
8
Copied!

Routes

Routes have changed slightly.
First, routes are now all under the Route class. The route classes have moved into methods:
1
from masonite.routes import Route
2
ROUTES = [
3
- Get('/', '[email protected]').name('home')
4
- Post('/login', '[email protected]').name('home')
5
+ Route.get('/', '[email protected]').name('home')
6
+ Route.post('/', '[email protected]').name('home')
7
]
Copied!

WSGI File

The WSGI file has also changed.
Go to this file and replace your own wsgi.py file

Import Path Changes

The import path has changed for the following:
1
- from masonite.helpers import random_string
2
+ from masonite.utils.str import random_string
3
4
- from masonite import Mail
5
+ from masonite.mail import Mail
6
7
- from masonite.view import View
8
+ from masonite.views import View
9
10
- from masonite.auth import Auth
11
+ from masonite.authentication import Auth
12
13
- from masonite import env
14
+ from masonite.environment import env
15
16
- from masonite.helpers import password
17
+ from masonite.facades import Hash #== See Hashing documentation
18
19
- from masonite.middleware import CsrfMiddleware as Middleware
20
+ from masonite.middleware import VerifyCsrfToken as Middleware
21
22
- from masonite.helpers import config
23
+ from masonite.configuration import config
24
25
- from masonite.drivers import Mailable
26
+ from masonite.mail import Mailable
27
28
- from masonite.provider import ServiceProvider
29
+ from masonite.providers import Provider
Copied!

Request and Response redirects

Previously when we had to do a redirection we would use the request class:
1
def store(self, request: Request):
2
return request.redirect('/home')
Copied!
This has now been changed to the response class:
1
from masonite.response import Response
2
3
def store(self, response: Response):
4
return response.redirect('/home')
Copied!
Same applies to back redirection:
1
- return request.back()
2
+ return response.back()
Copied!

Middleware

Middleware has been moved to this new Kernel file. Middleware now works a little different in M4. Middleware has changed in the following ways:
  1. 1.
    middleware no longer needs an __init__ method.
  2. 2.
    Middleware requires the request and response parameters inside the before and after methods.
  3. 3.
    Middleware requires either the request or response to be returned
Middleware will change in the following example:
Old:
1
class AdminMiddleware:
2
def __init__(self, request: Request):
3
"""Inject Any Dependencies From The Service Container.
4
Arguments:
5
Request {masonite.request.Request} -- The Masonite request object
6
"""
7
self.request = request
8
9
def before(self):
10
if not optional(self.request.user()).admin == 1:
11
self.request.redirect('/')
12
13
def after(self):
14
pass
Copied!
To this:
1
class AdminMiddleware:
2
3
def before(self, request, response):
4
if not optional(request.user()).admin == 1:
5
return response.redirect('/')
6
7
def after(self, request, response):
8
pass
Copied!

User Model & Authentication

Masonite 4 uses the same Masonite ORM package as Masonite 3 but changes a lot of the authentication.
Inherit a new Authenticates class
1
from masonite.authentication import Authenticates
2
from masoniteorm.models import Model
3
4
class User(Model, Authenticates):
5
# ..
Copied!
Authentication has also changes slightly. Whenever you are logging in a user the following UI has changed:
1
- auth.login(request.input('email'), request.input('password'))
2
+ auth.attempt(request.input('email'), request.input('password'))
Copied!

Controllers

Controllers have not changes much but in order for routes to pick up your string controllers, you must inherit from Masonite controller class:
1
from masonite.controllers import Controller
2
3
class DashboardController(Controller):
4
# ..
Copied!
The rest of your controller structure remains the same.

Routes

Config Changes

Application

Add the following to the config/application.py file.
1
HASHING = {
2
"default": "bcrypt",
3
"bcrypt": {"rounds": 10},
4
"argon2": {"memory": 1024, "threads": 2, "time": 2},
5
}
Copied!

Auth

Change the AUTH constant to the new GUARDS configuration:
1
GUARDS = {
2
"default": "web",
3
"web": {"model": User},
4
"password_reset_table": "password_resets",
5
"password_reset_expiration": 1440, # in minutes. 24 hours. None if disabled
6
}
Copied!
Add a new config/exceptions.py file:
1
HANDLERS = {"stack_overflow": True, "solutions": True}
Copied!

Storage -> Filesystem

The config/storage.py file has been replaced with a config/filesystem.py file:
Go to this file and copy it into your project. Then move the STATICFILES from your storage config into this new filesystem config

Session

Change the config/session.py to the following:
1
DRIVERS = {
2
"default": "cookie",
3
"cookie": {},
4
}
Copied!

Middleware

After you upgrade all your middleware, you will need to move them from the config/middleware.py file to the top of your Kernel file:
1
from some.place import CustomMiddleware
2
class Kernel:
3
4
# ...
5
route_middleware = {"web": [
6
# ...
7
CustomMiddleware
8
],
Copied!

Session

get_flashed method has changed to just get. Here is an example in your templates:
1
- {{ session().get_flashed('success') }}
2
+ session().get('success')
Copied!

Static Helper

The static helper has changed to asset:
1
- {{ static('s3.uploads', 'invoice.pdf') }}
2
+ {{ asset('s3.uploads', 'invoice.pdf') }}
Copied!
Finally after all the above changes attempt to run your server:
1
$ python craft serve
Copied!
Last modified 2mo ago