I am trying to integrate Flask-SocketIO with my Flask application.
For some reason I am getting an import error that is triggered by the
from .. import socketio that I have in my events.py and I am not sure why.
I would greatly appreciate any help provided.
app.py
from factory import create_app
app = create_app()
factory.py
from flask import Flask
from flask.ext.socketio import SocketIO
from flask.ext.login import LoginManager
import os
from celery import Celery
lm = LoginManager()
socketio = SocketIO()
lm.login_view = 'main.login'
lm.session_protection = 'strong'
def create_app():
app = Flask(__name__)
app.config.from_object(os.environ.get('APP_CONFIG')) # export APP_CONFIG=settings.Development
lm.init_app(app)
from project.main import main as main_blueprint
app.register_blueprint(main_blueprint)
socketio.init_app(app)
return app
main/____init____.py
from flask import Blueprint
main = Blueprint('main', __name__)
import views, events
main/events.py
# from __future__ import absolute_import
from uuid import uuid4
from flask import current_app, session, request
from flask.ext.socketio import emit, disconnect
from .. import socketio
#socketio.on('status', namespace='/events')
def events_message(message):
print 'socketio.on: status'
emit('status', {'status': message['status']})
#socketio.on('disconnect request', namespace='/events')
def disconnect_request():
print 'socketio.on: disconnect request'
emit('status', {'status': 'Disconnected!'})
disconnect()
#socketio.on('connect', namespace='/events')
def events_connect():
print 'socketio.on: connect'
websocket_id = str(uuid4())
session['websocket_id'] = websocket_id
current_app.clients[websocket_id] = request.namespace
emit('websocket_id', {'websocket_id': websocket_id})
Rename main/____init____.py to main/__init__.py and you can do:
from . import socketio
if socketio is defined in __init__.py like you said. However, it looks like it's defined in factory.py, in which case you'd do:
from ..factory import socketio
Related
I am using python anywhere to host a flask app that has 2 components: 1) a website to show some stuff from a txt file and 2) a python script to do some API stuff and change the data in the txt file.
Currently, I can run both of these separately without issue but I cannot use them together. I have tried to use threading but it doesn't work.
Basically, the background script (part 2) is in backend.py called by mainloop() consists of some API calls to other websites, modifying the txt file then sleeping for an hour.
wsgi.py
import sys
path = '/home/michalis95/API-updater'
if path not in sys.path:
sys.path.append(path)
from threading import Thread
import website
application = website.create_app()
/website/__init.py__
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
from threading import Thread
from flask_login import LoginManager
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from .views import views
from .auth import auth
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
from .models import User, Note
create_database(app)
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))
import backend
def run():
t=Thread(target=backend.mainloop())
t.start()
run()
return app
def create_database(app):
if not path.exists('website/' + DB_NAME):
db.create_all(app=app)
print('Created Database!')
backend.py
def mainloop():
while True:
#do stuff
time.sleep(3600)
You might need to look into Always-on tasks,
"Always-on tasks are scripts that are kept running all the time, and restarted if they crash."
I use them, they are really effective.Depending on the plan you have, They cost about a buck per month, but they do the job.
The problem was in
def run():
t=Thread(target=backend.mainloop())
...
it should be
def run():
t=Thread(target=backend.mainloop())
...
I tried to use Flask-Dance with normal flask app and it works and if I try to implement with flask blueprints it doesn't work. How to register flask-dance to flask blueprints?
My views.py for auth blueprint
from flask import render_template, url_for, redirect, current_app, request
from app.auth import auth
from flask_dance.contrib import github
#auth.route('/login')
def login():
return render_template('auth/login.html')
#auth.route("/")
def github():
if not github.authorized:
return redirect(url_for("github.login"))
resp = github.get("/user")
assert resp.ok
return "You are #{login} on GitHub".format(login=resp.json()["login"])
my init.py for auth blueprint
from flask import Blueprint
from flask_dance.contrib.github import make_github_blueprint, github
auth = Blueprint('auth', __name__, url_prefix='/auth')
blueprint = make_github_blueprint(client_id="m-client-id",client_secret="my-client-secret")
auth.register_blueprint(blueprint, url_prefix="/auth")
from app.auth import views
and my main init.py file:
from flask import Flask
from flask_fontawesome import FontAwesome
from app.config import Config
fa = FontAwesome()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
fa.init_app(app)
from app.public import public
app.register_blueprint(public)
from app.auth import auth
app.register_blueprint(auth)
return app
First you should create and register different blueprint for github.
github/init.py
from flask_dance.contrib import github
from flask_dance.contrib.github import make_github_blueprint
github_blueprint = make_github_blueprint(client_id='your-client-id',client_secret='your-client-secret')
from app.github import views
github/views.py
#github_blueprint.route("/")
def github_login():
if not github.authorized:
return redirect(url_for('github.login'))
account_info = github.get('/user')
if account_info.ok:
account = account_info.json()
return '<h1>Your Github name is {}'.format(account['login'])
and finally in your main init.py file
from flask import Flask
from flask_fontawesome import FontAwesome
from app.config import Config
fa = FontAwesome()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
fa.init_app(app)
from app.public import public
app.register_blueprint(public)
from app.auth import auth
app.register_blueprint(auth)
from app.github import github_blueprint
app.register_blueprint(github_blueprint, url_prefix='/github_login')
#/github_login=callback url
return app
I am getting the following error when trying to set up a scheduled job for my flask app:
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
I have tried to include the function 'print_session' (which is just a dummy function to check the session data will pull through - in reality this function will query a database) with a 'current_app.appcontext() with loop as I have seen on a few other apps but no joy. Does anyone know why it is still out of the application context?
main.py
from website import create_app
app = create_app()
if __name__=="__main__":
app.run(debug=True,host='localhost',port=5000,threaded=True)
init.py
from flask import Flask, session
from flask_sqlalchemy import SQLAlchemy
from os import path
from flask_session import Session
from flask_login import LoginManager
import redis
db = SQLAlchemy()
DB_NAME = 'sqlite:///db.sqlite3'
sess=Session()
login_manager = LoginManager()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = "SECRET_KEY"
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
app.config['SESSION_TYPE'] = 'SESSION_TYPE'
app.config['SESSION_REDIS'] = 'SESSION_REDIS'
db.init_app(app)
sess.init_app(app)
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
# with app.app_context():
from .views import views
from .auth import auth
app.register_blueprint(views,url_prefix='/')
app.register_blueprint(auth,url_prefix='/')
from .models import User,Token
create_database(app)
return app
def create_database(app):
db.create_all(app=app)
print('Created database')
views.py
from flask import Blueprint,render_template,session,redirect,request,url_for
from flask import current_app
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
from flask_login import login_required,current_user
from requests_oauthlib import OAuth2Session
from . import db
from .models import Token
from functools import wraps
def print_session(value):
with current_app.app_context():
print('Yes',value)
return(redirect(url_for('views.home')))
#views.route('/start_schedule')
#login_required
def start_xero_schedule():
with app.app_context():
sched = BackgroundScheduler()
sched.add_job(print_session,'interval',args=[session['value']],seconds=10)
sched.start()
return(redirect(url_for('views.xero')))
I'm trying to turn my Flask code into a python package structure, but now that I've done that, when I try running the code, none of the HTML templates are found.
Here is the simplified structure of my current flask package. run.py is what I use to execute the Flask code. routes.py contains all my #app.routes where the HTML templates are called.
pipeline-ui/
run.py
pipeline_app/
__init__.py
routes.py
models.py
forms.py
templates/
pipeline-alt.html
The error message I get is: TemplateNotFound: pipeline-alt.html
init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask('__name__')
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from pipeline_app import routes
run.py:
from pipeline_app import app
if __name__ == '__main__':
app.run(debug=True)
routes.py:
from flask import url_for, render_template, request, flash, redirect
from pipeline_app import app
from pipeline_app.forms import InputForm, RegistrationForm, LoginForm
from pipeline_app.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required
from math import ceil
import json
import subprocess
import os
import sys
from pprint import pprint
#app.route('/', methods=['GET', 'POST'])
def pipeline():
form = InputForm(request.form)
if request.method == 'POST':
if form.validate_on_submit():
STACK_NAME = request.form['stack_name']
# Store data in database for future use
db.create_all()
db_inputs = Post(stack_name=STACK_NAME)
db.session.add(db_inputs)
db.session.commit()
return render_template('pipeline-alt.html',
title='Pipeline Input',
form=form,
STACK_NAME=STACK_NAME)
Change app = Flask('__name__') to app = Flask(__name__). Flask uses this parameter to find resources on the filesystem, so if it is not set correctly it will not be able to find your templates.
i have a files like app.py and views.py
app.py
from flask import Flask
from flask_pymongo import PyMongo
app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://local:27017/local"
mongo = PyMongo(app)
from views import profileview
profileview.register(app, route_prefix='/profile/')
if __name__== "__main__":
app.run(debug=True)
views.py
from flask_classy import FlaskView , route
# i am unable to import the app in views
from app import mongo
class profileview(FlaskView):
route_base = '/'
#route("/user/",methods=["GET"])
def index(self):
pass
when i run the server it showing that cannot
import from views import profileview, how to avoid the circular import
this is how to avoid circular import :
db.py
from flask_pymongo import PyMongo
mongo = PyMongo()
app.py
if __name__ == '__main__':
from db import mongo
mongo.init_app(app)
views.py
from db import mongo
or you could use the factory pattern and make a create_app function.