Python Flask create schedule on startup - python

I am new-ish to python and new to Flask. I am trying to use APScheduler to schedule a db update when the app starts. It works until I tried to update the database. It says the database is not defined, but I am importing with from .models import Readings. Error can be recreated by uncommenting the lines in interval_task().
init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_apscheduler import APScheduler
from os import path
from flask_login import LoginManager
import pandas as pd
import multiprocessing
import random
db = SQLAlchemy()
DB_NAME_LEOTTA = "leotta.db"
DB_NAME_QUICK = "quick.db"
simulated_room_temperature = multiprocessing.Value('d', 29)
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = '0ddish'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///databases/{DB_NAME_LEOTTA}'
app.config['SQLALCHEMY_BINDS'] = {'quickdb' : f'sqlite:///databases/{DB_NAME_QUICK}'}
db.init_app(app)
from .views import views
from .auth import auth
from .scheduler import scheduler
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
app.register_blueprint(scheduler, url_prefix='/')
from .models import User, Note, Readings
create_database(app)
sched = APScheduler()
sched.init_app(app)
sched.start()
INTERVAL_TASK_ID = '1'
sched.add_job(id=INTERVAL_TASK_ID, func=interval_task, trigger='interval', seconds=5)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
return app
def create_database(app):
if not path.exists('website/databases/' + DB_NAME_LEOTTA):
#since no bind is specified, it will use default bind
db.create_all(app=app)
print('Created Database ' + DB_NAME_LEOTTA)
if not path.exists('website/databases/' + DB_NAME_QUICK):
db.create_all(bind=DB_NAME_QUICK)
print('Created Database ' + DB_NAME_QUICK)
def interval_task():
simulated_room_temperature.value = random.uniform(19, 31)
#reading = Readings(param_name='Temperature', param_value=simulated_room_temperature.value)
#db.session.add(reading)
#db.session.commit()
print(random.uniform(19, 31))
main.py
from website import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
models.py
from . import db
from flask_login import UserMixin
from sqlalchemy.sql import func
class Note(db.Model):
#no bind specified, will use default
id = db.Column(db.Integer, primary_key=True)
note = db.Column(db.String(150))
date_time = db.Column(db.DateTime(timezone=True), default=func.now('UTC'))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class User(db.Model, UserMixin):
#no bind specified, will use default
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
notes = db.relationship('Note')
class Readings(db.Model):
__bind_key__ = 'quickdb'
id = db.Column(db.Integer, primary_key=True)
param_name = db.Column(db.String(150), unique=True)
date_time = db.Column(db.DateTime(timezone=True), default=func.now('UTC'))
param_value = db.Column(db.Float)

Related

SQLAlchemy Marshmallow return empy JSON flask

I'm trying to get a JSON with all registered users, but the request returns an empty object.
Model and Schemas Model
from dataclasses import field
from utils.database import db, ma
from flask_bcrypt import check_password_hash
class Gym(db.Model):
id = db.Column(db.Integer, primary_key=True)
gym_nombre = db.Column(db.String(100))
password = db.Column(db.String(200))
direccion = db.Column(db.String(200))
propietario = db.Column(db.String(200))
telefono = db.Column(db.String(200))
def __init__(self, gym_nombre, password,direccion, propietario,telefono):
self.gym_nombre = gym_nombre
self.password = password
self.direccion = direccion
self.propietario = propietario
self.telefono = telefono
class GymSchemas(ma.Schema):
class meta:
model = Gym
gyms_schemas = GymSchemas(many=True)
gym_schemas = GymSchemas()
Route "usuarios"
from flask import Blueprint, jsonify
from models.model_usuarios import Gym, gyms_schemas
usuarios = Blueprint("usuarios", __name__)
#usuarios.route("/usuarios", methods=['GET'])
def getUsers():
all_users = Gym.query.all()
return jsonify(gyms_schemas.dump(all_users))
Request in postman

Flask-Marshmallow returning empty json and saying my schema is invalid

I am trying to use Marshmallow to serialize my Message Model class yet it is returning an empty json object whenever I try to get the data and after I debugged the program with
print(messagesSchema.validate(messages))
It said: 0: {'_schema': ['Invalid input type.']}
This is my Chat model, Message Model and my MessageSchema model
class Chat(db.Model):
id = db.Column(db.Integer, primary_key=True)
user1 = db.Column(db.String(150), unique=True)
user2 = db.Column(db.String(150), unique=True)
room = db.Column(db.String(300), unique=True)
messages = db.relationship("Message", backref="chat")
class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(300))
username = db.Column(db.String(150))
chat_id = db.Column(db.Integer, db.ForeignKey("chat.id"))
class MessageSchema(ma.SQLAlchemySchema):
class Meta:
model = Message
This is my socketHandler file
messages = Chat.query.filter_by(room=room).first().messages
messagesSchema = MessageSchema(many=True)
print(messagesSchema.validate(messages))
output = messagesSchema.dump(messages)
print(output)
print(jsonify(output))
and the init.py file if anybody is wondering
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from os import path
from flask_login import LoginManager
db = SQLAlchemy()
DB_NAME = "database.db"
ma = Marshmallow()
def create_app():
app = Flask(__name__)
app.config["SECRET_KEY"] = "secret"
app.config["SQLALCHEMY_DATABASE_URI"] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from .views import views
from .auth import auth
from .slashUrl import slashUrl
app.register_blueprint(slashUrl, url_prefix="/")
app.register_blueprint(views, url_prefix="/home/")
app.register_blueprint(auth, url_prefix="/auth/")
from .models import User
create_database(app)
login_manager = LoginManager()
login_manager.login_view = "auth.login"
login_manager.login_message_category = "dangerAlert"
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
return app
def create_database(app):
if not path.exists("website/" + DB_NAME):
db.create_all(app=app)
print("Database created")
From my print statements I get
{0: {'_schema': ['Invalid input type.']}}
[{}]
<Response 9 bytes [200 OK]>
If anybody knows how to fix this your help would be greatly appreciated!

Flask-sqlalchemy AttributeError: 'function' object has no attribute 'query'

I've been using flask with flask-sqlalchemy successfully for a number of weeks, but all of a sudden my code is coming up with this error: AttributeError: 'function' object has no attribute 'query', relating to this line of code:
project_choices = [(str(c.id) + ': ' + c.project_name) for c in Projects.query.all()]
Seems like the flask-sqalchemy Projects class is not being successfully created but I can't work out why.
Main routes file:
from flask import Flask, request, flash, url_for, redirect, render_template, session
from flask_sqlalchemy import SQLAlchemy
from app import db
from app import app
from app.forms import Basic_data_Form, Which_project#, Areas_form
from flask_bootstrap import Bootstrap
from app.models import Projects
#app.route('/Index', methods = ['GET', 'POST'])
def Index():
if 'project_name' not in session:
session['project_name'] = "0: No project selected"
project_name = session['project_name'].split(':')[1]
project_choices = [(str(c.id) + ': ' + c.project_name) for c in Projects.query.all()]
form2 = Which_project()
form2.project_choice.choices = project_choices
return render_template('Index.html', form2=form2, projects = Projects.query.filter_by(id=session['project_name'].split(':')[0]).all(), project_name=project_name)
init file:
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
bootstrap = Bootstrap(app)
from app import routes
models file:
from app import db
class Projects(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
project_name = db.Column(db.String(100))
user_id = db.Column(db.String(100))
address = db.Column(db.String(100))
region = db.Column(db.String(100))
postcode = db.Column(db.String(20))
building_year = db.Column(db.Integer)
climate_file = db.Column(db.String(100))
building_TFA = db.Column(db.Float)
thermal_mass = db.Column(db.String(100))
winter_int_temp = db.Column(db.Float)
summer_int_temp = db.Column(db.Float)
height_above_sea = db.Column(db.Float)
occupany = db.Column(db.Float)
def __repr__(self):
return '<Project {}>'.format(self.project_name)
I had a similar issue with that same error. It was because there was a function with the same name. So that is probably why it was saying a function had no attribute query even though the table used with sqlalchemy is a class
Consider either implementing a class function which renders the object into the current string representation you desire or implementing a hybrid property.
String method:
class Projects(db.Model):
...
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
project_name = db.Column(db.String(100))
...
def __str__(self):
return f'{self.id}: {self.project_name}'
Use string method as follows:
project_choices = Projects.query.all()
form2 = Which_project()
# probably str(x) would work, but if it doesn't the code below def works
form2.project_choice.choices = [x.__str__() for x in project_choices]
Hybrid property method:
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
class Projects(db.Model):
...
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
project_name = db.Column(db.String(100))
...
#hybrid_property
def project_choice(self):
return f'{self.id}: {self.project_name}'
Use hybrid property as follows:
# Access only the hybrid property
project_choices = Projects.query(Projects.project_choice).all()
form2 = Which_project()
form2.project_choice.choices = project_choices

Eve Authentication with bcrypt driver.db error when sending curl request

I use bcrypt for the authentication of my resources and have accounts stored in mydatabase with username and passwords. I have stored the passwords manually as hashes in the database as follows:
I started the python bash and typed in following code:
import bcrypt
password = u'passwordtobehashed'
password_hashed = bcrypt.hashpw(password, bcrypt.gensalt())
print (password_hashed)
Then i copied the output of print and stored it in the account table via a POST Request(w/o authentication):
curl -d '{"username": "someuser", "password": "somehashedpassword", "roles_id": 1}' -H 'Content-Type: application/json' http://127.0.0.1:5000/account
Well I use SQLAlchemy and eve is also up to date (Version: 0.7.1).
Well I request for example the people resource using Bcrypted Authentication as follows:
curl -u username 127.0.0.1:5000/people
Then I enter my password and I get following error:
File "/home/vagrant/erpghost/restapi/oldtrivial.py", line 57, in check_auth
accounts = app.data.driver.db['account']
AttributeError: 'SQLAlchemy' object has no attribute 'db'
For some reason the db attribute is not available. I also tried to use Eve.app.data.driver.db and I tried importing current_app from flask but that all did not work.
Well here is my code:
oldtrivial.py
from eve.auth import BasicAuth
from eve import Eve
from eve_sqlalchemy import SQL
from eve_sqlalchemy.validation import ValidatorSQL
import bcrypt
from connection import connect
from connection import Base
con, meta = connect()
Base.metadata.create_all(con)
class BCryptAuth(BasicAuth):
def check_auth(self, username, password, allowed_roles, resource, method):
accounts = app.data.driver.db['account']
account = accounts.find_one({'username': username})
return account and \
bcrypt.hashpw(password, account['password']) == account['password']
app = Eve(validator=ValidatorSQL, data=SQL, auth=BCryptAuth)
db = app.data.driver
Base.metadata.bind = db.engine
db.Model = Base
db.create_all()
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)
tables.py
from sqlalchemy.orm import column_property
from sqlalchemy import Column, Integer, String, DateTime, func, ForeignKey
from connection import connect
from eve.auth import BasicAuth
from connection import Base
from sqlalchemy.orm import relationship
con, meta = connect()
class CommonColumns(Base):
__abstract__ = True
_created = Column(DateTime, default=func.now())
_updated = Column(DateTime, default=func.now(), onupdate=func.now())
_etag = Column(String(40))
class People(CommonColumns):
__tablename__ = 'people'
_id = Column(Integer, primary_key=True, autoincrement=True)
firstname = Column(String(80))
lastname = Column(String(120))
fullname = column_property(firstname + " " + lastname)
class Roles(CommonColumns):
__tablename__ = 'roles'
_id = Column(Integer, primary_key=True, autoincrement=True)
role = Column(String(80))
class Account(CommonColumns):
__tablename__ = 'account'
_id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), nullable=False, unique=True)
password = Column(String(200), nullable=False)
roles = relationship("Roles", backref="account")
roles_id = Column(Integer, ForeignKey('roles._id'))
settings.py
from eve_sqlalchemy.decorators import registerSchema
from eve.utils import config
from tables import People
from tables import Account
from tables import Roles
registerSchema('people')(People)
registerSchema('roles')(Roles)
registerSchema('account')(Account)
DOMAIN = {
'people': People._eve_schema['people'],
'roles': Roles._eve_schema['roles'],
'account': Account._eve_schema['account'],
}
DOMAIN['account'].update({
'additional_lookup': {
'url': 'regex("[\w]+")',
'field': 'username'
},
'cache_control': '',
'cache_expires': 0,
'allowed_roles': ['superuser', 'admin'],
'authentication': None,
})
SQLALCHEMY_DATABASE_URI = 'postgresql://databaseuser:password#localhost:5432/database'
RESOURCE_METHODS = ['GET', 'POST']
ITEM_METHODS = ['GET', 'DELETE', 'PATCH', 'PUT']
DEBUG = True
config.ID_FIELD = config.ITEM_LOOKUP_FIELD = '_id'
DOMAIN['people']['id_field'] = config.ID_FIELD
DOMAIN['roles']['id_field'] = config.ID_FIELD
DOMAIN['account']['id_field'] = config.ID_FIELD
Hope someone can help me out.
Something along these lines should work:
from flask import current_app
from tables import Account
# ...
def check_auth(...):
session = current_app.data.driver.session
return session.query(Account) \
.filter(Account.username == username,
Account.password == hashed_password) \
.count() > 0
I guess you've tried to mimic the code in http://python-eve.org/authentication.html#basic-authentication-with-bcrypt ? This is for using Mongo-DB instead of SQLAlchemy.

Database Entry not Happening in Flask App with SQL Alchemy?

APP CODE : There is no entry in the database and i am new at Flask and i am not able to connect to database and get entry into it and i am confused is my code is at all right
from flask import *
from wtforms import *
from wtforms.validators import Required
from flask.ext.wtf import Form
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.secret_key = 'MY CSI FORM'
branch_choices = [('CSE','CSE'),('ECE','ECE'),('MEC','MEC'),('CIVIL','CIVIL')]
year_choices = [('1st','1st'),('2nd','2nd'),('3rd','3rd'),('4th','4th')]
cmem_choices = [('Yes','Yes'),('No','No')]
class CSIForm(Form):
er = IntegerField('Enrollment No',validators=[Required()])
name = StringField('Name', validators=[Required()])
branch = SelectField('Branch',choices=branch_choices, validators=[Required()])
year = SelectField('Year',choices=year_choices, validators=[Required()])
cmem = SelectField('CSI Member',choices=cmem_choices,validators=[Required()])
sop = TextAreaField('Statement of Purpose', validators=[Required()])
submit = SubmitField('Submit')
DATABASE CODE : Code for database creation in SQLAlchemy dont know its correct or not
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
class CSI(db.Model):
__tablename__ = 'form'
er = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
branch = db.Column(db.String(3))
year = db.Column(db.String(3))
cmem = db.Column(db.String(3))
sop = db.Column(db.String(50))
def __init__(self, er, name, branch, year, cmem, sop):
self.er = er
self.name = name
self.branch = branch
self.year = year
self.cmem = cmem
self.sop = sop
def connect_db():
db.create_all()
App running and connection
#app.route('/', methods=['GET', 'POST'])
def index():
form=CSIForm(request.form)
connect_db()
if form.validate_on_submit():
csi = CSI()
form.populate_obj(csi)
flash('Thanks for registering')
return render_template('form.html',form=form)
if __name__ == "__main__":
app.debug='True'
app.run()
You'll probably want to read up on sessions in SQLAlchemy. You need to add csi to your current session and commit the transaction.
def index():
form = CSIForm(request.form)
connect_db()
if form.validate_on_submit():
csi = CSI()
form.populate_obj(csi)
# These lines are new.
db.session.add(csi)
db.session.commit()
flash('Thanks for registering')

Categories

Resources