Flask socket.io message events in different files - python

socketservice.py:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from backend.database import db
app = Flask(__name__)
socketio = SocketIO(app, engineio_logger=True)
#socketio.on('connect')
def handle_connection():
from backend.electionAdministration import syncElections
syncElections()
if __name__ == '__main__':
socketio.run(app)
electionAdministration.py:
from flask_socketio import SocketIO, emit
from bson.json_util import dumps
from backend.socketservice import socketio
from backend.database import db
def syncElections():
elections = db.elections.find()
emit('syncElections',dumps(res) , broadcast=True)
#socketio.on('createElection')
def createElection(data):
db.elections.insert({'title': data["title"]})
syncElections()
The problem is, that the createElection event is never being called, when it is within the file electionAdministration.py. When I move it into socketservice.py, it suddenly works.
But I mean, I cannot put everything into one file, as it will get very messy as the application grows.

What you need to do is import your secondary module in the main module, but you need to do it after the socketio variable is created, because if not you will run into circular dependency errors.
Example:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from backend.database import db
app = Flask(__name__)
socketio = SocketIO(app, engineio_logger=True)
#socketio.on('connect')
def handle_connection():
from backend.electionAdministration import syncElections
syncElections()
import electionAdministration # <--- import your events here!
if __name__ == '__main__':
socketio.run(app)
In addition, you need to consider that your main Python script is not going to be called socketservice, because Python always names the top-level script __main__. So, if you start the above script as your main script, the second file should import socketio as follows:
from __main__ import socketio
This is a small annoyance with Python, which is made worse when you want to have a script that you sometimes run as a main script, but other times you also want it to be imported by another script. To make the import work in such case, I use the following trick:
try:
from __main__ import socketio
except ImportError:
from socketservice import socketio

Related

ImportError: cannot import name 'app' from 'FlaskApp' (unknown location)

I have been following this tutorial from digital ocean.
I got all the way to the last step when I get a 500 Internal Server Error.
My app is structured like the following:
|--------FlaskApp
|----------------FlaskApp
|-----------------------static
|-----------------------templates
|-----------------------venv
|-----------------------__init__.py
|----------------flaskapp.wsgi
My __init__.py contains the following:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello, I love Digital Ocean!"
if __name__ == "__main__":
app.run()
My flaskapp.wsgi contains the following:
import sys
import logging
import site
site.addsitedir('/var/www/FlaskApp/venv/lib/python3.7/site-packages')
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")
from FlaskApp import app as application
application.secret_key = 'key'
I had added the bit about importing site after reading this SO
When I look into /var/www/FlaskApp/venv/lib/python3.7/site-packages I can in fact see that packages I need and when I run python3, and import flask, it does load.
Thanks for your help in advance!

Flask ImportError: cannot import name (for app in __init__.py)

I'm new to flask, and REST-APIs / server side scripting in general. I get the error "ImportError: cannot import name 'flask_app'" when I try executing run_app.py
This is my dir structure.
my_project
- webapp
- __init__.py
- helpers.py
- c_data.py
- run_app.py
Contents of each file:
__init__.py
"""This is init module."""
from flask import Flask
from webapp import c_data
# Place where webapp is defined
flask_app = Flask(__name__)
c_data.py
"""This module will serve the api request."""
from app_config import client
from webapp import flask_app
from webapp import helpers
from flask import request, jsonify
# Select the database
db = client.newDB
# Select the collection
collection = db.collection
#flask_app.route("/")
def get_initial_response():
"""Welcome message for the API."""
# Message to the user
message = {
'apiVersion': 'v1.0',
'status': '200',
'message': 'Welcome to the Flask API'
}
# Making the message looks good
resp = jsonify(message)
# Returning the object
return resp
run_app.py
# -*- coding: utf-8 -*-
from webapp import flask_app
if __name__ == '__main__':
# Running webapp in debug mode
flask_app.run(debug=True)
What am I doing wrong?
It is because you import c_data in init.py, this makes recursive import
To be clearer, you import c_data and define flask_app inside __init__, but later than c_data you import flask_app which is not defined yet.
from webapp import c_data # Remove it, it makes recursive import
# Place where webapp is defined
flask_app = Flask(__name__)
Try to remove it. Or change the way to import c_data.
Possible solution, change your run_app.py
Remember to remove from webapp import c_data in __init__.py
from webapp import flask_app
from webapp import c_data # New import
if __name__ == '__main__':
# Running webapp in debug mode
flask_app.run(debug=True)

Flask ImportError: cannot import name routes

I'm converting a cli application to use a REST api and I've read up on flask and I thought I understood things but apparently not :-D. based on this: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
I have a directory structure:
--myApp
myApp.py
--APIService
__init__.py
WebService.py
myApp.py:
from APIService import app
app.run(debug = True )
init:
from flask import Flask
app = Flask(__name__)
from app import routes
WebService.py:
from APIService import app
class WebService(object):
'''
classdocs
'''
def __init__(self,):
'''
Constructor
'''
#app.route('/')
#app.route('/index')
def index():
return "Hello, World!"
I've tried this a few different ways like renaming app to APIService but I keep circling back to the same error: APIService\__init__.py", line 5, in <module> from app import routes ImportError: No module named app
I just don't get what I'm doing wrong here. I did pip install flask so the module is there. I skipped the environment part but that's because I wasn't bothered with running globally for now. anyone have a clue as to what I messed up?
In the following line insideAPIService\__init__.py:
from app import routes
the keyword routes is referencing a separate Python Module inside the APIService folder that is named "routes.py" in the Flask Mega Tutorial. It seems like you have renamed the "routes.py" file to "WebService.py" so you can solve the import issue by changing the import line insideAPIService\__init__.pyto:
from app import WebService

Flask ImportError: cannot import name 'app' [duplicate]

Trying to run my python file updater.py to SSH to a server and run some commands every few set intervals or so. I'm using APScheduler to run the function update_printer() from __init__.py. Initially I got a working outside of application context error but someone suggested that I just import app from __init__.py. However it isn't working out so well. I keep getting a cannot import name 'app' error.
app.py
from queue_app import app
if __name__ == '__main__':
app.run(debug=True)
__init__.py
from flask import Flask, render_template
from apscheduler.schedulers.background import BackgroundScheduler
from queue_app.updater import update_printer
app = Flask(__name__)
app.config.from_object('config')
#app.before_first_request
def init():
sched = BackgroundScheduler()
sched.start()
sched.add_job(update_printer, 'interval', seconds=10)
#app.route('/')
def index():
return render_template('index.html')
updater.py
import paramiko
import json
from queue_app import app
def update_printer():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(app.config['SSH_SERVER'], username = app.config['SSH_USERNAME'], password = app.config['SSH_PASSWORD'])
...
File Structure
queue/
app.py
config.py
queue_app/
__init__.py
updater.py
Error
Traceback (most recent call last):
File "app.py", line 1, in <module>
from queue_app import app
File "/Users/name/queue/queue_app/__init__.py", line 3, in <module>
from queue_app.updater import update_printer
File "/Users/name/queue/queue_app/updater.py", line 3, in <module>
from queue_app import app
ImportError: cannot import name 'app'
What do I need to do be able to get to the app.config from updater.py and avoid a "working outside of application context error" if ran from APScheduler?
It's a circular dependency, as you import updater in your __init__.py file. In my Flask setup, app is created in app.py.

Tumblelog Application with Flask and MongoEngine example does not work - Complete Novice

The Tumblelog app on the MongoDB site does not work .
I've followed the example absolutely and I get a 404 error when I run it in my local host. I'm using Eclipse Indigo (3.7.2) with pyDev on Ubuntu 12.0.4.
I'm not sure if it's because of the register_blueprints, which I included in the __init__.py
I did it like this as in the tutorial:
from flask import Flask
from flask.ext.mongoengine import MongoEngine
app = Flask(__name__)
app.config["MONGODB_DB"] = "my_tumble_log"
app.config["SECRET_KEY"] = "KeepThisS3cr3t"
db = MongoEngine(app)
if __name__ == '__main__':
app.run()
def register_blueprints(app):
# Prevents circular imports
from tumblelog.views import posts
app.register_blueprint(posts)
register_blueprints(app)
Otherwise I have followed the tutorial exactly.
register_blueprints is never called - app.run blocks until you kill the script (at which point there is no point to adding routes).
Change the order and everything will run:
def register_blueprints(app):
# Prevents circular imports
from tumblelog.views import posts
app.register_blueprint(posts)
register_blueprints(app)
if __name__ == '__main__':
app.run()
regist_blueprints is not actually preventing circular imports - the pattern to avoid circular imports is to create the app in a different file and import both app and blueprint into a third file to run everything:
# application.py
from flask import Flask # etc.
app = Flask("your_package_name")
# tumblelog/views.py
from flask import Blueprint, current_app # etc.
posts = Blueprint("tumblelog")
#posts.route("/")
def index():
# use current_app rather than app here
# run_server.py (use the same pattern for .wsgi files)
from application import app
from tumblelog.views import posts
app.register_blueprint(posts)
if __name__ == "__main__":
app.run()

Categories