Masonite 2.1 is a fantastic release. It works out a lot of the kinks that were in 2.0 as well as brings several new syntactically good looking code generation
This guide just shows the major changes between version to get your application working on 2.1. You should see the What's New in 2.1 documentation to upgrade smaller parts of your code that are likely to be smaller quality of life improvements.
For 2.1 you will need
Make sure you run:
$ pip install masonite-cli --upgrade
Middleware has been changed to classes so instead of doing this in your
HTTP_MIDDLEWARE = ['app.http.middleware.DashboardMiddleware.DashboardMiddleware',]
You will now import it directly:
import app.http.middleware.DashboardMiddleware import DashboardMiddlewareHTTP_MIDDLEWARE = [DashboardMiddleware,]
This is likely the biggest change in 2.0. Before 2.1 you were able to fetch by key when resolving by doing something like:
def show(self, Request):Request.input(..)
We have removed this by default and now you much explicitly import your classes in order to interact with the container resolving:
from masonite.request import Requestdef show(self, request: Request):request.input(..)
If you truly do not like this change you can modify your container on a per project basis by adding this to your container constructor in
container = App(resolve_parameters=True)
Just know this is not recommended and Masonite may or may not remove this feature entirely at some point in the future.
Previously we were able to do something like this:
def show(self, Mail):Mail.to(..)
Since we never actually created a class from this and you were not able to explicitly resolve this, we utilized the new container swapping in order to swap a class out for this container binding.
All instances above should be changed to:
from masonite import Maildef show(self, mail: Mail):mail.to(..)
Don't forgot to also do your
boot methods on your Service Providers as well:
def boot(self, request: Request):..request..
As well as all your middleware and custom code:
class AuthenticationMiddleware(object):""" Middleware To Check If The User Is Logged In """def __init__(self, request: Request):""" Inject Any Dependencies From The Service Container """self.request = request...
You may have classes you binded personally to the container like this:
def slack_send(self, IntegrationManager):return IntegrationManager.driver('slack').scopes('incoming-webhook').state(self.request.param('id')).redirect()
To get this in line for 2.1 you will need to use Container Swapping in order to be able to resolve this. This is actually an awesome feature.
First go to your provider where you binded it to the container:
from app.managers import IntegrationManagerdef boot(self):self.app.bind('IntegrationManager', IntegrationManager.driver('something'))
and add a container swap right below it by swapping it with a class:
from app.managers import IntegrationManagerdef boot(self):self.app.bind('IntegrationManager', IntegrationManager.driver('somedriver'))self.app.swap(IntegrationManager, IntegrationManager.driver('somedriver'))
now you can use that class to resolve:
from app.managers import IntegrationManagerdef slack_send(self, manager: IntegrationManager):return manager.driver('slack').scopes('incoming-webhook').state(self.request.param('id')).redirect()
Completely removed the
masonite.facades module and put the only class (the
Auth class) in the
So all instances of:
from masonite.facades.Auth import Auth
need to be changed to:
from masonite.auth import Auth
StartResponseProvider was not doing anything crazy and it could be achieved with a simple middleware. This speeds up Masonite slightly by offsetting where the response preparing takes place.
Simply remove the
StartResponseProvider from your
PROVIDERS = [# Framework ProvidersAppProvider,SessionProvider,RouteProvider,StatusCodeProvider,# StartResponseProvider,WhitenoiseProvider,ViewProvider,HelpersProvider,...
As well as put the new middleware in the HTTP middleware
from masonite.middleware import ResponseMiddleware..HTTP_MIDDLEWARE = [LoadUserMiddleware,CsrfMiddleware,HtmlMinifyMiddleware,ResponseMiddleware, # Here]
In 2.0 you had to fetch incoming JSON payloads like this:
So now all instances of the above can be used normally:
CSRF middleware now lives in core and allows you to override some methods or interact with the middleware with class attributes:
Replace your current CSRF Middleware with this new one:
""" CSRF Middleware """from masonite.middleware import CsrfMiddleware as Middlewareclass CsrfMiddleware(Middleware):""" Verify CSRF Token Middleware """exempt = 
If you made changes to the middleware to prevent middleware from being ran on every request you can now set that as a class attribute:
""" CSRF Middleware """from masonite.middleware import CsrfMiddleware as Middlewareclass CsrfMiddleware(Middleware):""" Verify CSRF Token Middleware """exempt = every_request = False
This also allows any security issues found with CSRF to be handled on all projects quickly instead of everyone having to patch their applications individually.
In migrations (and seeds) you will need to put this import inside a
__init__.py file in order to allow models to be imported into them
import osimport syssys.path.append(os.getcwd())
There was a slight change in the
bootstrap/start.py file around
Needs to be changed to:
You no longer should bind directly to the
Response key in the container. You should use the new Response object.
All instances of:
self.app.bind('Response', 'some value')
should now be:
and any instance of:
should be changed to:
Restructuring some sample code would be changing this:
Cache.cache_exists() has been changed to just
Cache.exists(). You will need to make changes accordingly:
from masonite import Cachedef show(self, cache: Cache):# Fromcache.cache_exists('key')# Tocache.exists('key')
That is all the main changes in 2.1. Go ahead and run your server and you should be good to go. For a more up to date list on small improvements that you can make in your application be sure to checkout the Whats New in 2.1 documentation article.
Although not a critical upgrade, it would be a good idea to replace all instances of retrieval of environment variables with the new
Change all instances of this:
import os..DRIVER = os.getenv('key', 'default')..KEY = os.envrion.get('key', 'default')
with the new
from masonite import env..DRIVER = env('key', 'default')..KEY = env('key', 'default')
What this will do is actually type cast accordingly. If you pass a numeric value it will cast it to an int and if you want a boolean if will cast
false to booleans like this:
if you don't want to cast the value you can set the
cast parameter to
KEY = env('key', 'default', cast=False)
We removed the
store_prepend() method on the upload drivers for the
filename keyword arg on the store method.