File tree Expand file tree Collapse file tree 9 files changed +87
-74
lines changed Expand file tree Collapse file tree 9 files changed +87
-74
lines changed Original file line number Diff line number Diff line change 1
1
venv /
2
2
idea /
3
3
.idea
4
+ .venv
5
+ .code
6
+ vscode
7
+ .vscode
4
8
.env
5
9
.DS_Store
6
10
.__pycache__ /
7
11
__pycache__ /
8
12
tests /__pycache__ /
9
13
.pytest_cache /
10
14
migrations /
11
- ** .db
15
+ ** .db
16
+ instance
Original file line number Diff line number Diff line change @@ -14,26 +14,28 @@ Initial scaffolding for a flask rest API development. Starter template for build
14
14
15
15
This App was developed with the following stack:
16
16
17
- - Python
18
- - Flask
19
- - Flask-restful
20
- - Postgres DB
17
+ - Python==3.12
18
+ - Flask==3.10
19
+ - Flask-restful==0.3.10
20
+ - Flask-Script==2.0.6
21
+ - Flask-SQLAlchemy==3.1.1
22
+ - Postgres DB / SQlite
21
23
- Gunicorn Web Server
22
24
23
25
## Requirements
24
- - Python 3.6 +
26
+ - Python 3.12 +
25
27
- Python pip
26
- - Postgres SQL
28
+ - Postgres / SQlite
27
29
28
30
## Installation
29
31
- fork this repository
30
32
- create a .env file as shown in the env_example file
31
33
- setup your database
32
34
- on the terminal cd into the app folder
33
35
- run ` pip install -r requirements.txt ` to install required modules
34
- - run ` python manage.py db init ` to setup alembic migrations
35
- - run ` python manage.py db migrate -m='<your migration message>'` to create migration files
36
- - then run ` python manage.py db upgrade ` to create tables
36
+ - run ` flask --app manage db init ` to setup alembic migrations
37
+ - run ` flask --app manage db migrate -m='<your migration message>'` to create migration files
38
+ - then run ` flask --app python manage db upgrade` to create tables
37
39
38
40
## Running the App
39
41
- on the terminal run ` gunicorn main:app `
@@ -48,5 +50,13 @@ This App was developed with the following stack:
48
50
- You can modify the app to suit your need.
49
51
- Happy usage.
50
52
53
+ ## Update Information
54
+ - Flask-JWT has been replaced with Flask-JWT-extended
55
+ - Flask-Scripts and dependencies removed.
56
+ - Future versions may use Pydantic instead of Marshmallow
57
+
58
+ ## Contributions
59
+ - Contributors are needed to keep developing this template with updates to its dependencies. You can reach me on my email.
60
+
51
61
## Credits
52
62
solnsumei@gmail.com
Original file line number Diff line number Diff line change 1
1
import os
2
- from os .path import join , dirname
3
2
from dotenv import load_dotenv
4
3
5
- dotenv_path = join ( dirname ( __file__ ), '.env' )
6
- load_dotenv ( dotenv_path )
4
+ load_dotenv ( )
5
+
7
6
8
7
app_environment = os .environ .get ('FLASK_ENV' )
9
8
JWT_AUTH_URL_RULE = '/api/v1/login'
Original file line number Diff line number Diff line change 1
- import os
2
1
from flask import Flask , Blueprint
3
2
from flask_restful import Api
4
- from flask_jwt import JWT
5
- from src .utils .security import authenticate , identity
3
+ from flask_jwt_extended import JWTManager
6
4
from src .models .basemodel import db
7
5
8
6
@@ -30,8 +28,6 @@ def create_app():
30
28
31
29
flask_app .register_blueprint (admin_bp , url_prefix = "/api/v1/admin" )
32
30
33
- JWT (flask_app , authenticate , identity ) # /auth
34
-
35
31
@flask_app .route ('/' )
36
32
def index ():
37
33
return 'Welcome to Flask Rest API Setup!'
@@ -42,6 +38,7 @@ def index():
42
38
43
39
44
40
app = create_app ()
41
+ jwt = JWTManager (app )
45
42
46
43
47
44
if __name__ == "__main__" :
Original file line number Diff line number Diff line change 1
1
import importlib
2
2
import os
3
- from flask_script import Manager
4
- from flask_migrate import Migrate , MigrateCommand
3
+ from flask_migrate import Migrate
5
4
from src .models .basemodel import db
6
5
from main import create_app
7
6
8
-
9
7
app = create_app ()
10
8
11
9
@@ -24,9 +22,6 @@ def scan_models():
24
22
25
23
migrate = Migrate (app , db )
26
24
27
- manager = Manager (app )
28
- manager .add_command ('db' , MigrateCommand )
29
-
30
- if __name__ == '__main__' :
25
+ if __name__ == "__main__" :
31
26
scan_models ()
32
- manager . run ()
27
+
Original file line number Diff line number Diff line change 1
- alembic == 1.4.3
2
- aniso8601 == 8.0.0
3
- attrs == 20.2.0
4
- bcrypt == 3.2.0
5
- cffi == 1.14.3
6
- click == 7.1.2
7
- dnspython == 1.16.0
8
- eventlet == 0.31.0
9
- Flask == 1.1.2
10
- Flask-JWT == 0.3.2
11
- Flask-Migrate == 2.5.3
12
- Flask-RESTful == 0.3.8
1
+ alembic == 1.14.1
2
+ aniso8601 == 10.0.0
3
+ attrs == 25.1.0
4
+ bcrypt == 4.2.1
5
+ blinker == 1.9.0
6
+ cffi == 1.17.1
7
+ click == 8.1.8
8
+ dnspython == 2.7.0
9
+ eventlet == 0.39.0
10
+ Flask == 3.1.0
11
+ Flask-JWT-Extended == 4.7.1
12
+ Flask-Migrate == 4.1.0
13
+ Flask-RESTful == 0.3.10
13
14
Flask-Script == 2.0.6
14
- Flask-SQLAlchemy == 2.4.4
15
- greenlet == 0.4.17
16
- gunicorn == 20.0.4
17
- iniconfig == 1.0.1
18
- itsdangerous == 1.1.0
19
- Jinja2 == 2.11.3
20
- Mako == 1.2.2
21
- MarkupSafe == 1.1.1
22
- marshmallow == 3.8.0
23
- monotonic == 1.5
24
- packaging == 20.4
25
- passlib == 1.7.2
26
- pluggy == 0.13.1
27
- psycopg2-binary == 2.8.6
28
- py == 1.10.0
29
- pycparser == 2.20
30
- PyJWT == 1.4.2
31
- pyparsing == 2.4.7
32
- pytest == 6.1.0
33
- python-dateutil == 2.8.1
34
- python-dotenv == 0.14.0
15
+ Flask-SQLAlchemy == 3.1.1
16
+ greenlet == 3.1.1
17
+ gunicorn == 23.0.0
18
+ iniconfig == 2.0.0
19
+ itsdangerous == 2.2.0
20
+ Jinja2 == 3.1.5
21
+ Mako == 1.3.9
22
+ MarkupSafe == 3.0.2
23
+ marshmallow == 3.26.1
24
+ monotonic == 1.6
25
+ packaging == 24.2
26
+ passlib == 1.7.4
27
+ pluggy == 1.5.0
28
+ psycopg2-binary == 2.9.10
29
+ pycparser == 2.22
30
+ PyJWT == 2.10.1
31
+ pyparsing == 3.2.1
32
+ pytest == 8.3.4
33
+ python-dateutil == 2.9.0.post0
34
+ python-dotenv == 1.0.1
35
35
python-editor == 1.0.4
36
- python-slugify == 4 .0.1
37
- pytz == 2020 .1
38
- six == 1.15 .0
39
- SQLAlchemy == 1.3.19
36
+ python-slugify == 8 .0.4
37
+ pytz == 2025 .1
38
+ six == 1.17 .0
39
+ SQLAlchemy == 2.0.38
40
40
text-unidecode == 1.3
41
- toml == 0.10.1
42
- urllib3 == 1.26.5
43
- webargs == 6.1.1
44
- Werkzeug == 1.0.1
41
+ toml == 0.10.2
42
+ typing_extensions == 4.12.2
43
+ urllib3 == 2.3.0
44
+ webargs == 8.6.0
45
+ Werkzeug == 3.1.3
Original file line number Diff line number Diff line change 1
1
from flask_restful import Resource
2
- from werkzeug . security import safe_str_cmp
2
+ from hmac import compare_digest
3
3
from src .models .user import UserModel
4
4
from src .models .schemas .user import UserSchema , user_summary
5
5
@@ -11,7 +11,7 @@ class Register(Resource):
11
11
@UserSchema .validate_fields (location = ('json' ,))
12
12
def post (args ):
13
13
14
- if not safe_str_cmp (args ['password' ], args ['password_confirmation' ]):
14
+ if not compare_digest (args ['password' ], args ['password_confirmation' ]):
15
15
return {
16
16
'success' : False ,
17
17
'errors' : {
@@ -43,4 +43,3 @@ def post(args):
43
43
'success' : True ,
44
44
'user' : user_summary .dump (user ).data
45
45
}, 201
46
-
Original file line number Diff line number Diff line change 1
1
from functools import wraps
2
- from flask_jwt import current_identity
2
+ from flask_jwt_extended import current_user
3
3
4
4
5
5
def admin_required ():
6
6
def decorator (f ):
7
7
@wraps (f )
8
8
def decorated_function (* args , ** kwargs ):
9
- if not current_identity .is_admin :
9
+ if not current_user .is_admin :
10
10
return {"error" : "Unauthorized user" }, 403
11
11
return f (* args , ** kwargs )
12
12
return decorated_function
Original file line number Diff line number Diff line change 1
1
from src .models .user import UserModel
2
+ from main import jwt
2
3
3
4
4
5
def authenticate (email , password ):
@@ -7,6 +8,12 @@ def authenticate(email, password):
7
8
return user
8
9
9
10
10
- def identity (payload ):
11
- user_id = payload ['identity' ]
11
+ @jwt .user_identity_loader
12
+ def user_identity_lookup (user ):
13
+ return user .id
14
+
15
+
16
+ @jwt .user_lookup_loader
17
+ def identity (_jwt_header , jwt_data ):
18
+ user_id = jwt_data ['sub' ]
12
19
return UserModel .find_by_id (user_id )
You can’t perform that action at this time.
0 commit comments