Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
There are plenty of ways to contribute to open source. Many of which don't even rely on writing code. A great open source project should have excellent documentation, a thriving community and have as little bugs as possible. Below I will explain how to contribute to this project in different ways both including and exluding code contributions.
This is not an exhaustive list and not the only ways to contribute but they are the most common. If you know of other ways to contribute then please let us know.
Of course the project requires contributions to the main development aspects but it's not the only way. But if you would like to contribute to development then a great way to get started is to simply read through this documentation. Get acquainted with how the framework works, how Controllers and Routing work and read the Architectural Concepts documentation starting with the Request Lifecycle, then the Service Providers and finally the Service Container.
It would also be good to read about the Release Cycle to get familiar with how Masonite does releases (SemVer and RomVer).
Feature Maintainers are people who are in charge of specific features (such as Caching or Creating Packages). These developers will be in charge of reviewing PR's and merging them into the development branch and also have direct contact with the repository owner to discuss.
Feature maintainers must already have significant contributions to development of the repository they are trying to be a Feature Maintainer for. Although they do not have to be contributors to the actual feature they plan to maintain.
If you don't want to touch the code and instead want to just look at it and figure it out, contribute some comments! Comments are an excellent way for future developers to read and understand the framework. Masonite strives on being extremely commented. Although most of the code itself does not need to be commented, some of the classes, modules, methods and functions do (although a lot of them already are).
Comments don't affect the working code so if you want to get used to contributing to open source or you just don't quite understand what a class method is doing or you are afraid of contributing and breaking the project (there are tests) then contributing comments is right for you!
The Masonite pip packages require testing (The main repository does not). If you want to search through all the tests in the tests directories of those repositories and write additional tests and use cases then that will be great! There are already over 100 tests but you can always write more. With more testing comes more stability. Especially as people start to contribute to the project. Check the tests that are already there and write any use cases that are missing. These tests can be things such as special characters in a url or other oddities that may not have been thought of when using TDD for that feature.
Once familiar with the project (by either contributing or by building application using the framework) it would be excellent if you could write or record tutorials and put them on Medium or YouTube. In order for the framework to be successful, it needs to have a plethora of documentation even outside of this documentation. It needs to have notoriety and if people are seeing the framework pop up in their favorite locations they will be more inclined to use the framework and contribute to it as well.
Plus there will be fantastic tutorials out there for beginners to find and watch and you could also build a following off the back of Masonite.
This documentation is fantastic but there are spots where it could be improved. Maybe we haven't explained something fully or something just doesn't make sense to you. Masonite uses Gitbook.com to host it's documentation and with that you are able to comment directly on the documentation which will start a discussion between you and the documentation collaborators. So if you want to cycle through the documentation page by page and get acquainted with the framework but at the same time contribute to the documentation, this is perfect for you.
If you just don't want to contribute code to the main project you may instead simply report bugs or improvements. You can go ahead and build any of your applications as usual and report any bugs you encounter to the GitHub.com issues page.
Look at the issues page on GitHub.com for any issues, bugs or enhancements that you are willing to fix. If you don't know how to work on them, just comment on the issue and Joseph Mancuso or other core contributors will be more than happy explaining step by step on how you can go about fixing or developing that issue.
If you have a large following on any social media or no following at all, you can contribute by trying to build up a following around Masonite. Any open source project requires an amazing community around the framework. You can either build up a community personally and be the leader of that community or you can simply send them to Masonite's GitHub repository where we can build up a community around there.
Another idea is to use Masonite to build applications such as a screencast website like LaraCasts.com or an official Masonite website or even a social network around Masonite. Every great framework needs it's "ecosystem" so you may be apart of that by building these applications with the Masonite branding and logos. Although copying the branding requires an OK from Joseph Mancuso, as long as the website was built with Masonite and looks clean it shouldn't be a problem at all.
Questions will come in eventually either through the GitHub issues or through websites like StackOverflow. You could make it a priority to be the first to answer these peoples questions or if you don't know the answer you can redirect one of the core maintainers or contributors to the question so we can answer it further.
Most pull requests will sit inside GitHub for a few days while it gets quality tested. The main develop
branch pull requests could sit there for as long as 6 months and will only be merged in on releases. With that being said, you can look at the file changes of these pull requests and ensure they meet the community guidelines, the API is similar to other aspects of the project and that they are being respectful and following pull requests rules in accordance with the Contributing Guide documentation.
Every now and then will be a requires discussion
label on an issue or pull request. If you see this label then be sure to add your thoughts on an issue. All issues are open for discussion and Masonite strives off of developer input so feel free to enter a discussion.
Every framework needs great packages and we as the maintainers of Masonite can only do so much with coming out with great packages and maintaining the framework at the same time. We look forward to our community coming out with awesome additions to the Masonite ecosystem. If you have any issues then be sure to open in the gitter chatroom on the Github homepage.
Masonite 1.5 is focused on a few bug fixes and changes to several core classes in order to expand on the support of third party package integration.
Masonite 1.5 is releasing also with a new official package for adding RESTful API's to your project. This package used API Resources which are classes that can add a plethora of capabilities to your API endpoints. You can read more about it at the Masonite Entry documentation.
Masonite 1.5 also adds additional support HTTP methods like PUT
, PATCH
and DELETE
. More information about these new routes can be found under the Routing documentation
Nearly all dependencies have been moved to the core Masonite package. The only thing inside the project that is installed using craft new
is the WSGI server (which is waitress by default) and Masonite itself. This will improve the ability to change and update dependencies.
HTML forms only support GET and POST so there is no the ability to add any other HTTP methods like PUT
and PATCH
which will change the actual request method on submission. You can read more about this in the Requests documentation.
You can now use functions for routes instead of the classes. These new functions are just wrappers around the classes itself. Read more about this under the Routing documentation.
In Masonite 1.4 and below was the Api()
route which added some very basic API endpoints. All references to API's have been removed from core and added to the new Masonite Entry official package.
If you would like to use API's you will have to use the Masonite Entry package instead.
You can now get and set any header information using the new Request.header
method. This also allows third party packages to manipulate header information. Read more about this in the Requests documentation.
You can now delete cookies using the delete_cookie
method as well as set expiration dates for them. See the Requests documentation for more information.
The Cache driver now has an update method which can update a cache value by key. This is useful if you want to change a key value or increment it. Storing a cache file also now auto creates that directory. Read more about this in the Caching documentation.
Craft commands have been built from the ground up with the cleo package. It's an excellent package that is built around the extendability of commands by using primarily classes (instead of decorator functions). Read more under The Craft Command documentation
It is now possible to add craft commands to craft. You can read more about how under The Craft Command documentation
You can now add more migration directories by adding it to the container with a key ending in MigrationDirectory
. This will add the directory to the list of directory that run when migrate commands are ran. You can read more about this in the Creating Packages documentation.
You can now add data to sessions using the new Sessions feature which comes with a memory and cookie driver for storing data.
In previous versions, Masonite has not been able to fetch the site packages directory if you were in a virtual environment because virtual environment directories are dynamically named depending on who created it. We have found a way to detect the virtual environment and the site packages directory so now there is no need to add the site packages directory manually to the packages configuration file
The Masonite framework itself follows the RomVer versioning schema which is PARADIGM.MAJOR.MINOR
although all Masonite packages follow the SemVer versioning schema which is MAJOR.MINOR.BUGFIX
.
This means that a framework version of 1.3.20 may have breaking changes with version 1.4.0. Masonite uses a 6 month major release cycle in order to maintain it's state as a modern Python web framework. Each release is a solid and stable release and upgrading typically takes minimal time.
The Masonite main repository (the MiraFramework/masonite
repository) contains only the basic file structure of the application. All of the core framework functionality is inside the MasoniteFramework/core
repository which can be updated as much as every day or once per month.
Because MiraFramework/masonite
does not require major updates, we can follow RomVer nicely and keep the versioning number artificially lower. Any major updates to this repsository will likely just be file structure changes which should rarely happen unless there are major architectural changes.
Masonite is currently on a 6 month major release cycle. This means that once six months will be a new 2.x release.
Releases are planned to be upgradable from the previous release in 30 minutes or less. If they break that requirement then they should be considered for the next Paradigm release (the x.0.0
release)
Masonite is made up of three different repositories. There is
The main repository where development is done on the repo that installs on developer's systems.
The core repository which is where the main Masonite pip package is located.
The craft repository where the craft command tool is located.
Major 6 month releases will be released on or after the release date when all repositories are able to be released at the same time, as well as passing all tests.
The core repository is uploaded to PyPi under the new release. At this time, everyone could theoretically install the package. Once core is released, craft is updated for any minor changes it may require. Once these two repositories are completed, the masonite repository is updated and finally released. Once this repo is released to the latest version, all future projects will default to the latest version of Masonite.
After that we will bump the version of Masonite in the documentation and verify and update any documentation that is not up to standard.
Whenever the MasoniteFramework/craft
and MasoniteFramework/core
repositories are released on Github, Travis CI will run tests and automatically deploy to PyPi. These major version numbers should correspond to the version of Masonite they support. For example, if the MasoniteFramework/masonite
releases to version 1.4, MasoniteFramework/core
should bump up to 1.4.x regardless of changes.
The main repository which is MasoniteFramework/masonite
does not have a corresponding PyPi package and is only for installing new Masonite projects. See the craft new
command under The Craft Command documentation. The craft new
command will download a zip of the latest release of Masonite, unzip it and rename the folder. Once the next release for this repository is ready, it will be released but marked as a Pre-release
and therefore will not be installable by the default craft new
command.
This is so developers and maintainers will be able to test the new pre release with their applications. Once all QA tests have passed, it will be marked as a normal release and therefore all new applications created from there on out will be the new release.
Developers will still have the option of doing something like: craft new project_name --version 1.6
and installing that version of Masonite.
Once all three repositories are ready for release, they will all be released on GitHub under the respective new version numbers.
This page contains all deprecated code that may be removed in future versions of Masonite. These helpers are available to use for the remainder of the 2.1 lifetime but will be removed in either the next version (2.2) or the version after.
Some code inside Masonite becomes obsolete as new features become available. In order to make maintaining the codebase easier and clutter free, Masonite will start emitting deprecation warnings during minor releases of the current release.
For example if you upgrade from 2.1.20 to 2.1.21, you may start seeing deprecation warnings inside your console. You can safely ignore these warnings and your code will still work fine but may not work when upgrading to the next major version (for example from 2.1 to 2.2).
When you see these deprecation warnings, you will see a link as well that comes to this page. You should scroll down this page for examples on how to get your code up to date and not in a deprecated state. You should do this as soon as it becomes convenient for you to do so.
No code is scheduled for deprecation as of yet. This can change with future versions of Masonite
Masonite now has a built in caching class that you can use to either cache forever or cache for a specific amount of time.
Templates may have a lot of logic that are only updated every few minutes or even every few months. With template caching you can now cache your templates anywhere from every few seconds to every few years. This is an extremely powerful caching technique that will allow your servers to run less intensively and easily increase the performance of your application.
If a page gets hit 100 times every second then you can cache for 5, 10 or 15 seconds at a time to lessen the load on your server.
This feature only activates if you have the CacheProvider
loaded in your PROVIDERS
list. If you try to use these features without that provider then you will be hit with a RequiredContainerBindingNotFound
exception letting you know you are missing a required binding from a service provider. This provider comes out of the box in Masonite 1.4.
We have also updated the code to closely conform to PEP 8 standards.
Because of the caching features, we have added a bootstrap/cache
folder where all caching will be put but you can change this in the new config/cache.py
file.
Masonite 1.4 brings the idea of contracts which are very similar to interfaces in other languages. Contracts ensure that a driver or manager inherits has the same functionality across all classes of the same type.
Cross-Site Request Forgery is a crucial security milestone to hit and Masonite 1.4 brings that ability. With a new Service Provider and middleware, we can now add a simple {{ csrf_field }}
to our forms and ensure we are protected from CSRF attacks.
Managers were very redundant before this release so we made it much easier to create managers with 2 simple class attributes instead of the redundant method. Managers are used to manage features and drivers to Masonite.
Now the constructor of all middleware is resolved by the container. This means you may use the IOC dependency injection techniques like controller methods and drivers.
There were two unused imports in the models that Masonite created. These have been removed completely.
This section of the documentation will contain various tutorials. These are guides that are designed to take you from beginning to end on building various types of projects with Masonite. We may not explain things in much detail for each section as this part of the documentation is designed to just get you familiar with the inner workings of Masonite.
Since this section of the documentation is designed to just get you up and coding with Masonite, any further explanations that should be presented are inside various "hint blocks." Once you are done with the tutorial or simply want to learn more about a topic it is advised that you go through each hint block and follow the links to dive deeper into the reference documentation which does significantly more explaining.
You will see various hint blocks throughout the tutorials. Below are examples of what the various colors represent.
You'll see hint blocks that are green which you should follow if you want to learn more information about the topic currently being discussed.
You'll also see hint blocks that are blue. These should not be ignored and typically contain background information you need to further understand something.
In this tutorial we will walk through how to create a blog. We will touch on all the major systems of Masonite and it should give you the confidence to try the more advanced tutorials or build an application yourself.
Typically your first starting point for your Masonite development flow will be to create a route. All routes are located in routes/web.py
and are extremely simple to understand. They consist of a request method and a route method. Routing is simply stating what incoming URI's should direct to which controllers.
For example, to create a GET
request route it will look like:
We'll talk more about the controller in a little bit.
We will start off by creating a view and controller to create a blog post.
A controller is a simple class that holds controller methods. These controller methods will be what our routes will call so they will contain all of our application's business logic.
Think of a controller method as a function in the views.py
file if you are coming from the Django framework
Let's create our first route now. We can put all routes inside routes/web.py
and inside the ROUTES
list. You'll see we have a route for the home page. Let's add a route for creating blogs.
You'll notice here we have a BlogController@show
string. This means "use the blog controller's show method to render this route". The only problem here is that we don't yet have a blog controller.
All controllers are located in the app/http/controllers
directory and Masonite promotes 1 controller per file. This has proven efficient for larger application development because most developers use text editors with advanced search features such as Sublime, VSCode or Atom. Switching between classes in this instance is simple and promotes faster development. It's easy to remember where the controller exactly is because the name of the file is the controller.
You can of course move controllers around wherever you like them but the craft command line tool will default to putting them in separate files. If this seems weird to you it might be worth a try to see if you like this opinionated layout.
Like most parts of Masonite, you can scaffold a controller with a craft command:
This will create a controller in app/http/controllers
directory that looks like this:
Simple enough, right? You'll notice we have a show
method we were looking for. These are called "controller methods" and are similiar to what Django calls a "view."
But also notice we now have our show method that we specified in our route earlier.
We can return a lot of different things in our controller but for now we can return a view from our controller. A view in Masonite are html files or "templates". They are not Python objects themselves like other Python frameworks. Views are what the users will see (or view).
This is important as this is our first introduction to Python's IOC container. We specify in our parameter list that we need a view class and Masonite will inject it for us.
For now on we won't focus on the whole controller but just the sections we are worried about. A ...
means there is stuff in between code that we are not worried about:
Notice here we annotated the View
class. This is what Masonite calls "Auto resolving dependency injection". If this doesn't make sense to you right now don't worry. The more you read on the more you will understand.
You'll notice now that we are returning the blog
view but it does not exist yet.
All views are in the resources/templates
directory. We can create a new file called resources/templates/blog.html
or we can use another craft command:
This will create that template we wanted above for us.
We can put some text in this file like:
and then run the server
and open up http://localhost:8000/blog
. You will see "This is a blog" in your web browser.
Most applications will require some form of authentication. Masonite comes with a craft command to scaffold out an authentication system for you. This should typically be ran on fresh installations of Masonite since it will create controllers routes and views for you.
For our blog, we will need to setup some form of registration so we can get new users to start posting to our blog. We can create an authentication system by running the craft command:
We should get a success message saying that some new assets were created. You can check your controllers folder and you should see a few new controllers there that should handle registrations.
We will check what was created for us in a bit.
In order to register these users, we will need a database. Hopefully you already have some kind of local database setup like MySQL or Postgres but we will assume that you do not. In this case we can just use SQLite.
Now we just need to change a few environment variables so Masonite can create the SQLite database.
These environment variable can be found in the .env
file in the root of the project. Open that file up and you should see a few lines that look like:
Go ahead and change those setting to your connection settings by adding sqlite
to the DB_CONNECTION
variable and whatever you want for your database which will be created for you when you migrate. We will call it blog.db
:
Once you have set the correct credentials, we can go ahead and migrate the database. Out of the box, Masonite has a migration for a users table which will be the foundation of our user. You can edit this user migration before migrating but the default configuration will suit most needs just fine and you can always add or remove columns at a later date.
This will create our users table for us along with a migrations table to keep track of any migrations we add later.
Now that we have the authentication and the migrations all migrated in, let's create our first user. Remember that we ran craft auth
so we have a few new templates and controllers.
Go ahead and run the server:
Now that we have our authentication setup and we are comfortable with migrating our migrations, let's create a new migration where we will store our posts.
Our posts table should have a few obvious columns that we will simplify for this tutorial part. Let's walk through how we create migrations with Masonite.
This command simply creates the start of a migration that will create the posts table. By convention, table names should be plural (and model names should be singular but more on this later).
This will create a migration in the databases/migrations
folder. Let's open that up and starting on line 6 we should see something that looks like:
Lets add a title, an author, and a body to our posts tables.
Now we can migrate this migration to create the posts table
Now that we have our tables and migrations all done and we have a posts table, let's create a model for it.
Models in Masonite are a bit different than other Python frameworks. Masonite uses Orator which is an Active Record implementation of an ORM. This bascially means we will not be building our model and then translating that into a migration. Models and migrations are separate in Masonite. Our models will take shape of our tables regardless of what the table looks like.
Again, we can use a craft command to create our model:
Notice we used the singular form for our model. By default, Orator will check for the plural name of the class in our database (in this case posts) by simply appending an "s" onto the model. We will talk about how to specify the table explicitly in a bit.
The model created now resides inside app/Post.py
and when we open it up it should look like:
Simple enough, right? Like previously stated, we don't have to manipulate the model. The model will take shape of the table as we create or change migrations.
Again, the table name that the model is attached to is the plural version of the model (by appending an "s") but if you called your table something different such as "blog" instead of "blogs" we can specify the table name explicitly:
Orator by default protects against mass assignment as a security measure so we will explicitly need to set what columns we would like to be fillable:
The relationship is pretty straight forward here. Remember that we created a foreign key in our migration. We can create that relationship in our model like so:
Because of how Masonite does models, some models may rely on each other so it is typically better to perform the import inside the relationship like we did above to prevent any possibilities of circular imports.
Let's setup a little HTML so we can learn a bit more about how views work. In this part we will setup a really basic template in order to not clog up this part with too much HTML but we will learn the basics enough that you can move forward and create a really awesome blog template (or collect one from the internet).
Now that we have all the models and migrations setup, we have everything in the backend that we need to create a layout and start creating and updating blog posts.
We will also check if the user is logged in before creating a template.
The URL for creating will be located at /blog/create
and will be a simple form for creating a blog post
Notice here we have this strange {{ csrf_field }}
looking text. Masonite comes with CSRF protection so we need a token to render with the CSRF field.
Now because we have a foreign key in our posts table, we need to make sure the user is logged in before creating this so let's change up our template a bit:
auth()
is a view helper function that either returns the current user or returns None
.
For simplicity sake, we won't be styling our blog with something like Bootstrap but it is important to learn how static files such as CSS files work with Masonite so let's walk through how to add a CSS file and add it to our blog.
Firstly, head to storage/static/
and make a blog.css
file and throw anything you like in it. For this tutorial we will make the html page slightly grey.
Now we can add it to our template like so right at the top:
That's it. Static files are really simple. It's important to know how they work but for this tutorial we will ignore them for now and focus on more of the backend.
Javascript files are the same exact thing:
Notice that our action is going to /blog/create
so we need to direct a route to our controller method. In this case we will direct it to a store
method.
Let's open back up routes/web.py and create a new route. Just add this to the ROUTES
list:
and create a new store method on our controller:
Now notice above in the form we are going to be receiving 2 form inputs: title and body. So let's import the Post
model and create a new post with the input.
Also notice we used an input()
method. Masonite does not discriminate against different request methods so getting input on a GET
or a POST
request doesn't matter. You will always use this input method.
Go ahead and run the server using craft serve and head over to http://localhost:8000/blog
and create a post. This should hit the /blog/create
route with the POST
request method and we should see "post created".
Lets go ahead and show how we can show the posts we just created. In this part we will create 2 new templates to show all posts and a specific post.
Let's create 2 new templates.
Let's start with showing all posts
Let's create a controller for the posts to separate it out from the BlogController
.
Great! So now in our show
method we will show all posts and then we will create a single
method to show a specific post.
Let's get the show
method to return the posts view with all the posts:
We need to add a route for this method:
Our posts view can be very simple:
Go ahead and run the server and head over to http://localhost:8000/posts
route. You should see a basic representation of your posts. If you only see 1, go to http://localhost:8000/blog
to create more so we can show an individual post.
Remember we made our author relationship before. Orator will take that relationship and make an attribute from it so we can display the author's name as well:
Let's repeat the process but change our workflow a bit.
Next we want to just show a single post. We need to add a route for this method:
Notice here we have a @id
string. We can use this to grab that section of the URL in our controller in the next section below.
Let's create a single
method so we show a single post.
We use the param()
method to fetch the id from the URL. Remember this key was set in the route above when we specified the @id
For a real application we might do something like @slug
and then fetch it with request().param('slug')
.
We just need to display 1 post so lets just put together a simple view:
Go ahead and run the server and head over the http://localhost:8000/post/1
route and then http://localhost:8000/post/2
and see how the posts are different.
By now, all of the logic we have gone over so far will take you a long way so let's just finish up quickly with updating and deleting a posts. We'll assume you are comfortable with what we have learned so far so we will run through this faster since this is just more of what were in the previous parts.
Let's just make an update method on the PostController
:
Since we are more comfortable with controllers we can go ahead and make two at once. We made one that shows a view that shows a form to update a post and then one that actually updates the post with the database.
Remember we made 2 controller methods so let's attach them to a route here:
That should be it! We can now update our posts.
Let's expand a bit and made a delete method.
Notice we used a GET
route here, It would be much better to use a POST
method but for simplicity sake will assume you can create one by now. We will just add a link to our update method which will delete the post.
We can throw a delete link right inside our update template:
Great! You now have a blog that you can use to create, view, update and delete posts! Go on to create amazing things!
Please note we have a code of conduct, please follow it in all your interactions with the project. You can find it in the base of the core project directory.
The framework has three main parts.
This MasoniteFramework/masonite
repository is the main repository that will install when creating new projects using the craft new
command. This is actually a full Masonite project. Not much development will be done in this repository and won't be changed unless new releases of Masonite require changes in the default installation project.
The MasoniteFramework/core
repository is where the main masonite
pip package lives. This is where the from masonite ...
module lives.
The MasoniteFramework/craft
repository where the craft
command lives. This is the actual command itself and is installed when you run pip install masonite-cli --user
.
This repo is simple and will be able to be installed following the installation instruction in the README.
Fork the MasoniteFramework/masonite
repo.
Clone that repo into your computer:
git clone http://github.com/your-username/masonite.git
Checkout the current release branch (example: develop
)
git checkout -b develop
You should now be on a develop
local branch.
Run git pull origin develop
to get the current release version.
From there simply create your feature branches (<feature|fix>-<issue-number>
) and make your desired changes.
Push to your origin repository:
git push origin change-default-orm
Open a pull request and follow the PR process below
The trick to this is that we need it to be pip installed and then quickly editable until we like it, and then pushed back to the repo for a PR. Do this only if you want to make changes to the core Masonite package
To do this just:
Fork the MasoniteFramework/core
repo,
Clone that repo into your computer:
git clone http://github.com/your-username/core.git
Activate your masonite virtual environment (optional)
Go to where you installed masonite and activate the environment
While inside the virtual environment, cd into the directory you installed core.
Run pip install .
from inside the masonite-core directory. This will install masonite as a pip package.
Any changes you make to this package just push it to your feature branch on your fork and follow the PR process below.
This repository has a barebones skeleton of a sample project in order to aid in testing all the features of Masonite against a real project. If you install this as editable by passing the --editable
flag then this may break your project because it will override the modules in this package with your application modules.
craft
commands)Craft commands make up a large part of the workflow for Masonite. Follow these instructions to get the masonite-cli package on your computer and editable.
Fork the MasoniteFramework/craft
repo,
Clone that repo into your computer:
git clone http://github.com/your-username/craft.git
Activate your masonite virtual environment (optional)
Go to where you installed masonite and activate the environment
While inside the virtual environment, cd into the directory you installed cli
Run pip install --editable .
from inside the masonite-cli directory. This will install craft (which contains the craft commands) as a pip package but also keep a reference to the folder so you can make changes freely to craft commands while not having to worry about continuously reinstalling it.
Any changes you make to this package just push it to your feature branch on your fork and follow the PR process below.
Comments are a vital part of any repository and should be used where needed. It is important not to overcomment something. If you find you need to constantly add comments, you're code may be too complex. Code should be self documenting (with clearly defined variable and method names)
There are 3 main type of comments you should use when developing for Masonite:
All modules should have a docstring at the top of every module file and should look something like:
Notice there are no spaces before and after the sentence.
All methods and functions should also contain a docstring with a brief description of what the module does
For example:
Most methods will require some dependency or parameters. You must specify them like this:
And if your dependency are object it should give the path to the module:
If you're code MUST be complex enough that future developers will not understand it, add a #
comment above it
For normal code this will look something like:
You should open an issue before making any pull requests. Not all features will be added to the framework and some may be better off as a third party package or not be done at all. It wouldn't be good if you worked on a feature for several days and the pull request gets rejected for reasons that could have been discussed in an issue for several minutes.
Ensure any changes are well commented and any configuration files that are added have a docstring comments on the variables it's setting.
Update the README.md and MasoniteFramework/docs
repo with details of changes to the interface, this includes new environment variables, new file locations, container parameters etc.
Name your branches in the form of feature|fix-<issue-number>
. For example if you are doing a bug fix and the issue number is 576
then name your branch fix-576
. This will help us locate the branches on our systems at later dates. If it is a new feature name it feature-576
.
You must add unit testing for any changes made. Of the three repositories listed above, only the craft
and core
repos require unit testing.
The PR must pass the Travis CI build. The Pull Request can be merged in once you have a successful review from two other collaborators, or one review from a maintainer or Masonite creator.
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment include:
Using welcoming and inclusive language
Being respectful of differing viewpoints and experiences
Gracefully accepting constructive criticism
Focusing on what is best for the community
Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
The use of sexualized language or imagery and unwelcome sexual attention or advances
Trolling, insulting/derogatory comments, and personal or political attacks
Public or private harassment
Publishing others' private information, such as a physical or electronic
address, without explicit permission
Other conduct which could reasonably be considered inappropriate in a
professional setting
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at idmann509@gmail.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
Masonite 1.4 brings several new features to Masonite. These features include caching, template caching, websocket support with Masonite calls Broadcasting and much more testing to make Masonite as stable as possible. If you would like to contribute to Masonite, please read the and the documentation.
If you are upgrading from Masonite 1.3 then please read the documentation.
We recognize that in order for frameworks to keep up with modern web application, they require real time broadcasting. Masonite 1.4 brings basic broadcasting of events to masonite and comes with two drivers out of the box: pusher
and ably
. If you'd like to create more drivers then you can do so easily by reading the documentation. If you do create a driver, please consider making it available on PyPi so others can install it into their projects or open an issue on GitHub and make to add it to the built in drivers.
This tutorial will assume you have already installed Masonite. If you haven't, be sure to read the guide to get a fresh install of Masonite up and running. Once you have one up and running or if you already have it running, go ahead and continue on.
You can read more about routes in the documentation
Let's create the BlogController
in the next step:
Be sure to learn more about the .
and head over to and fill out the form. You can use whatever name and email you like but for this purpose we will use:
Not surprisingly, we have a craft command to create migrations. You can read more about but we'll simplify it down to the command and explain a little bit of what's going on:
This should be fairly straight forward but if you want to learn more, be sure to read the documentation.
We won't go into much more detail here about different types of relationships but to learn more, read the documentation.
Masonite uses Jinja2 templating so if you don't understand this templating, be sure to .
For more information on static files, checkout the documentaton.
Notice that we now used request: Request
here. This is the Request
object. Where did this come from? This is the power and beauty of Masonite and your first introduction to the . The is an extremely powerful implementation as allows you to ask Masonite for an object (in this case Request
) and get that object. This is an important concept to grasp so be sure to read the documentation further.
Read more about the here.
When contributing to this repository, please first discuss the change you wish to make via an issue or in the channel.
Increase the version numbers in any example files and the README.md to the new version that this Pull Request would represent. The versioning scheme we use is .
This Code of Conduct is adapted from the , version 1.4, available at
Masonite 1.3 comes with a plethora of improvements over previous versioning. This version brings new features such as Queue and Mail drivers as well as various bug fixes.
Previously when a you tried to redirect using the Request.redirect()
method, Masonite would sometimes send the browser to an infinite redirection. This was because masonite was not resetting the redirection attributes of the Request
class.
Previously the content length in the request header was not being set correctly which led to the gunicorn server showing a warning that the content length did not match the content of the output.
Previously the Request class simply got the input data on both POST
and GET
requests by converting the wsgi.input
WSGI parameter into a string and parsing. All POST input data is now retrieved using FieldStorage
which adds support for also getting files from multipart/formdata
requests.
You may now simply upload images to both disk and Amazon S3 storage right out of the box. With the new UploadProvider
service provider you can simply do something like:
As well as support for Amazon S3 by setting the DRIVER
to s3
.
These helper functions are added functions to the builtin Python functions which can be used by simply calling them as usual:
Notice how we never imported anything from the module or Service Container. See the Helper Functions documentation for a more exhaustive list
Very often you will want to have a single variable accessible in all of your views, such as the Request
object or other class. We can use the new View
class for this and put it in it's own service provider:
You can now specify anything that is in the container in your middleware constructor and it will be resolved automatically from the container
Specify the subdomain you want to target with your route. It's common to want to have separate routes for your public site and multi-tenant sites. This will now look something like:
Which will target test.example.com/dashboard
and not example.com/dashboard
. Read more about subdomains in the Routing documentation.
By default, masonite will look for routes in the app/http/controllers
namespace but you can change this for individual routes:
This will look for the controller in the thirdparty.routes
module.
Masonite now ships with a QueueManager
class which can be used to build queue drivers. Masonite ships with an async
driver which sends jobs to a background thread. These queues can process Jobs which ca be created with the new craft job
command. See the Queues and Jobs documentation for more information.
Masonite 1.6 brings mostly minor changes to the surface layer of Masonite. This release brings a lot of improvements to the engine of Masonite and sets up the framework for the release of 2.0.
Previously, all cookies were set with an HttpOnly flag when setting cookies. This change came after reading several articles about how cookies can be read from Javascript libraries, which is fine, unless those Javascript libraries have been compromised which could lead to a malicious hacker sending your domain name and session cookies to a third party. There is no the ability to turn the HttpOnly flag off when setting cookies by creating cookies like:
Because craft is it's own tool essentially and it needs to work across Masonite versions, all commands have been moved into the Masonite repository itself. Now each version of Masonite maintains it's own commands. The new craft version is 2.0
Before, you had to use the Manager class associated with a driver to switch a driver. For example:
Now you can switch drivers from the driver itself:
This version has been fine tuned for adding packages to Masonite. This version will come along with a new Masonite Billing package. The development of Masonite Billing has discovered some rough spots in package integrations. One of these rough spots were adding controllers that were not in the project. For example, Masonite Billing allows adding a controller that handles incoming Stripe webhooks. Although this was possible before this release, Masonite 1.6 has added a new syntax:
Notice the new forward slash in the beginning where the string controller goes.
Previously, controllers were created as they were specified. For example:
created a DashboardController. Now the "Controller" part of the controller is appended by default for you. Now we can just specify:
to create our DashboardController. You may was to actually just create a controller called Dashboard. We can do this by specifying a flag:
short for "exact"
It's also really good practice to create 1 controller per "action type." For example we might have a BlogController
and a PostController
. It's easy to not be sure what action should be in what controllers or what to name your actions. Now you can create a "Resource Controller" which will give you a list of actions such as show, store
, create
, update
etc etc. If what you want to do does not fit with an action you have then you may want to consider making another controller (such as an AuthorController
)
You can now create these Resource Controllers like:
Just like the global controllers, some packages may require you to add a view that is located in their package (like the new exception debug view in 1.6) so you may now add views in different namespaces:
This will get a template that is located in the masonite package itself.
You can now group routes based on a specific string prefix. This will now look like:
which will compile down into /dashboard/user
and /dashboard/user/1
The container was one of the first features coded in the 1.x release line. For Masonite 1.6 we have revisited how the container resolves objects. Before this release you had to put all annotation classes in the back of the parameter list:
If we put the annotation in the beginning it would have thrown an error because of how the container resolved.
Now we can put them in any order and the container will grab each one and resolve it.
This will now work when previously it did not.
The container will now resolve instances of classes as well. It's a common paradigm to "code to an interface and not an implementation." Because of this paradigm, Masonite comes with contracts that act as interfaces but in addition to this, we can also resolve instances of classes.
For example, all Upload drivers inherit the UploadContract contract so we can simply resolve the UploadContract which will return an Upload Driver:
Notice here that we annotated an UploadContract but got back the actual upload driver.
You can now search the container and "collect" objects from it by key using the new collect method:
which will find all keys in the container such as SentryExceptionHook and SentryWebHook and make a new dictionary out of them.
A complaint a few developers pointed out was that Masonite has too many dependencies. Masonite added Pusher, Ably and Boto3 packages by default which added a bit of overhead, especially if developers have no intentions on real time event broadcasting (which most applications probably won't). These dependencies have now been removed and will throw an exception if they are used without the required dependencies.
Masonite 1.6 + will slowly be rolling out various framework hooks. These hooks will allow developers and third party packages to integrate into various events that are fired throughout the framework. Currently there is the abilitity to tie into the exception hook which will call any objects loaded into the container whenever an exception is hit. This is great if you want to add things like Sentry into your project. Other hooks will be implemented such as View, Mail and Upload Hooks.
Masonite 1.4 brings several new features and a few new files. This is a very simple upgrade and most of the changes were done in the pip package of Masonite. The upgrade from 1.3 to 1.4 should take less than 10 minutes
This requirement file has the masonite>=1.3,<=1.3.99
requirement. This should be changed to masonite>=1.4,<=1.4.99
. You should also run pip install --upgrade -r requirements.txt
to upgrade the Masonite pip package.
There is now a new cache folder under bootstrap/cache
which will be used to store any cached files you use with the caching feature. Simply create a new bootstrap/cache
folder and optionally put a .gitignore
file in it so your source control will pick it up.
Masonite 1.4 brings a new config/cache.py
and config/broadcast.py
files. These files can be found on the GitHub page and can be copied and pasted into your project. Take a look at the new config/cache.py file and the config/broadcast.py file. Just copy and paste those configuration files into your project.
Masonite comes with a lot of out of the box functionality and nearly all of it is optional but Masonite 1.4 ships with three new providers. Most Service Providers are not ran on every request and therefore does not add significant overhead to each request. To add these 3 new Service Providers simple add these to the bottom of the list of framework providers:
Note however that if you add the CsrfProvider
then you will also need the CSRF middleware which is new in Masonite 1.4. Read the section below to add the middleware
Masonite 1.4 adds CSRF protection. So anywhere there is any POST form request, you will need to add the {{ csrf_field }}
to it. For example:
This type of protection prevents cross site forgery. In order to activate this feature, we also need to add the CSRF middleware. Copy and paste the middleware into your project under the app/http/middleware/CsrfMiddleware.py
file.
Lastly, put that middleware into the HTTP_MIDDLEWARE
list inside config/middleware.py
like so:
There has been a slight change in the constants used in the config/database.py file. Mainly just for consistency and coding standards. Your file may have some slight changes but this change is optional. If you do make this change, be sure to change any places in your code where you have used the Orator Query Builder. For example any place you may have:
should now be:
with this change
Masonite 2.1 introduces a few new changes that are designed to correct course for the 2.x family and ensure we can go far into the 2.x family without having to make huge breaking changes. It was questionable whether we should break from the 2.x family and start a new 3.x line. The biggest question was removing (actually disabling) the ability to resolve parameters and go with the more favorable annotation resolving. That could have made Masonite a 3.x line but we have ultimately decided to go with the 2.1 as a course correction. Below you will find all changes that went into making 2.1 awesome. Nearly all of these changes are breaking changes.
It is much easier to contribute to Masonite now since nearly classes have awesome docstrings explaining what they do, their dependencies and what they return.
We have completely removed parameter resolving. We can no longer resolve like this:
in favor of the more explicit:
This is a bit of a big change and will be most of the time spent on refactoring your application to upgrade to Masonite 2.1. If you already used the more explicit version then you won't have to worry about this change. It is still possible to resolve parameters by passing that keyword argument to your container to activate that feature:
This should help with upgrading from 2.0 to 2.1 until you have refactored your application. Then you should deactivate this keyword argument so you can be in line with future 2.x releases.
You can choose to keep it activated if that is how you want to create applications but it won't be officially supported by packages, future releases or in the documentation.
All middleware are now classes:
this is different from the previous string based middleware
Previously when getting an incoming JSON response, we had to get the values via the payload input like so:
which was kind of strange in hindsight. Now we can just straight up use the input:
Again this is only a change for incoming JSON responses. Normal form inputs remain the same.
Previously we had a facades module but it was being unused and we didn't see a future for this module so we moved the only class in this module to it's own class. All instances of:
now become:
We also noticed that for some reason we were parsing parameters before we found routes but we only ever needed those parameters inside our routes so we were parsing them whether we found a route or not. We moved the parsing of parameters into the if statement that executes when a route is found.
When we say "parsing route parameters" we mean the logic required to parse this:
into a usable form to use on the request class this:
This provider has been completely removed for the more recommended ResponseMiddleware which will need to be added to your HTTP middleware list:
We also noticed that for some reason we were parsing parameters before we found routes but we only ever needed those parameters inside our routes so we were parsing them whether we found a route or not. We moved the parsing of parameters into the if statement that executes when a route is found.
When we say "parsing route parameters" we mean the logic required to parse this:
into a usable form to use on the request class this:
This provider has been completely removed for the more recommended ResponseMiddleware which will need to be added to your HTTP middleware list:
We also noticed that for some reason we were parsing parameters before we found routes but we only ever needed those parameters inside our routes so we were parsing them whether we found a route or not. We moved the parsing of parameters into the if statement that executes when a route is found.
When we say "parsing route parameters" we mean the logic required to parse this:
into a usable form to use on the request class this:
You can now optionally use .
instead of /
in your views:
We moved the CSRF middleware completely into the core framework and allow developers to extend from it now. This will allow us to fix any security bugs that are apart of the CSRF feature.
You may see this pattern a lot in the future which is only extending classes from the core framework so we can hot fix things much better.
Masonite now has a plethora of docstrings on each and every class by default to really give the developer an understanding about what each default class is actually doing and what it is dependent on.
Masonite is also much more PEP 8 compliant. We removed all instances of triple single quotes: '''
for the more preferred and PEP 8 compliant double quotes """
for docstrings.
We also cleaned a lot of the classes generated by the auth command since those were pretty ugly.
We also removed all instances of helper functions by default since it was confusing developers and was throwing red squiggly marks for text editors. They are still available to be used but they will not be known to developers unless they discover them in the documentation. Now all default code explicitly resolves via the container and helper functions can be used on the developers own terms.
Helper functions are still available but you will need to use them on your own terms.
Now every application has a basic seeding structure setup which is the same as if running the craft seed
command. This is to promote more use of this awesome feature which can be used in migration files for quick seeding of databases for development.
We were previously not able to import code into our migration files or database seeders because the command line tool would not pick up our current working directory to import classes into. Now the migrations module and seeds module have 3 lines of code:
this helpers when running the command line to import code into these modules.
In development you would see a message like:
When you hit a route in development mode. Well you would also hit it in production mode too since that was never turned off. Although this is likely fine, it would slow down the framework significantly under load since it takes a bit of resources to print something that didn't need to be printed. This enables a bit of a performance boost.
This command gets the statuses of all migrations in all directories. To include third party migration directories that are added to your project.
simple
container bindingsSometimes you do not need to bind an object to any key, you just want the object in the container. For this you can now do simple
bindings like this:
This new mail helper can be used globally which points to the default mail driver:
|safe
filters on built in template helpers.We no longer need to do:
We can now simply do:
Previously we had to specify the status code as a string:
in order for these to be used properly. Now we can just specify the status code:
There is quite a bit of things to remember when binding various things into the container. For example when binding commands, the key needs to be postfixed with Command
like ModelCommand
. Now we can do things like:
Along with this there are several other methods to help you bind things into the container without having to remember all the special rules involved, if any.
We now have View Routes on all instances of the normal HTTP classes:
We previously used this method on the Cache class like so:
Now we removed the cache_
prefix and it is just:
We can now use the .without()
method on the request class which returns all inputs except the ones specified:
Previously the port was missing from the database configuration settings. This was fine when using the default connection but did not work unless added to the config.
Instead of doing something like:
We can now use a dictionary:
We can now specify a route with multiple HTTP methods. This can be done like so:
Core can now emit events that can be listened to through the container.
Now you can setup a way to send email verifications into your user signup workflow simply but inherting a class to your User model.
Now all redirections set the status code implicitly instead of explicitly needing to set them.
Now you can use craft middleware MiddlewareName
in order to scaffold middleware like other classes.
All views can optionally use dot notation instead of foward slashes:
is the same as:
We can now do container swapping which is swapping out a class when it is resolved. In other words we may want to change what objects are returned when certain objects are resolved. These objects do not have to be in the container in the first place.
You can now use a env
function to automatically type cast your environment variables turning a numeric into an int:
You can now resolve from a container with a parameter list in addition to custom parameters.
In addition to all the awesome things that craft auth
generates, we now generate password reset views and controllers as well for you
Fixed an issue where custom route compilers was not working well with request parameters
All new 2.1 projects have a seeder setup so you can quickly make some mock users to start off your application. All users have a randomly generated email and the password of "secret".
You can run seeders by running:
When setting headers we had to set the http_prefix to None more times then not. So it is set by default.
This:
can change to:
Originally the code:
would return None
if there was no header. Now this returns a blank string.
There is now an up and down command so you can put that in your application in a maintenance state via craft commands:
There is also a new MaintenanceModeMiddleware
:
We removed the store_prepend()
method on the upload drivers for the filename
keyword arg on the store method.
So this:
now becomes:
Previously you had to append all routes with a /
character. This would look something like:
You can now optionally prefix this without a /
character:
Previously we had to do something like:
Now we can optionally get the parameter from the method definition:
Learn more in the Controllers documentation here.
This is used as a wrapper around I/O operations. It will also be a wrapper around the upload drivers and moving files around and other file management type operations
We can now specify directly in the configuration file whether or not the threading or multiprocessing for the async type operations.
Learn more in the Queues documentation here.
We added 4 new HTTP verbs: HEAD
, CONNECT
, OPTIONS
, TRACE
. You import these and use them like normal:
Learn more in the Routes documentation here.
If the incoming request is a JSON request, Masonite will now return all errors as JSON
This is more of an internal change for Core itself.
Before we had to specify that we wanted the server to auto-reload by specifying a -r flag:
Now we can just specify the serve command it will default to auto-reloading:
You can now specify it to NOT auto-reload by passing in 1 of these 2 commands:
Learn more in the Craft commands documentation here.
By default you can only upload image files because of security reasons but now you can disable that by doing an accept('*') option:
Learn more in the Uploading documentation here.
Learn more in the Views documentation here.
We moved from pytest to unittests for test structures.
Learn more in the Testing documentation here.
Added a new DatabaseTestcase
so we can properly setup and teardown our database. This works for sqlite databases by default to prevent your actual database from being destroyed.
Before in templates we had to specify a path to go back to but most of the time we wanted to go back to the current path.
Instead of:
We can now do:
In order to learn how to use this you can visit the documentation here.
Learn more in the Requests documentation here.
We built a new validation library from scratch and completely ripped out the old validation code. Any current validation code will need to be updated to the new way.
The new way is MUCH better. You can read about it in the new validation section here.
Learn more in the Validation documentation here.
Previously we needed to pass in the request object to the Auth class like this:
Now we have it a bit cleaner and you can just resolve it and the request class will be injected for you
You may not notice anything but now if you bind a class into the container like this:
It will be resolved when you resolve it:
This is why the Auth class no longer needs to accept the request class. Masonite will inject the request class for you when you resolve the class.
This works with all classes and even your custom classes to help manage your application dependencies
Auth
class.You can now do something like:
Learn more in the Authentication documentation here.
Previously, each route's regex was being compiled when Masonite checked for it but we realized this was redundant. So now all route compiling is done before the server starts.
This has given Masonite a bit of a speed boost.
Masonite now has the ability to remember the previous container bindings for each object. This can speed of resolving your code by 10-15x. This is disabled by default as it is still not clear what kind of issues this can cause.
This is scheduled to be set by default in the next major version of Masonite
Learn more in the Service Container documentation here.
with_errors()
method in order to cut down on setting an errors session.Now instead of doing this:
we can now shorten down the flashing of errors and do:
Learn more in the Requests documentation here.
Masonite 2 brings an incredible new release to the Masonite family. This release brings a lot of new features to Masonite to include new status codes, database seeding, built in cron scheduling, controller constructor resolving, auto-reloading server, a few new internal ways that Masonite handles things, speed improvements to some code elements and so much more. We think developers will be extremely happy with this release.
Upgrading from Masonite 1.6 to Masonite 2.0 shouldn't take very long although it does have the largest amount of changes in a single release. On an average sized project, this upgrade should take around 30 minutes. We'll walk you through the changes you have to make to your current project and explain the reasoning behind it
Masonite 2 adds some improvements with imports. Previously we had to import providers and drivers like:
Masonite 2 brings a more explicit way of declaring Service Providers in your application. You'll need to take your current PROVIDERS
list inside the config/application.py
file and move it into a new config/providers.py
file.
Now all Service Providers should be imported at top of the file and added to the list:
String providers will still work but it is not recommended and will not be supported in current and future releases of Masonite.
There are a few changes in the wsgi.py
file and the bootstrap/start.py
file.
In the wsgi.py
file we should add a new import at the top:
Then change the code logic of bootstrapping service providers from:
to:
and change the logic in bootstrap/start.py
to:
Notice here we split the providers list when the server first boots up into two lists which significantly lowers the overhead of each request.
This change should significantly boost speed performances as providers no longer have to be located via pydoc. You should see an immediate decrease in the time it takes for the application to serve a request. Rough time estimates say that this change should increase the request times by about 5x as fast.
Again, with the addition of the above change, any place you have a duplicated class name like:
You can change it to:
Renamed Request.redirectTo to Request.redirect_to. Be sure to change any of these instances accordingly.
All instances of:
should be changed to:
Also removed the .send()
method completely on the Request
class so all instances of:
Need to be changed to:
Some variable internals have changed to prepend a double underscore to them to better symbolize they are being handled internally. Because of this we need to change any instances of csrf_token to __token in the CSRF Middleware file.
Simply add a new AUTOLOAD
constant in your config/application.py
file. This is the entire section of the autoload configuration.
By default this points to the app directory where models are stored by default but if you moved your models to other directories like app/models or app/admin/models then add those directories to your list:
Because of a minor rewrite of the Request class, we now do not need the RedirectionProvider. You can remove the RedirectionProvider completely in your PROVIDERS
list.
There is a new status code provider which adds support for adding custom status codes and rendering better default status code pages such as 400 and 500 error pages. This should be added right above the StartResponseProvider:
The .env got a small upgrade and in order to make the APP_DEBUG
variable consistent, it should be set to either True
or False
. Previously this was set to something like true
or false
.
Masonite 2 also removed the APP_LOG_LEVEL
environment variable completely.
That's it! You're all done upgrading Masonite 1.6 to Masonite 2.0. Build something awesome!
Welcome to the upgrade guide to get your Masonite 2.1 application working with Masonite 2.2. We'll be focusing on all the breaking changes so we can get all your code working on a Masonite 2.2 release cycle.
Masonite 2.2 is jam packed with amazing new features and most of which are backwards compatible so upgrading from Masonite 2.1 to 2.2 is really simple.
We'll go through each section that your application will need to be upgraded and how it can be done.
Each upgrade will have an impact rating from LOW to HIGH. The lower the rating, the less likely it will be that your specific application needs the upgrade.
First let's upgrade Masonite to 2.2 first so we can see any exceptions that will be raised.
Let's upgrade by doing:
You can also add it to your requirements.txt or Pipfile.
In Masonite 2.1, route helpers were deprecated and you likely started receiving deprecation warnings. In Masonite 2.2, these were removed. You may have had routes that looks like this:
You will now need to remove all these and use the class based ones. To make this easier we can just import the get and post helpers and alias them like this:
Impact: MEDIUM
Masonite 2.2 completely removes the validation library that shipped with Masonite in favor of a brand new one that was built specifically for Masonite.
You'll need to add a new validation provider if you want your application to have the new validation features.
Add it by importing it into config/providers.py
and add it to your PROVIDERS
list:
Masonite 2.2 completely removed the validation package from 2.1 and created an even better all new validation package. You'll have to remove all your validation classes and use the new validation package.
For example you may have had a validation class that looked like this:
and used it inside your views like this:
This is now completely changed to use a better and more sleeker validation. The above validation can now be written like this:
Masonite 2.2 changes a bit how the masonite.auth.Auth
class resolves out of the container and how it resolves its own dependencies.
Now instead of doing something like:
You'll need to move this into the parameter list so it can be resolved:
There should be quite a bit of these in your application if you have used this class or you have used the built in craft auth
scaffold command.
Impact: MEDIUM
The behavior for resolving classes has now been changed. If you bind a class into the container like this:
It previously would have resolved and gave back the class:
This will now resolve from the container when you resolve it as a parameter list. This means that you will never get back a class inside places like controllers.
Now the above code would look something like this:
notice it now returns an object. This is because Masonite will check before it resolves the class if the class itself needs to be resolved (if it is a class). If SomeClass
requires the request object, it will be passed automatically when you resolve it.
Masonite 2.2 focused a lot on new testing aspects of Masonite and has some big rewrites of the package internally.
The UnitTest class has been completely removed in favor of the new masonite.testing.TestCase
method.
An import that looked like this:
Should now look like this:
All classes have now been changed to unittest classes. This will still work with pytest and you can still run python -m pytest
. The only thing that changes is the structure of the setup_method()
. This has been renamed to setUp()
.
A class like this:
Should now look like this:
Previously all methods were snake_case
but to continue with the unittest convention, all testing methods are camelCase
.
A method like:
Now becomes:
Again this is to prevent developers from needing to switch between snake_case
and camelCase
when using Masonite methods and unittest methods.
The route method that looked something like this:
Has now been replaced with the method name of the route. So to get a GET route you would do:
or a POST route:
So be sure to update all methods of self.route()
with the correct request methods.
In 2.1 you had to manually load your routes in like this:
this is no longer required and routes will be found automatically. There is no longer a self.routes()
method.
The JSON method signature has changed and you now should specify the request method as the first parameter.
A previous call that looked like this:
should become:
Previously you logged a user in by using the user
method but now you can using the actingAs
method before you call the route:
A method like this:
Should now be:
Any developers that are using or have used Masonite
If you can take 5 minutes to complete this survey it would be very much appreciated. Just very simple questions that we can use to make Masonite an even better framework then it already is!
The modern and developer centric Python web framework that strives for an actual batteries included developer tool with a lot of out of the box functionality with an extremely extendable architecture. Masonite is perfect for beginner developers getting into their first web applications as well as experienced devs that need to utilize the full potential of Masonite to get their applications done.
Masonite works hard to be fast and easy from install to deployment so developers can go from concept to creation in as quick and efficiently as possible. Use it for your next SaaS! Try it once and you’ll fall in love.
Easily send emails with the Mail Provider and the SMTP and Mailgun drivers.
Send websocket requests from your server with the Broadcast Provider and Pusher and Ably drivers.
IOC container and auto resolving dependency injection.
Service Providers to easily add functionality to the framework.
Extremely simple static files configured and ready to go.
Active Record style ORM called Orator.
An extremely useful command line tool called craft commands.
Extremely extendable.
These, among many other features, are all shipped out of the box and ready to go. Use what you need when you need it.
In order to use Masonite, you’ll need:
Python 3.4+
Latest version of OpenSSL
Pip3
All commands of python and pip in this documentation is assuming they are pointing to the corresponding Python 3 versions. If you are having issues with any installation steps just be sure the commands are for Python 3.4+ and not 2.7 or below.
If you are running on a Linux flavor, you’ll need the Python dev package and the libssl package. You can download these packages by running:
Or you may need to specify your python3.x-dev
version:
Masonite excels at being simple to install and get going. We use a simple command line tool that will become your best friend. You’ll never want to develop again without it. We call them craft
commands.
We can download our craft
command line tool by just running:
If you already have craft installed, Masonite 2.2 requires masonite-cli>=2.2.0
so you may have to run with the upgrade flag too.
Great! We are now ready to create our first project. We should have the new craft
command. We can check this by running:
This should show a list of command options. If it doesn't then you may have installed the masonite cli incorrectly. Try uninstalling it and be sure when you install it you install it with a
--user
flag likepip install masonite-cli --user
.
We are currently only interested in the craft new
command. To create a new project just run:
This will get the latest Masonite project template and unzip it for you. We just need to go into our new project directory and install the dependencies in our requirements.txt
file.
You can optionally create a virtual environment if you don't want to install all of masonite's dependencies on your systems Python. If you use virtual environments then create your virtual environment by running:
or if you are on Windows:
The python
command here is utilizing Python 3. Your machine may run Python 2 (typically 2.7) by default for UNIX machines. You may set an alias on your machine for Python 3 or simply run python3
anytime you see the python
command.
For example, you would run python3 -m venv venv
instead of python -m venv venv
Now lets install our dependencies. We can do this simply by using a craft
command:
This command is just a wrapper around the pip
command. This installs all the required dependencies of Masonite, creates a .env
file for us, generates a new secret key, and puts that secret key in our .env
file. After it’s done we can just run the server by using another craft
command:
After it’s done we can just run the server by using another craft
command:
Congratulations! You’ve setup your first Masonite project! Keep going to learn more about how to use Masonite to build your applications.
The Masonite CLI (also known as craft) will try to find all the commands in your project but may not be able to. In this case you will need to call craft directly using something like:
Masonite has romantic versioning instead of semantic versioning. Because of this, all minor releases (2.0.x) will contain bug fixes and fully backwards compatible feature releases. Be sure to always keep your application up to date with the latest minor release to get the full benefit of Masonite's romantic versioning.
Not much has changed in the actual project structure of Masonite 1.6 so we just need to make some minor changes to our existing 1.5 project
We just have to change our Masonite dependency version in this file:
Masonite 1.6 now wraps the majority of the application in a try and catch block so we can add exception handling such as the new debug view and other exception features down the road such as Sentry and other error logging.
In the middle of the file (line 45 if you have not made changes to this file) we can simply wrap the application:
This will also display an exception view whenever an exception is it.
That's all the changes we have to make for our project.
Masonite 1.5 doesn't bring many file changes to Masonite so this upgrade is fairly straight forward and should take less than 10 minutes.
All requirements are now gone with the exception of the WSGI server (waitress
) and the Masonite dependency. You should remove all dependencies and only put:
If you have added your site packages directory to our packages configuration file, you can now remove this because Craft commands can now detect your site packages directory in your virtual environment.
Remove the masonite.providers.ApiProvider.ApiProvider
from the PROVIDERS
list as this has been removed completely in 1.5
You'll also have to add a new RESOURCES = []
line to your routes/api.py
file for the new Masonite Entry package if you choose to use it.
This release works with the new craft command release. Upgrade to version masonite-cli / 1.1+
. <1.1
will only work with Masonite 1.4 and below.
Simply run:
You may have to run sudo if you are using a UNIX machine.
Masonite 1.5 now has sessions that can be used to hold temporary data. It comes with the cookie and memory drivers. Memory stores all data in a class which is lost when the server restarts and the cookie driver sets cookies in the browser.
There is a new config/session.py
file you can copy and paste:
As well as add the SessionProvider
inside your PROVIDERS
list just below the AppProvider
:
That's it! You have officially upgrades to Masonite 1.5
There are no known Masonite specific issues known and if there are then there should be an issue open for them on GitHub. With that being said, some users may experience some difficulties with installing Masonite simply because their computer environment is not the norm, they have never setup Python and may have configured it incorrectly or they have not used Python in a while and have an old version.
Before you get started reading through this FAQ make sure you have:
Python 3.4+
Pip3
Ensure you are installing masonite-cli with pip3
and not pip
.
You are likely running this command on a UNIX based machine like Mac or Linux. In that case you should either run it again with a sudo command or a user command flag:
or
If you ran:
and then run:
and get something like:
then try closing your terminal and reopening it. If that doesn't work then you may be running a pip version connecting to Python 2.7. Try uninstalling it and reinstalling it using pip3:
If that does not work then you may have to run sudo:
You may get a strange error like:
The simple fix may just be to run:
If that doesn't work we can just go back to the lower idna version:
If that does not fix the issue then continue reading.
If the above fix did not work then this likely means you installed masonite-cli using the Python 2.7 pip command. Out of the box, all Mac and Linux based machines have Python 2.7. If you run:
you should get a return value of:
But if you run:
you should get a return value of:
Now pip commands are similar:
Notice here we are using 2 different Python installations.
So if you are getting this error you should uninstall masonite-cli from pip and reinstall it using pip3:
You may have to run sudo to remove and install it and you may need to close your terminal to get it work if you are using a UNIX machine.
If you installed everything successfully and running:
Shows an error that it can't be found then try closing your terminal and opening it again. This should refresh any commands that were recently installed
If you still have errors and on a UNIX based machine try running:
You likely ran:
and hit this weird snag that throws this ambiguous error. You might think this is because of a Python version issue but craft is designed to work on Python 2.7 and 3.4+ (although 2.7 and not thoroughly tested) and you're years of Python experience would make you right but this is special. If you are getting this error then that means you are likely on a UNIX machine, Mac right?
The problem is that your machine does not have sufficient permissions to access these external calls from the command line because your machine does not have permission to do so. You will have to give you machine the command to do so by running:
or whatever your Python 3 version is in the middle. Now try running:
and it should work great!
Because of this, all framework will need to cut out the redundant last part. The above code should be changed to:
You can check for what the class should look like from the repository
Masonite 2 comes with a new autoloader. This can load all classes in any directory you specify right into the when the server first starts. This is incredibly useful for loading your models, commands or tasks right into the container.
Be caution that this will autoload all models into the with the class name as the key and the class as the binding.
Be sure to read about all the to ensure that your application is completely up to date with many of the latest decisions and be sure to thoroughly test your application. Feel free to open an issue if any problems arise during upgrading.
We will not go into all the better ways to use some of the features. For those changes be sure to read the "" documentation to the left to see what fits into your application and what doesn't. We will only focus on the breaking changes here.
You can do a lot of other awesome things like rule enclosures. Read more under the
Here is an example application that is being upgraded from 2.1 to 2.2
If you are more of a visual learner you can watch Masonite related tutorial videos at
Be sure to join the for help or guidance.
If you are having installation issues, be sure to read the documentation.
You can learn more about craft by reading documentation or continue on to learning about how to create web application by first reading the documentation
Read for any futher changes you may want or have to make to your code base.
If you are using the Api()
route inside routes/api.py
for API endpoints then remove this as well. You will need to implement API endpoints using the new Official package instead.