I am trying to implement multiprocessing or threading in my flask __init__.py to implement a sub-process that will handle some back-end work for me. However, I can't seem to pass the application context to the sub-process, and exisitng libraries are focused on requests - I need this process to start running in parallel when flask is run, no later.
Here is my __init__.py code (excluding setup for irrelevant pages, I only use one implementation at a time ofc):
import os
from multiprocessing import Process
from threading import Thread
from flask_executor import Executor
from flask import Flask
from . import backend
def create_app():
app = Flask(__name__, instance_relative_config=True)
# Multiprocessing Implementation:
p = Process(target=backend.start)
p.start()
# Threading Implementation:
thread = Thread(target=backend.start)
thread.daemon = True
thread.start()
# Flask Executor Implementation:
executor = Executor(app)
executor.submit(backend.start)
return app
And here is my backend.py, called by the subprocess:
from datetime import datetime
from flask import g, request, session
from flaskr.db import log
def start(app=None):
print("\nBackend Started\n")
log("INFO","Backend Started")
while True:
pass
The backend code calls a logging function which works when called from a request inside my normal flask process.
My multiprocessing and threading implementation do not work, as I cannot pass the application context to the sub-process. Process(target=backend.start, args=app) or Thread(target=backend.start, args=app) gives me an error, TypeError: 'Flask' object is not iterable. I cannot add #with_appcontext flags to the start function, as it is not a request.
My Flask Executor passes the application context to the sub-process, but it cannot succeed either, as it is not called from a request:
Traceback (most recent call last):
File "c:\...\python\python39\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\...\python\python39\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\...\Python\Python39\Scripts\flask.exe\__main__.py", line 7, in <module>
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 988, in main
cli.main()
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 579, in main
return super().main(*args, **kwargs)
File "c:\...\python\python39\lib\site-packages\click\core.py", line 1055, in main
rv = self.invoke(ctx)
File "c:\...\python\python39\lib\site-packages\click\core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "c:\...\python\python39\lib\site-packages\click\core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\...\python\python39\lib\site-packages\click\core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "c:\...\python\python39\lib\site-packages\click\decorators.py", line 84, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "c:\...\python\python39\lib\site-packages\click\core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 850, in run_command
app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 299, in __init__
self._load_unlocked()
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 333, in _load_unlocked
self._app = rv = self.loader()
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 389, in load_app
app = locate_app(import_name, name)
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 251, in locate_app
return find_best_app(module)
File "c:\...\python\python39\lib\site-packages\flask\cli.py", line 77, in find_best_app
app = app_factory()
File "C:\...\flaskr\__init__.py", line 51, in create_app
executor.submit(backend.start)
File "c:\...\python\python39\lib\site-packages\flask_executor\executor.py", line 162, in submit
fn = self._prepare_fn(fn)
File "c:\...\python\python39\lib\site-packages\flask_executor\executor.py", line 122, in _prepare_fn
fn = copy_current_request_context(fn)
File "c:\...\python\python39\lib\site-packages\flask\ctx.py", line 172, in copy_current_request_context
raise RuntimeError(
RuntimeError: This decorator can only be used when a request context is active, such as within a view function.
How can I implement this properly?
I found a solution to this issue. I added this code to my backend.py:
from flask import Blueprint
from threading import Thread
bp = Blueprint('backend', __name__)
def backend(app):
thread = Thread(target=start, args=(app,))
thread.daemon = True
thread.start()
I then added backend.backend(app) to my create_app() function in __init__.py, right before the end of my function. This will call my backend() function from backend.py and pass the application context, and this function starts my sub-process.
Related
What I'm trying to do:
In init.py I have a function create_app that needs to call a function called init_tokenizer that uses the global dict g and I get the following errors when I use any flask commands such as flask --version or flask init-db (a command I created and must use):
When I tried to do:
def init_tokenizer(app):
...
with app.app_context():
g.starts = starts
g.ends = ends
g.tokenizer = tokenizer
I get the error:
Traceback (most recent call last):
File "C:\Users\yonik\anaconda3\envs\venv\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\yonik\anaconda3\envs\venv\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\yonik\anaconda3\envs\venv\Scripts\flask.exe\__main__.py", line 7, in <module>
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 988, in main
cli.main()
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 579, in main
return super().main(*args, **kwargs)
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\click\core.py", line 1055, in main
rv = self.invoke(ctx)
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\click\core.py", line 1655, in
invoke
sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)
AttributeError: 'function' object has no attribute 'make_context'
And when I tried to do:
#with_appcontext
def init_tokenizer()
Or:
starts, ends, my_tokenizer = tokenizer.init_tokenizer(app)
with app.app_context():
g.starts = starts
g.ends = ends
g.my_tokenizer = my_tokenizer
I got the infinite recursion:
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 77, in
find_best_app
app = app_factory()
File "C:\yoni\final_project\web_app\flaskr\__init__.py", line 34, in create_app
tokenizer.init_tokenizer(app)
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\click\decorators.py", line 26, in
new_func
return f(get_current_context(), *args, **kwargs)
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 426, in
decorator
with __ctx.ensure_object(ScriptInfo).load_app().app_context():
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 389, in
load_app
app = locate_app(import_name, name)
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 251, in
locate_app
return find_best_app(module)
File "C:\Users\yonik\anaconda3\envs\venv\lib\site-packages\flask\cli.py", line 77, in
find_best_app
app = app_factory()
I use windows 10, Python 3.9.12, Flask 2.1.2, Werkzeug 2.1.2
Solution:
Turns out that because I already deleted and re-created the database with the command: init-db I can't use the command again before there is something in the database.
I am having trouble running flask db migrate. I have run flask db init without issue and have modified the resulting migrations/env.py file to focus only on a specific schema in an existing MS SQL Server database. It is acting like the migrations/env.py: run_migrations_online() method is not finding the correct app configuration. It wants to create a default sqlite in memory db instead.
I am defining SQLALCHEMY_DATABASE_URI in create_app() where that reads in a local config file:
app.config.from_object('app.local_settings')
The config for the mssql db should be:
SQLALCHEMY_DATABASE_URI = \
"mssql+pyodbc://db-dev.my.company.com/devdb?driver=SQL+Server"
My app entry point looks like:
from app import create_app
try:
app = create_app()
except Exception as e:
print(repr(e))
raise
if __name__ == "__main__":
try:
app.run(debug=True)
except Exception as e:
app.logger.error(repr(e))
print(repr(e))
The definition of create_app() is in the __init__.py of the app module:
import pyodbc
from flask import Flask
from flask_mail import Mail
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect
from flask_security import Security, SQLAlchemyUserDatastore, auth_required, \
hash_password
from flask_security.models import fsqla_v2 as fsqla
# Instantiate Flask
app = Flask(__name__)
# Instantiate Flask extensions
csrf_protect = CSRFProtect(app=app)
db = SQLAlchemy(app=app)
mail = Mail(app=app)
migrate = Migrate(app=app, db=db)
# Initialize Flask Application
def create_app(extra_config_settings={}):
# Load common settings
app.config.from_object('app.settings')
# Load environment specific settings
app.config.from_object('app.local_settings')
# Load extra settings from extra_config_settings param
app.config.update(extra_config_settings)
# print(pyodbc.drivers())
# Setup Flask-SQLAlchemy
db.init_app(app)
# Setup Flask-Migrate
migrate.init_app(app=app, db=db)
# Setup Flask-Mail
mail.init_app(app)
# Setup WTForms CSRFProtect
csrf_protect.init_app(app)
# Register blueprints
from .views import register_blueprints
register_blueprints(app)
# Setup an error-logger to send emails to app.config.ADMINS
init_email_error_handler(app)
# Setup Flask-User to handle user account related forms
from .models.user import User, UserRegisterForm, UserProfileForm, \
UserLoginForm
from .views.main import user_profile_page
from .models.roles import Role
# APIs
from .views import register_api, SchoolAPI
register_api(app, SchoolAPI, 'school_api', '/school/', pk='school_id')
# #app.context_processor
# def context_processor():
# return dict(user_manager=user_manager)
fsqla.FsModels.set_db_info(db)
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
return app
I have modified the migrations/env.py file as:
from __future__ import with_statement
import logging
from logging.config import fileConfig
from flask import current_app
from alembic import context
config = context.config
fileConfig(config.config_file_name)
logger = logging.getLogger('alembic.env')
config.set_main_option(
'sqlalchemy.url',
str(current_app.extensions['migrate'].db.get_engine().url).replace(
'%', '%%'))
target_metadata = current_app.extensions['migrate'].db.metadata
def include_name(name, type_, parent_names):
result = False
if type_ == "schema":
return name in ["MySchema"]
else:
return True
def run_migrations_offline():
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
print(f'run_migrations_offline: {url}')
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
version_table_schema='MySchema',
include_schemas=True,
include_name=include_name
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
# this callback is used to prevent an auto-migration from being generated
# when there are no changes to the schema
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
def process_revision_directives(context, revision, directives):
if getattr(config.cmd_opts, 'autogenerate', False):
script = directives[0]
if script.upgrade_ops.is_empty():
directives[:] = []
logger.info('No changes in schema detected.')
connectable = current_app.extensions['migrate'].db.get_engine()
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
version_table_schema='MySchema',
include_schemas=True,
include_name=include_name,
**current_app.extensions['migrate'].configure_args
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
When I run flask db migrate I get:
H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask_sqlalchemy\__init__.py:851: UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".
warnings.warn(
H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask_sqlalchemy\__init__.py:872: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds signi
ficant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
warnings.warn(FSADeprecationWarning(
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
Traceback (most recent call last):
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1819, in _execute_context
self.dialect.do_execute(
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\engine\default.py", line 732, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: unknown database "MyProjectDB"
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Python310\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "H:\path\to\my\project\UserInterface\venv\Scripts\flask.exe\__main__.py", line 7, in <module>
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask\cli.py", line 988, in main
cli.main()
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask\cli.py", line 579, in main
return super().main(*args, **kwargs)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\core.py", line 1055, in main
rv = self.invoke(ctx)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\core.py", line 1657, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\decorators.py", line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask\cli.py", line 427, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\click\core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask_migrate\cli.py", line 104, in migrate
_migrate(directory, message, sql, head, splice, branch_label, version_path,
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask_migrate\__init__.py", line 98, in wrapped
f(*args, **kwargs)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\flask_migrate\__init__.py", line 155, in migrate
command.revision(config, message, autogenerate=True, sql=sql,
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\command.py", line 229, in revision
script_directory.run_env()
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\script\base.py", line 569, in run_env
util.load_python_file(self.dir, "env.py")
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\util\pyfiles.py", line 94, in load_python_file
module = load_module_py(module_id, path)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\util\pyfiles.py", line 110, in load_module_py
spec.loader.exec_module(module) # type: ignore
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "H:\path\to\my\project\UserInterface\MyProjectDB\migrations\env.py", line 108, in <module>
run_migrations_online()
File "H:\path\to\my\project\UserInterface\MyProjectDB\migrations\env.py", line 102, in run_migrations_online
context.run_migrations()
File "<string>", line 8, in run_migrations
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\runtime\environment.py", line 853, in run_migrations
self.get_context().run_migrations(**kw)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\runtime\migration.py", line 601, in run_migrations
heads = self.get_current_heads()
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\runtime\migration.py", line 533, in get_current_heads
if not self._has_version_table():
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\runtime\migration.py", line 549, in _has_version_table
return sqla_compat._connectable_has_table(
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\alembic\util\sqla_compat.py", line 195, in _connectable_has_table
return inspect(connectable).has_table(tablename, schemaname)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\engine\reflection.py", line 283, in has_table
return self.dialect.has_table(conn, table_name, schema)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\dialects\sqlite\base.py", line 2018, in has_table
info = self._get_table_pragma(
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\dialects\sqlite\base.py", line 2545, in _get_table_pragma
cursor = connection.exec_driver_sql(statement)
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1686, in exec_driver_sql
return self._exec_driver_sql(
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1595, in _exec_driver_sql
ret = self._execute_context(
File "H:\path\to\my\project\UserInterface\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1862, in _execute_context
Thoughts?
Turns out that I was trying to follow Flask-Security-Too's "Basic SQLAlchemy Application with session" quick start guide. I am not claiming it is incorrect but my understanding is probably flawed.
I decided to replace FST's "session" idea with the simpler "SQLAlchemy Application" sample and everything is rolling along just fine.
My best guess at the general issue is that maybe Alembic was not at the correct version or there are changes to the env.py file that I could not figure out.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I just installed Python, pip, and flask.
Then I created a test file (hello.py):
from flask import Flask
app = Flask(_name_)
#app.route('/')
def index():
return 'Hello world!'
if __name__ == "__main__":
app.run()
when I try to run the file using
>set FLASK_APP=hello.py
>flask run
I get this error
Serving Flask app "hello.py"
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
Traceback (most recent call last):
File "c:\users\ahmed\appdata\local\programs\python\python39\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\users\ahmed\appdata\local\programs\python\python39\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\ahmed\helloworld\env\Scripts\flask.exe\__main__.py", line 7, in <module>
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "c:\users\ahmed\helloworld\env\lib\site-packages\click\core.py", line 782, in main
rv = self.invoke(ctx)
File "c:\users\ahmed\helloworld\env\lib\site-packages\click\core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "c:\users\ahmed\helloworld\env\lib\site-packages\click\core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\users\ahmed\helloworld\env\lib\site-packages\click\core.py", line 610, in invoke
return callback(*args, **kwargs)
File "c:\users\ahmed\helloworld\env\lib\site-packages\click\decorators.py", line 73, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "c:\users\ahmed\helloworld\env\lib\site-packages\click\core.py", line 610, in invoke
return callback(*args, **kwargs)
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 848, in run_command
app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 305, in __init__
self._load_unlocked()
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 330, in _load_unlocked
self._app = rv = self.loader()
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "c:\users\ahmed\helloworld\env\lib\site-packages\flask\cli.py", line 240, in locate_app
__import__(module_name)
File "C:\Users\ahmed\helloworld\hello.py", line 2, in <module>
app = Flask(_name_)
NameError: name '_name_' is not defined
The key is here
File "C:\Users\ahmed\helloworld\hello.py", line 2, in <module>
app = Flask(_name_)
NameError: name '_name_' is not defined
So, change
app = Flask(_name_)
to
app = Flask(__name__)
The reason for the double underscore is that in Python they have a special meaning. See Underscore vs Double underscore with variables and methods
and What is the meaning of single and double underscore before an object name?
The code you posted has also other issues. For example, in the last line you have no identation. Also, your formatting can be improved. Putting it together, your code might look like this.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return 'Hello world!'
if __name__ == "__main__":
app.run()
I try to create a simple flask app:
from flask import Flask
app = Flask(__name__)
if __name__ == '__main__':
app.run()
but when I add the debug:
FLASK_APP = run.py
FLASK_ENV = development
FLASK_DEBUG = 1
I got the following error:
ValueError: signal only works in main thread
here the full stacktrace
FLASK_APP = run.py
FLASK_ENV = development
FLASK_DEBUG = 1
In folder c:/MyProjectPath/api
c:\MyProjectPath\api\venv\Scripts\python.exe -m flask run
* Serving Flask-SocketIO app "run.py"
* Forcing debug mode on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 283-122-745
Exception in thread Thread-1:
Traceback (most recent call last):
File "c:\appdata\local\programs\python\python37\Lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "c:\appdata\local\programs\python\python37\Lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "c:\MyProjectPath\api\venv\lib\site-packages\flask_socketio\cli.py", line 59, in run_server
return run_command()
File "c:\MyProjectPath\api\venv\lib\site-packages\click\core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "c:\MyProjectPath\api\venv\lib\site-packages\click\core.py", line 717, in main
rv = self.invoke(ctx)
File "c:\MyProjectPath\api\venv\lib\site-packages\click\core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\MyProjectPath\api\venv\lib\site-packages\click\core.py", line 555, in invoke
return callback(*args, **kwargs)
File "c:\MyProjectPath\api\venv\lib\site-packages\click\decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "c:\MyProjectPath\api\venv\lib\site-packages\click\core.py", line 555, in invoke
return callback(*args, **kwargs)
File "c:\MyProjectPath\api\venv\lib\site-packages\flask\cli.py", line 771, in run_command
threaded=with_threads, ssl_context=cert)
File "c:\MyProjectPath\api\venv\lib\site-packages\werkzeug\serving.py", line 812, in run_simple
reloader_type)
File "c:\MyProjectPath\api\venv\lib\site-packages\werkzeug\_reloader.py", line 267, in run_with_reloader
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
File "c:\appdata\local\programs\python\python37\Lib\signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
The problem you are facing has to do with a bug in the Flask-SocketIO package which replaces the flask run command. Due to this Flask-SocketIO is always used even if you don’t import it. There are several solutions:
Uninstall Flask-SocketIO
Do not use flask run but run the main file of your program
Disable debugging
Disable auto loading if debugging required flask run --no-reload
Reference to the Flask-SocketIO bug: issue 817
I solved the problem thanks to #AkshayKumar007 answer on github. That was the most convenient solution for me.
Hey guys, I was also facing the same problem. So to summarize, if
you're using socket-io, don't do flask run. First, add
if __name__ == "__main__":
socketio.run(app)
At the end of your application. To run it just do
python3 __init__.py
Hope it helped.
I am running this python code where I am trying to run a socketio flask application and passing ssl certificate files:
from flask import Flask, render_template, request, session, Markup, current_app, jsonify
from flask_socketio import emit, SocketIO
import eventlet
from flask_babel import gettext
app = Flask(__name__)
app.config['SECRET_KEY'] = '123'
app.config['FILEDIR'] = 'static/_files/'
socketio = SocketIO(app)
if __name__ == '__main__':
try:
app_host = os.environ.get('APP_HOST')
app_port = os.environ.get('APP_PORT')
eventlet.wsgi.server(eventlet.wrap_ssl(eventlet.listen((app_host, int(app_port))),certfile ='selfsigned.crt', keyfile = 'selfsigned.key',server_side = True),app)
except Exception as e:
logger.error(e)
When I run this code it throws following SSL error:
(21755) wsgi starting up on https://12.34.56.78:5000
(21755) accepted ('12.34.56.79', 50021)
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/eventlet/hubs/hub.py", line 458, in fire_timers
timer()
File "/usr/local/lib/python3.6/site-packages/eventlet/hubs/timer.py", line 58, in __call__
cb(*args, **kw)
File "/usr/local/lib/python3.6/site-packages/eventlet/greenthread.py", line 218, in main
result = function(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 781, in process_request
proto.__init__(conn_state, self)
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 335, in __init__
self.handle()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 368, in handle
self.handle_one_request()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 397, in handle_one_request
self.raw_requestline = self._read_request_line()
File "/usr/local/lib/python3.6/site-packages/eventlet/wsgi.py", line 380, in _read_request_line
return self.rfile.readline(self.server.url_length_limit)
File "/usr/local/lib/python3.6/socket.py", line 586, in readinto
return self._sock.recv_into(b)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 204, in recv_into
return self._base_recv(nbytes, flags, into=True, buffer_=buffer)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 225, in _base_recv
read = self.read(nbytes, buffer_)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 139, in read
super(GreenSSLSocket, self).read, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/eventlet/green/ssl.py", line 113, in _call_trampolining
return func(*a, **kw)
File "/usr/local/lib/python3.6/ssl.py", line 871, in read
return self._sslobj.read(len, buffer)
File "/usr/local/lib/python3.6/ssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:2217)
What I want is that this app should run over https connection but this error is preventing it from running. Below are my python and package version details:
python 3.6.3
eventlet==0.22.1
Flask==0.12.2
Flask-SocketIO==2.9.3
It seems that the request that has been made to the server is using http instead of https. You have to make sure that the client is also making a request using the same https protocol as the server. For example in you client code, you have to make a request to https://<server-ip> instead of http://<server-ip>