├── .circleci
└── config.yml
├── .gitignore
├── LICENSE
├── api.db
├── app
├── User.py
├── http
│ ├── controllers
│ │ ├── HomeController.py
│ │ ├── LoginController.py
│ │ ├── RegisterController.py
│ │ └── WelcomeController.py
│ └── middleware
│ │ ├── AuthenticationMiddleware.py
│ │ ├── CsrfMiddleware.py
│ │ └── LoadUserMiddleware.py
└── resources
│ └── UserResource.py
├── config
├── __init__.py
├── application.py
├── auth.py
├── database.py
├── middleware.py
├── packages.py
├── providers.py
├── session.py
└── storage.py
├── databases
└── migrations
│ ├── 2018_01_09_043202_create_users_table.py
│ └── __init__.py
├── readme.md
├── requirements.txt
├── routes
└── web.py
├── setup.py
├── src
└── api
│ ├── __init__.py
│ ├── authentication
│ ├── BaseAuthentication.py
│ ├── JWTAuthentication.py
│ ├── PermissionScopes.py
│ ├── TokenAuthentication.py
│ └── __init__.py
│ ├── controllers
│ ├── TokenController.py
│ └── __init__.py
│ ├── exceptions.py
│ ├── filters
│ ├── FilterScopes.py
│ └── __init__.py
│ ├── resources
│ ├── Resource.py
│ └── __init__.py
│ ├── routes
│ ├── TokenRoutes.py
│ └── __init__.py
│ ├── serializers
│ ├── JSONSerializer.py
│ ├── XMLSerializer.py
│ └── __init__.py
│ └── templates
│ └── __init__.py
├── tests
├── models
│ └── User.py
├── test_filter_scopes.py
└── test_resource.py
└── wsgi.py
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: circleci/python:3.6
6 | steps:
7 | - checkout
8 | - run: pip install https://github.com/$BUILD_REPO/archive/$BUILD_BRANCH.zip --user
9 | - run: pip install -e . --user
10 | - run: pip install -r requirements.txt --user
11 | - run: python -m pytest
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .pytest_cache
2 | .vscode
3 | *.egg-info
4 | .DS_STORE
5 | .env
6 | .env.*
7 | venv
8 | __pycache__
9 | dist
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Joseph Mancuso
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/api.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MasoniteFramework/api/6e4ec0a991fb2df1a9e23e8676a93bebfd0b53d5/api.db
--------------------------------------------------------------------------------
/app/User.py:
--------------------------------------------------------------------------------
1 | """ User Model """
2 |
3 | from config.database import Model
4 |
5 |
6 | class User(Model):
7 | """User Model
8 | """
9 |
10 | __fillable__ = ['name', 'email', 'password']
11 |
12 | __auth__ = 'email'
13 |
--------------------------------------------------------------------------------
/app/http/controllers/HomeController.py:
--------------------------------------------------------------------------------
1 | """ The HomeController Module """
2 |
3 | from masonite.auth import Auth
4 | from masonite.request import Request
5 | from masonite.view import View
6 |
7 |
8 | class HomeController:
9 | """Home Dashboard Controller
10 | """
11 |
12 | def __init__(self):
13 | pass
14 |
15 | def show(self, request: Request, view: View):
16 | if not Auth(request).user():
17 | request.redirect('/login')
18 | return view.render('auth/home', {'app': request.app().make('Application'), 'Auth': Auth(request)})
19 |
--------------------------------------------------------------------------------
/app/http/controllers/LoginController.py:
--------------------------------------------------------------------------------
1 | """ A LoginController Module """
2 |
3 | from masonite.auth import Auth
4 | from masonite.request import Request
5 | from masonite.view import View
6 |
7 |
8 | class LoginController:
9 | """Login Form Controller
10 | """
11 |
12 | def __init__(self):
13 | """LoginController Constructor.
14 | """
15 |
16 | pass
17 |
18 | def show(self, request: Request, view: View):
19 | """Show the login page.
20 |
21 | Arguments:
22 | request {masonite.request.Request} -- The Masonite request class.
23 | view {masonite.view.View} -- The Masonite view class.
24 |
25 | Returns:
26 | masonite.view.View -- Returns the Masonite view class.
27 | """
28 |
29 | return view.render('auth/login', {'app': request.app().make('Application'), 'Auth': Auth(request)})
30 |
31 | def store(self, request: Request):
32 | """Login the user.
33 |
34 | Arguments:
35 | request {masonite.request.Request} -- The Masonite request class.
36 |
37 | Returns:
38 | masonite.request.Request -- The Masonite request class.
39 | """
40 |
41 | if Auth(request).login(request.input('username'), request.input('password')):
42 | return request.redirect('/home')
43 |
44 | return request.redirect('/login')
45 |
46 | def logout(self, request: Request):
47 | """Logs out the user.
48 |
49 | Arguments:
50 | request {masonite.request.Request} -- The Masonite request class.
51 |
52 | Returns:
53 | masonite.request.Request -- The Masonite request class.
54 | """
55 |
56 | Auth(request).logout()
57 | return request.redirect('/login')
58 |
--------------------------------------------------------------------------------
/app/http/controllers/RegisterController.py:
--------------------------------------------------------------------------------
1 | """ The RegisterController Module """
2 |
3 | from config import auth
4 | from masonite.auth import Auth
5 | from masonite.helpers import password as bcrypt_password
6 | from masonite.request import Request
7 | from masonite.view import View
8 |
9 |
10 | class RegisterController:
11 | """The RegisterController class.
12 | """
13 |
14 | def __init__(self):
15 | """The RegisterController Constructor
16 | """
17 |
18 | pass
19 |
20 | def show(self, request: Request, view: View):
21 | """Show the registration page.
22 |
23 | Arguments:
24 | Request {masonite.request.request} -- The Masonite request class.
25 |
26 | Returns:
27 | [type] -- [description]
28 | """
29 |
30 | return view.render('auth/register', {'app': request.app().make('Application'), 'Auth': Auth(request)})
31 |
32 | def store(self, request: Request):
33 | """Register the user with the database.
34 |
35 | Arguments:
36 | request {masonite.request.Request} -- The Masonite request class.
37 |
38 | Returns:
39 | masonite.request.Request -- The Masonite request class.
40 | """
41 |
42 | password = bcrypt_password(request.input('password'))
43 |
44 | auth.AUTH['model'].create(
45 | name=request.input('name'),
46 | password=password,
47 | email=request.input('email'),
48 | )
49 |
50 | # Login the user
51 | if Auth(request).login(request.input(auth.AUTH['model'].__auth__), request.input('password')):
52 | # Redirect to the homepage
53 | return request.redirect('/home')
54 |
55 | # Login failed. Redirect to the register page.
56 | return request.redirect('/register')
57 |
--------------------------------------------------------------------------------
/app/http/controllers/WelcomeController.py:
--------------------------------------------------------------------------------
1 | """ Welcome The User To Masonite """
2 |
3 | from masonite.view import View
4 | from masonite.request import Request
5 | from app.User import User
6 |
7 | class WelcomeController:
8 | """Controller For Welcoming The User
9 | """
10 |
11 | def show(self, view: View, request: Request):
12 | """Shows the welcome page.
13 |
14 | Arguments:
15 | view {masonite.view.View} -- The Masonite view class.
16 | Application {config.application} -- The application config module.
17 |
18 | Returns:
19 | masonite.view.View -- The Masonite view class.
20 | """
21 |
22 | User.create({'name': 'John', 'email': 'SomeEmail@email.com', 'password': '1234'})
23 |
24 | return view.render('welcome', {'app': request.app().make('Application')})
25 |
--------------------------------------------------------------------------------
/app/http/middleware/AuthenticationMiddleware.py:
--------------------------------------------------------------------------------
1 | """ Authentication Middleware """
2 |
3 | from masonite.request import Request
4 |
5 |
6 | class AuthenticationMiddleware:
7 | """Middleware To Check If The User Is Logged In
8 | """
9 |
10 | def __init__(self, request: Request):
11 | """Inject Any Dependencies From The Service Container
12 |
13 | Arguments:
14 | Request {masonite.request.Request} -- The Masonite request object
15 | """
16 |
17 | self.request = request
18 |
19 | def before(self):
20 | """Run This Middleware Before The Route Executes
21 | """
22 |
23 | if not self.request.user():
24 | self.request.redirect_to('login')
25 |
26 | def after(self):
27 | """Run This Middleware After The Route Executes
28 | """
29 |
30 | pass
31 |
--------------------------------------------------------------------------------
/app/http/middleware/CsrfMiddleware.py:
--------------------------------------------------------------------------------
1 | """ CSRF Middleware """
2 |
3 | from masonite.middleware import CsrfMiddleware as Middleware
4 |
5 |
6 | class CsrfMiddleware(Middleware):
7 | """ Verify CSRF Token Middleware """
8 |
9 | exempt = [
10 | '/api/user',
11 | '/token',
12 | '/jwt',
13 | '/jwt/refresh',
14 | '/authorize'
15 | ]
16 |
--------------------------------------------------------------------------------
/app/http/middleware/LoadUserMiddleware.py:
--------------------------------------------------------------------------------
1 | """ Load User Middleware """
2 |
3 | from masonite.auth import Auth
4 | from masonite.request import Request
5 |
6 |
7 | class LoadUserMiddleware:
8 | """Middleware class which loads the current user into the request
9 | """
10 |
11 | def __init__(self, request: Request, auth: Auth):
12 | """Inject Any Dependencies From The Service Container
13 |
14 | Arguments:
15 | Request {masonite.request.Request} -- The Masonite request object.
16 | """
17 |
18 | self.request = request
19 | self.auth = auth
20 |
21 | def before(self):
22 | """Run This Middleware Before The Route Executes
23 | """
24 |
25 | self.load_user()
26 | return self.request
27 |
28 | def after(self):
29 | """Run This Middleware After The Route Executes
30 | """
31 |
32 | pass
33 |
34 | def load_user(self):
35 | """Load user into the request
36 |
37 | Arguments:
38 | request {masonite.request.Request} -- The Masonite request object.
39 | """
40 |
41 | self.request.set_user(self.auth.user())
42 |
--------------------------------------------------------------------------------
/app/resources/UserResource.py:
--------------------------------------------------------------------------------
1 | from masonite.request import Request
2 |
3 | from src.api.authentication import (JWTAuthentication, PermissionScopes,
4 | TokenAuthentication)
5 | from src.api.resources import Resource
6 | from src.api.serializers import JSONSerializer
7 | from app.User import User
8 | from src.api.filters import FilterScopes
9 |
10 | class UserResource(Resource, JSONSerializer):
11 | model = User
12 | # methods = ['create', 'index', 'show']
13 | scopes = ['user:read']
14 |
15 | def index(self, request: Request):
16 | return {'id': 1}
--------------------------------------------------------------------------------
/config/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MasoniteFramework/api/6e4ec0a991fb2df1a9e23e8676a93bebfd0b53d5/config/__init__.py
--------------------------------------------------------------------------------
/config/application.py:
--------------------------------------------------------------------------------
1 | """ Application Settings """
2 |
3 | import os
4 |
5 | """
6 | |--------------------------------------------------------------------------
7 | | Application Name
8 | |--------------------------------------------------------------------------
9 | |
10 | | This value is the name of your application. This value is used when the
11 | | framework needs to place the application's name in a notification or
12 | | any other location as required by the application or its packages.
13 | |
14 | """
15 |
16 | NAME = 'Masonite 2.1'
17 |
18 | """
19 | |--------------------------------------------------------------------------
20 | | Application Debug Mode
21 | |--------------------------------------------------------------------------
22 | |
23 | | When your application is in debug mode, detailed error messages with
24 | | stack traces will be shown on every error that occurs within your
25 | | application. If disabled, a simple generic error page is shown
26 | |
27 | """
28 |
29 | DEBUG = os.getenv('APP_DEBUG', False)
30 |
31 | """
32 | |--------------------------------------------------------------------------
33 | | Secret Key
34 | |--------------------------------------------------------------------------
35 | |
36 | | This key is used to encrypt and decrypt various values. Out of the box
37 | | Masonite uses this key to encrypt or decrypt cookies so you can use
38 | | it to encrypt and decrypt various values using the Masonite Sign
39 | | class. Read the documentation on Encryption to find out how.
40 | |
41 | """
42 |
43 | KEY = os.getenv('KEY', 'wzWfd04IxEjyoyNHN9M-pizOO4TYOnWUoxBqjO61FCA=')
44 |
45 | """
46 | |--------------------------------------------------------------------------
47 | | Application URL
48 | |--------------------------------------------------------------------------
49 | |
50 | | Sets the root URL of the application. This is primarily used for testing
51 | |
52 | """
53 |
54 | URL = 'http://localhost:8000'
55 |
56 | """
57 | |--------------------------------------------------------------------------
58 | | Base Directory
59 | |--------------------------------------------------------------------------
60 | |
61 | | Sets the root path of your project
62 | |
63 | """
64 |
65 | BASE_DIRECTORY = os.getcwd()
66 |
67 | """
68 | |--------------------------------------------------------------------------
69 | | Static Root
70 | |--------------------------------------------------------------------------
71 | |
72 | | Set the static root of your application that you wil use to store assets
73 | |
74 | """
75 |
76 | STATIC_ROOT = os.path.join(BASE_DIRECTORY, 'storage')
77 |
78 | """
79 | |--------------------------------------------------------------------------
80 | | Autoload Directories
81 | |--------------------------------------------------------------------------
82 | |
83 | | List of directories that are used to find classes and autoload them into
84 | | the Service Container. This is initially used to find models and load
85 | | them in but feel free to autoload any directories
86 | |
87 | """
88 |
89 | AUTOLOAD = [
90 | 'app',
91 | ]
92 |
--------------------------------------------------------------------------------
/config/auth.py:
--------------------------------------------------------------------------------
1 | """ Authentication Settings """
2 |
3 | import os
4 | from app.User import User
5 |
6 | """
7 | |--------------------------------------------------------------------------
8 | | Authentication Model
9 | |--------------------------------------------------------------------------
10 | |
11 | | Put the model here that will be used to authenticate users to your site.
12 | | Currently the model must contain a password field. In the model should
13 | | be an auth_column = 'column' in the Meta class. This column will be
14 | | used to verify credentials in the Auth facade or any other auth
15 | | classes. The auth_column will be used to change auth things
16 | | like 'email' to 'user' to easily switch which column will
17 | | be authenticated.
18 | |
19 | | @see masonite.auth.Auth
20 | |
21 | """
22 |
23 | AUTH = {
24 | 'driver': os.getenv('AUTH_DRIVER', 'cookie'),
25 | 'model': User,
26 | }
27 |
--------------------------------------------------------------------------------
/config/database.py:
--------------------------------------------------------------------------------
1 | """ Database Settings """
2 |
3 | import os
4 |
5 | from masonite.environment import LoadEnvironment
6 | from orator import DatabaseManager, Model
7 |
8 | """
9 | |--------------------------------------------------------------------------
10 | | Load Environment Variables
11 | |--------------------------------------------------------------------------
12 | |
13 | | Loads in the environment variables when this page is imported.
14 | |
15 | """
16 |
17 | LoadEnvironment()
18 |
19 | """
20 | |--------------------------------------------------------------------------
21 | | Database Settings
22 | |--------------------------------------------------------------------------
23 | |
24 | | Set connection database settings here as a dictionary. Follow the
25 | | format below to create additional connection settings.
26 | |
27 | | @see Orator migrations documentation for more info
28 | |
29 | """
30 |
31 | DATABASES = {
32 | 'default': os.environ.get('DB_DRIVER'),
33 | 'sqlite': {
34 | 'driver': 'sqlite',
35 | 'database': os.environ.get('DB_DATABASE')
36 | },
37 | os.environ.get('DB_DRIVER'): {
38 | 'driver': os.environ.get('DB_DRIVER'),
39 | 'database': os.environ.get('DB_DATABASE'),
40 | 'prefix': ''
41 | }
42 | }
43 |
44 | DB = DatabaseManager(DATABASES)
45 | Model.set_connection_resolver(DB)
46 |
--------------------------------------------------------------------------------
/config/middleware.py:
--------------------------------------------------------------------------------
1 | """ Middleware Configuration Settings """
2 |
3 | from masonite.middleware import ResponseMiddleware
4 |
5 | from app.http.middleware.AuthenticationMiddleware import AuthenticationMiddleware
6 | from app.http.middleware.CsrfMiddleware import CsrfMiddleware
7 | from app.http.middleware.LoadUserMiddleware import LoadUserMiddleware
8 |
9 | """
10 | |--------------------------------------------------------------------------
11 | | HTTP Middleware
12 | |--------------------------------------------------------------------------
13 | |
14 | | HTTP middleware is middleware that will be ran on every request. Middleware
15 | | is only ran when a HTTP call is successful (a 200 response). This list
16 | | should contain a simple aggregate of middleware classes.
17 | |
18 | """
19 |
20 | HTTP_MIDDLEWARE = [
21 | LoadUserMiddleware,
22 | CsrfMiddleware,
23 | ResponseMiddleware
24 | ]
25 |
26 | """
27 | |--------------------------------------------------------------------------
28 | | Route Middleware
29 | |--------------------------------------------------------------------------
30 | |
31 | | Route middleware is middleware that is registered with a name and can
32 | | be used in the routes/web.py file. This middleware should really be
33 | | used for middleware on an individual route like a dashboard route.
34 | |
35 | | The Route Middleware is a dictionary with the key being what is specified
36 | | in your route/web.py file (in the .middleware() method) and the value is
37 | | a string with the full module path of the middleware class
38 | |
39 | """
40 |
41 | ROUTE_MIDDLEWARE = {
42 | 'auth': AuthenticationMiddleware,
43 | }
44 |
--------------------------------------------------------------------------------
/config/packages.py:
--------------------------------------------------------------------------------
1 | """ Packages Configuration Settings """
2 |
3 | """
4 | |--------------------------------------------------------------------------
5 | | Site Packages
6 | |--------------------------------------------------------------------------
7 | |
8 | | Although not used often, you may have to add several additional package
9 | | directories while building third party packages. Put the path of the
10 | | package here and Masonite will pick it up.
11 | |
12 | | ----------
13 | | @example
14 | | SITE_PACKAGES = [
15 | | 'venv/lib/python3.6/site-packages'
16 | | ]
17 | | ----------
18 | |
19 | """
20 |
21 | SITE_PACKAGES = [
22 | # '/Users/joseph/Programming/core'
23 | ]
24 |
--------------------------------------------------------------------------------
/config/providers.py:
--------------------------------------------------------------------------------
1 | """ Providers Configuration File """
2 |
3 | from masonite.providers import (
4 | AppProvider,
5 | SessionProvider,
6 | RouteProvider,
7 | StatusCodeProvider,
8 | SassProvider,
9 | WhitenoiseProvider,
10 | MailProvider,
11 | UploadProvider,
12 | ViewProvider,
13 | HelpersProvider,
14 | QueueProvider,
15 | BroadcastProvider,
16 | CacheProvider,
17 | CsrfProvider,
18 | )
19 |
20 | """
21 | |--------------------------------------------------------------------------
22 | | Providers List
23 | |--------------------------------------------------------------------------
24 | |
25 | | Providers are a simple way to remove or add functionality for Masonite
26 | | The providers in this list are either ran on server start or when a
27 | | request is made depending on the provider. Take some time to learn
28 | | more about Service Providers in our documentation
29 | |
30 | """
31 |
32 |
33 | PROVIDERS = [
34 | # Framework Providers
35 | AppProvider,
36 | SessionProvider,
37 | RouteProvider,
38 | StatusCodeProvider,
39 | # WhitenoiseProvider,
40 | ViewProvider,
41 |
42 | # Optional Framework Providers
43 | # SassProvider,
44 | # MailProvider,
45 | # UploadProvider,
46 | # QueueProvider,
47 | # CacheProvider,
48 | # BroadcastProvider,
49 | # CacheProvider,
50 | CsrfProvider,
51 | # HelpersProvider,
52 |
53 | # Third Party Providers
54 |
55 | # Application Providers
56 |
57 | ]
58 |
--------------------------------------------------------------------------------
/config/session.py:
--------------------------------------------------------------------------------
1 | """ Session Settings """
2 |
3 | import os
4 |
5 | """
6 | |--------------------------------------------------------------------------
7 | | Session Driver
8 | |--------------------------------------------------------------------------
9 | |
10 | | Sessions are able to be linked to an individual user and carry data from
11 | | request to request. The memory driver will store all the session data
12 | | inside memory which will delete when the server stops running.
13 | |
14 | | Supported: 'memory', 'cookie'
15 | |
16 | """
17 |
18 | DRIVER = os.getenv('SESSION_DRIVER', 'cookie')
19 |
--------------------------------------------------------------------------------
/config/storage.py:
--------------------------------------------------------------------------------
1 | """ Storage Settings """
2 |
3 | import os
4 |
5 | """
6 | |--------------------------------------------------------------------------
7 | | Storage Driver
8 | |--------------------------------------------------------------------------
9 | |
10 | | The default driver you will like to use for storing uploads. You may add
11 | | additional drivers as you need or pip install additional drivers.
12 | |
13 | | Supported: 'disk', 's3'
14 | |
15 | """
16 |
17 | DRIVER = os.getenv('STORAGE_DRIVER', 'disk')
18 |
19 | """
20 | |--------------------------------------------------------------------------
21 | | Storage Drivers
22 | |--------------------------------------------------------------------------
23 | |
24 | | Different drivers you can use for storing file uploads.
25 | |
26 | """
27 |
28 | DRIVERS = {
29 | 'disk': {
30 | 'location': 'storage/uploads'
31 | },
32 | 's3': {
33 | 'client': os.getenv('S3_CLIENT', 'AxJz...'),
34 | 'secret': os.getenv('S3_SECRET', 'HkZj...'),
35 | 'bucket': os.getenv('S3_BUCKET', 's3bucket'),
36 | }
37 | }
38 |
39 |
40 | """
41 | |--------------------------------------------------------------------------
42 | | Static Files
43 | |--------------------------------------------------------------------------
44 | |
45 | | Put anywhere you keep your static assets in a key, value dictionary here
46 | | The key will be the folder you put your assets in relative to the root
47 | | and the value will be the alias you wish to have in your templates.
48 | | You may have multiple aliases of the same name
49 | |
50 | | Example will be the static assets folder at /storage/static
51 | | and an alias of
52 | |
53 | """
54 |
55 | STATICFILES = {
56 | # folder # template alias
57 | 'storage/static': 'static/',
58 | 'storage/compiled': 'static/',
59 | 'storage/uploads': 'static/',
60 | }
61 |
62 | """
63 | |--------------------------------------------------------------------------
64 | | SASS Settings
65 | |--------------------------------------------------------------------------
66 | |
67 | | These settings is what Masonite will use to compile SASS into CSS.
68 | |
69 | | importFrom should contain a list of all folders where your main SASS
70 | | files live. Masonite will search in this folder for any .scss files
71 | | that do not start with an underscore and compile them.
72 | |
73 | | includePaths should contain a list of directories of any .scss files
74 | | that you plan to @import.
75 | |
76 | | compileTo should contain a string with the directory you want your sass
77 | | compiled to.
78 | |
79 | """
80 |
81 | SASSFILES = {
82 | 'importFrom': [
83 | 'storage/static'
84 | ],
85 | 'includePaths': [
86 | 'storage/static/sass'
87 | ],
88 | 'compileTo': 'storage/compiled'
89 | }
90 |
--------------------------------------------------------------------------------
/databases/migrations/2018_01_09_043202_create_users_table.py:
--------------------------------------------------------------------------------
1 | from orator.migrations import Migration
2 |
3 |
4 | class CreateUsersTable(Migration):
5 |
6 | def up(self):
7 | """
8 | Run the migrations.
9 | """
10 | with self.schema.create('users') as table:
11 | table.increments('id')
12 | table.string('name')
13 | table.string('email').unique()
14 | table.string('password')
15 | table.string('remember_token').nullable()
16 | table.timestamps()
17 |
18 | def down(self):
19 | """
20 | Revert the migrations.
21 | """
22 | self.schema.drop('users')
23 |
--------------------------------------------------------------------------------
/databases/migrations/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | sys.path.append(os.getcwd())
4 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
63 | * * * * 64 |
65 | 66 | Not all computers are made the same so you may have some trouble installing Masonite depending on your machine. If you have any issues be sure to read the [Known Installation Issues](https://docs.masoniteproject.com/prologue/known-installation-issues) Documentation. 67 | 68 |69 | * * * * 70 |
71 | 72 | **** 73 | 74 | ## Contributing 75 | 76 | Please read the [Contributing Documentation](https://masoniteframework.gitbook.io/docs/prologue/contributing-guide) here. Development will be on the current releasing branch of the [Core Repository](https://github.com/MasoniteFramework/core) (typically the `develop` branch) so check open issues, the current Milestone and the releases in that repository. Ask any questions you like in the issues so we can have an open discussion about the framework, design decisions and future of the project. 77 | 78 | ## Contributors 79 | 80 | Thank you for those who have contributed to Masonite! 81 | 82 | 83 | 84 | | | | | 85 | | :-------------: | :-------------: | :-------------: | 86 | | [105 | * * * * 106 |
107 | 108 | NOTE: If you do not have the craft command, you can run `pip install masonite-cli` which will install `craft` command line tool. 109 | 110 |111 | * * * * 112 |
113 | 114 | **** 115 | 116 | This command will create a new directory called `project_name` with our new Masonite project. 117 | 118 | You can now cd into this directory by doing: 119 | 120 | $ cd project_name 121 | 122 | Now we just need to add the pip dependencies. You can run `pip3 install -r "requirements.txt"` or you can run the `craft` command: 123 | 124 | $ craft install 125 | 126 | **** 127 | 128 |129 | * * * * 130 |
131 | 132 | NOTE: Python craft commands are essentially wrappers around common mundane tasks. Read the docs about the craft command tool to learn more 133 | 134 |135 | * * * * 136 |
137 | 138 | **** 139 | 140 | 141 | This will install all the required dependencies to run this framework. Now we can run the `craft` command: 142 | 143 | $ craft serve 144 | 145 | This will run the server at `localhost:8000`. Navigating to that URL should show the Masonite welcome message. 146 | 147 | If that port is blocked you can specify a port by running: 148 | 149 | $ craft serve --port 8080 150 | 151 | Or specify a host by running: 152 | 153 | $ craft serve --host 192.168.1.283 154 | 155 | The server can also be auto reloaded by passing in a `-r` flag (short for `--reload`) 156 | 157 | $ craft serve -r 158 | 159 | This will reload the server when Masonite detects file changes. This is very similiar to Django. 160 | 161 | ## Hello World 162 | 163 | All web routes are in `routes/web.py`. In this file is already the route to the welcome controller. To start your hello world example just add something like: 164 | 165 | ```python 166 | Get().route('/hello/world', 'HelloWorldController@show'), 167 | ``` 168 | 169 | our routes constant file should now look something like: 170 | 171 | ```python 172 | ROUTES = [ 173 | Get().route('/', 'WelcomeController@show'), 174 | Get().route('/hello/world', 'HelloWorldController@show'), 175 | ] 176 | ``` 177 | 178 | **** 179 | 180 |181 | * * * * 182 |
183 | 184 | NOTE: Notice this new interesting string syntax in our route. This will grant our route access to a controller (which we will create below) 185 | 186 |187 | * * * * 188 |
189 | 190 | **** 191 | 192 | Since we used a string controller we don't have to import our controller into this file. All imports are done through Masonite on the backend. 193 | 194 | You'll notice that we have a reference to the HelloWorldController class which we do not have yet. This framework uses controllers in order to separate the application logic. Controllers can be looked at as the views.py in a Django application. The architectural standard here is 1 controller per file. 195 | 196 | In order to make the `HelloWorldController` we can use a `craft` command: 197 | 198 | $ craft controller HelloWorld 199 | 200 | This will scaffold the controller for you and put it in `app/http/controllers/HelloWorldController.py` 201 | 202 | We will have a `show()` method by default which is the typical method we will use to "show" our views and content. 203 | 204 | Inside the `HelloWorldController` we can make our `show` method like this: 205 | 206 | ```python 207 | def show(self): 208 | """ Show Hello World Template """ 209 | return view('helloworld') 210 | ``` 211 | 212 | As you see above, we are returning a `helloworld` template but we do not have that yet. All templates are in `resources/templates`. We can simply make a file called `helloworld.html` or run the `craft` command: 213 | 214 | $ craft view helloworld 215 | 216 | Which will create the `resources/templates/helloworld.html` template for us. 217 | 218 | Lastly all templates run through the Jinja2 rendering engine so we can use any Jinja2 code inside our template like: 219 | 220 | inside the `resources/views/helloworld.html` 221 | 222 | ``` 223 | {{ 'Hello World' }} 224 | ``` 225 | 226 | Now just run the server: 227 | 228 | $ craft serve 229 | 230 | And navigate to `localhost:8000/hello/world` and you will see `Hello World` in your browser. 231 | 232 | Happy Crafting! 233 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | masonite>=2.2,<2.3 2 | pyjwt 3 | coveralls 4 | flake8 5 | pytest -------------------------------------------------------------------------------- /routes/web.py: -------------------------------------------------------------------------------- 1 | """ Web Routes """ 2 | from masonite.routes import Get, Post 3 | 4 | from src.api.routes import JWTRoutes, TokenRoutes 5 | from app.resources.UserResource import UserResource 6 | 7 | ROUTES = [ 8 | Get().route('/', 'WelcomeController@show').name('welcome'), 9 | UserResource('/api/user').routes(), 10 | 11 | TokenRoutes('/token'), 12 | JWTRoutes('/authorize'), 13 | ] 14 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='masonite-api', 5 | 6 | # Versions should comply with PEP440. For a discussion on single-sourcing 7 | # the version across setup.py and the project code, see 8 | # https://packaging.python.org/en/latest/single_source_version.html 9 | version='2.2.2', 10 | package_dir={'': 'src'}, 11 | 12 | description='Masonite API Package', 13 | long_description='Masonite API Package', 14 | 15 | # The project's main homepage. 16 | url='https://github.com/masoniteframework/api', 17 | 18 | # Author details 19 | author='The Masonite Community', 20 | author_email='joe@masoniteproject.com', 21 | 22 | # Choose your license 23 | license='MIT', 24 | 25 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 26 | classifiers=[ 27 | # How mature is this project? Common values are 28 | # 3 - Alpha 29 | # 4 - Beta 30 | # 5 - Production/Stable 31 | 'Development Status :: 3 - Alpha', 32 | 33 | # Indicate who your project is intended for 34 | 'Intended Audience :: Developers', 35 | 'Topic :: Software Development :: Build Tools', 36 | 'Environment :: Web Environment', 37 | 38 | # Pick your license as you wish (should match "license" above) 39 | 'License :: OSI Approved :: MIT License', 40 | 41 | 'Operating System :: OS Independent', 42 | 43 | # Specify the Python versions you support here. In particular, ensure 44 | # that you indicate whether you support Python 2, Python 3 or both. 45 | 'Programming Language :: Python :: 3.4', 46 | 'Programming Language :: Python :: 3.5', 47 | 'Programming Language :: Python :: 3.6', 48 | 'Programming Language :: Python :: 3.7', 49 | 50 | 'Topic :: Internet :: WWW/HTTP', 51 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 52 | 'Topic :: Internet :: WWW/HTTP :: WSGI', 53 | 'Topic :: Software Development :: Libraries :: Application Frameworks', 54 | 'Topic :: Software Development :: Libraries :: Python Modules', 55 | ], 56 | 57 | # What does your project relate to? 58 | keywords='masonite python framework', 59 | 60 | # You can just specify the packages manually here if your project is 61 | # simple. Or you can use find_packages(). 62 | packages=find_packages(exclude=[ 63 | 'tests*', 64 | 'app', 65 | 'bootstrap', 66 | 'config', 67 | 'databases', 68 | 'resources', 69 | 'routes', 70 | 'storage' 71 | ]), 72 | 73 | # List run-time dependencies here. These will be installed by pip when 74 | # your project is installed. For an analysis of "install_requires" vs pip's 75 | # requirements files see: 76 | # https://packaging.python.org/en/latest/requirements.html 77 | install_requires=[ 78 | 'pyjwt>=1.7.1' 79 | ], 80 | 81 | # List additional groups of dependencies here (e.g. development 82 | # dependencies). You can install these using the following syntax, 83 | # for example: 84 | # $ pip install -e .[dev,test] 85 | extras_require={ 86 | 'test': ['coverage', 'pytest'], 87 | }, 88 | 89 | # If there are data files included in your packages that need to be 90 | # installed, specify them here. If using Python 2.6 or less, then these 91 | # have to be included in MANIFEST.in as well. 92 | ## package_data={ 93 | ## 'sample': [], 94 | ## }, 95 | 96 | # Although 'package_data' is the preferred approach, in some case you may 97 | # need to place data files outside of your packages. See: 98 | # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa 99 | # In this case, 'data_file' will be installed into '