I'm building a project with multiple flask applications and all of them need to share the same database and they both have the same secret key. I have first_application.py
import os
import enum
from datetime import datetime, timezone
from flask import (
Flask, jsonify, request
)
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import (
create_access_token, get_jwt_identity,
jwt_required, JWTManager
)
from flask_cors import CORS, cross_origin
from dotenv import load_dotenv
load_dotenv()
application = Flask(__name__)
CORS(application, support_credentials=True)
db = SQLAlchemy(application)
jwt = JWTManager(application)
application.config['SECRET_KEY'] = 'same_secret'
application.config['SQLALCHEMY_DATABASE_URI'] = 'same_rds_db_uri'
class RoleEnum(enum.Enum):
waiter = 'waiter'
manager = 'manager'
class ShiftEnum(enum.Enum):
night = 'night'
day = 'day'
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
password = db.Column(db.String(6), unique=True, nullable=False)
role = db.Column(
db.Enum(RoleEnum),
default=RoleEnum.waiter,
nullable=False
)
shift = db.Column(
db.Enum(ShiftEnum),
default=ShiftEnum.night,
nullable=False
)
started_job = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<User %r>' % self.name
#application.route("/login", methods=["POST"])
def login():
password = request.json.get("password", None)
user = User.query.filter_by(password=password).first_or_404()
access_token = create_access_token(identity=user.name)
return jsonify(access_token=access_token)
#application.route("/start-job", methods=["POST"])
#jwt_required()
def start_job():
current_user = get_jwt_identity()
user = User.query.filter_by(name=current_user)
user.started_job = datetime.now(timezone.utc)
return jsonify({"message": "Job started"}), 201
with application.app_context():
db.create_all()
if __name__ == "__main__":
application.run(debug=True)
and second_application.py
import os
import enum
from datetime import datetime, timezone
from flask import (
Flask, jsonify, request
)
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import (
create_access_token, get_jwt_identity,
jwt_required, JWTManager
)
from flask_cors import CORS, cross_origin
from dotenv import load_dotenv
load_dotenv()
application = Flask(__name__)
CORS(application, support_credentials=True)
db = SQLAlchemy(application)
jwt = JWTManager(application)
application.config['SECRET_KEY'] = 'same_secret'
application.config['SQLALCHEMY_DATABASE_URI'] = 'same_rds_db_uri'
class TableStatusEnum(enum.Enum):
reserved = 'Reserved'
free_table = 'Free table'
preperation = 'Preperation'
occupied = 'Occupied'
class Table(db.model):
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.String(80), nullable=False)
chairs = db.Column(db.Integer)
status = db.Column(
db.Enum(TableStatusEnum),
default=TableStatusEnum.free_table,
nullable=False
)
waiter = db.Column(db.Integer, db.ForeignKey('user.id'))
if __name__ == "__main__":
application.run(debug=True)
Now I need to create one to many relationship between User and Table models. The question is how do I connect them if they are in different environments. I'm using the same AWS RDS database.
I assume by connecting you mean joining?
After creating the tables from two separate applications, you can use reflection to access the other tables that are already in the database.
Related
I am building a web-application in flask and one of the modules I am adding to it is the user module which contains the information from the users including ID, email, password and role.
For the password I am trying to generate a password hash but in my flask shell I cannot add the password to the database (however I can add email AND also if I do not generate password hash, I can add password too).
For the user module I made a Blueprint and a separate folder which includes models.py and __init__.py.
Here is the app.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import Development
app = Flask(__name__)
app.config.from_object(Development)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
#app.route('/')
def index():
return "Home page"
from mod_users import users
app.register_blueprint(users)
And for the users module (folder), here is the __init__.py file:
from flask import Blueprint
users = Blueprint('users', __name__, url_prefix='/users/')
from .models import User
#users.route('/')
def user_index():
return "Hello from User index"
And here is the models.py :
from werkzeug.security import generate_password_hash
from sqlalchemy import Column, Integer, String
from app import db
class User(db.Model):
__tablename__ = 'users'
ID = Column(Integer(), primary_key=True)
email = Column(String(128), nullable=False , unique=True)
password = Column(String(128), nullable=False, unique=False)
role = Column(Integer(), nullable=False, default=0)
def set_password(self, password):
self.password = generate_password_hash(password)
In my flask shell :
from mod_users.models import User
from app import db
user = User()
user.email = ‘myemail#hgku.er’
user.set_password('123456')
For the last line I will get this error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'User' object has no attribute 'set_password'
But if I do:
user.password = ‘123456’
It works and I can add it to the database.
Do you know how I can fix the error?
your indentation in the User object is apparently wrong. if you want set_password to be a class function, you have to indent it into the User class scope
class User(db.Model):
__tablename__ = 'users'
ID = Column(Integer(), primary_key=True)
email = Column(String(128), nullable=False , unique=True)
password = Column(String(128), nullable=False, unique=False)
role = Column(Integer(), nullable=False, default=0)
def set_password(self, password):
self.password = generate_password_hash(password)
I've create CRUD API in Flask, but I have a problem with the filtering function returning books by a specific author.
from flask import Flask, request, jsonify, make_response, render_template
from flask_sqlalchemy import SQLAlchemy
from marshmallow import fields
from marshmallow_sqlalchemy import SQLAlchemySchema
from flask_marshmallow import Marshmallow
import psycopg2
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] ='postgresql+psycopg2://name:pass#localhost/testovoe1'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
ma=Marshmallow(app)
class Book(db.Model):
__tablename__='books'
id=db.Column(db.Integer, primary_key=True)
author=db.Column(db.String(100), nullable=False)
title=db.Column(db.String(100), nullable=False)
def __init__(self, author, title):
self.author=author
self.title=title
class BookSchema(ma.Schema):
class Meta:
fields=("author","title")
book_schema=BookSchema()
books_schema=BookSchema(many=True)
.............
#app.route('/book_author/<author>/', methods=['GET'])
def book_authors(author):
book=Book.query.filter_by(author=author)
return book_schema.jsonify(book)
Suppose I want to get a list of books filtered by the author Johnson. Using the query http://127.0.0.1:5000/book_author/Johnson shows empty result.
got this error while executing my aap.py...cna anyone help?`
sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 1 - probably unsupported type.
[SQL: INSERT INTO room (r_name, created_at, created_by, r_description) VALUES (?, CURRENT_TIMESTAMP, ?, ?)]
[parameters: ('hello', <Users 13>, None)]
(Background on this error at: http://sqlalche.me/e/14/rvf5)
my module.py
from flask import Flask
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import DateTime
from sqlalchemy.sql import func
import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///C:/sqlite3/database/chat.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
class Users(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
phone_no = db.Column(db.Integer, unique=True, nullable=False)
city = db.Column(db.String(80), nullable=False)
rooms = db.relationship('Room', backref='users')
class Room(db.Model):
id = db.Column(db.Integer, primary_key=True)
r_name = db.Column(db.String(200), unique=False, nullable=False)
created_at = db.Column(db.DateTime, default=db.func.current_timestamp())
created_by = db.Column(db.String(200), db.ForeignKey('users.id'), nullable=False)
r_description = db.Column(db.String(200), nullable=True)
if __name__ == '__main__':
manager.run()
db.create_all()
'''
my app.py
'''
from flask import Flask, request, jsonify
from models import db, Users, Room, app
from datetime import datetime
#app.route('/user', methods=['POST'])
def add_users():
if request.method == 'POST':
name = request.json['name']
email = request.json['email']
phone_no = request.json['phone_no']
city = request.json['city']
new_user = Users(name=name, email=email, phone_no=phone_no, city=city)
db.session.add(new_user)
db.session.commit()
room = Room(r_name='hello')
room.created_by = new_user
# room.created_at = datetime(2015, 6, 5, 8, 10, 10, 10)
db.session.add(room)
db.session.commit()
return jsonify({'message': 'successfully created user'})
if __name__ == '__main__':
app.run(debug=True)
'''
room.created_by is an integer column, so you can't assign a User instance like new_user to it.
You could assign new_user.id
room.created_by = new_user.id
but it might be more elegant to make use of the rooms relationship defined on User.
This ought to work
#app.route('/user', methods=['POST'])
def add_users():
if request.method == 'POST':
name = request.json['name']
email = request.json['email']
phone_no = request.json['phone_no']
city = request.json['city']
new_user = Users(name=name, email=email, phone_no=phone_no, city=city)
room = Room(r_name='hello')
new_user.rooms.append(room)
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'successfully created user'})
I am trying to map my class diagram into data base tables. I have a repair class that inherits the service class. But when I am trying to do that its says that Can't find any foreign key relationships between 'service' and 'repair
This this my full code.
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from sqlalchemy import ForeignKey
import os
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
database = SQLAlchemy(app)
ORM = Marshmallow(app)
# Models
# Service Model
class Service(database.Model):
service_id = database.Column(database.Integer, primary_key=True)
image_url = database.Column(database.String(255))
jewellery_type = database.Column(database.String(50))
def __init__(self, image_url, jewellery_type):
self.image_url = image_url
self.jewellery_type = jewellery_type
# Service Schema
class ServiceSchema(ORM.Schema):
class Meta:
fields = ('service_id', 'image_url', 'jewellery_type')
# Initialize Service Schema
service_schema = ServiceSchema()
Service_schema_all = ServiceSchema(many=True)
# repair Model
class Repair(Service):
repair_id = database.Column(database.Integer, ForeignKey('service_id'), primary_key=True)
damage_type = database.Column(database.String(50))
repair_type = database.column(database.String(50))
def _init__(self, repair_id, damage_type, repair_type):
self.repair_id = repair_id
self.damage_type = damage_type
self.repair_type = repair_type
# repair Schema
class RepairSchema(ORM.Schema):
class Meta:
fields = ('repair_id', 'damage_type', 'repair_type')
# Initialize Repair Schema
repair_schema = RepairSchema()
repair_schema_all = RepairSchema(many=True)
# start the server
if __name__ == '__main__':
app.run(debug=True)
Try changing this reference
ForeignKey('service_id')
to
ForeignKey('service.service_id').
I'm trying to replicate this https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xxiii-application-programming-interfaces-apis focus only in the API and security (tokens) part.
I'm having problems when I'm executing the example to manage the database
>>> u = User(username='susan', email='susan#example.com')
>>> db.session.add(u)
>>> db.session.commit()
I get this error:
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
The main idea here is to validate if the db is working properly
This is the code in my main app/init.py file:
from flask import Flask, request, current_app
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import Config
db = SQLAlchemy()
migrate = Migrate()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db)
from app.main import bp as main_bp
app.register_blueprint(main_bp)
from app.api import bp as api_bp
app.register_blueprint(api_bp, url_prefix='/api')
return app
from app import models
This is my app/models.py file:
from flask import current_app, url_for
from werkzeug.security import generate_password_hash, check_password_hash
from app import db#, login
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
token = db.Column(db.String(32), index=True, unique=True)
token_expiration = db.Column(db.DateTime)
def __repr__(self):
return '<User {}>'.format(self.username)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def from_dict(self, data, new_user=False):
for field in ['username', 'email']:
if field in data:
setattr(self, field, data[field])
if new_user and 'password' in data:
self.set_password(data['password'])
#staticmethod
def check_token(token):
user = User.query.filter_by(token=token).first()
if user is None or user.token_expiration < datetime.utcnow():
return None
return user