EzDevInfo.com

blinker

A fast Python in-process signal/event dispatching system. Blinker Documentation — Blinker

Flask-Security user_registered Signal Not Received in Python 3.3, but works in 2.7

I'm trying to use the user_registered signal in order to set up default roles for users when they register using flask-security as in the following link: Setting Default Role in Flask Security

In my searches I can see that there was a bug that was already addressed for this in flask-security: Not getting signal from flask-security, Fix - user_registered signal problem

I've tried the following to prove if the signal is received by the handler without any luck:

@user_registered.connect_via(app)
def user_registered_sighandler(sender, **extra):
    print("print-user_registered_sighandler:", extra)

This, however, never gets called even though the user gets registered and the signal should be sent.

If it helps I've set the flask-security configuration as follows:

app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = False
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False
app.config['SECURITY_CHANGEABLE'] = True
app.config['SECURITY_SEND_PASSWORD_CHANGE_EMAIL'] = False

Signals from Flask-Login and Flask-Principal are working for me as I managed to confirm that the following code snippets successfully print when the signals are sent:

@user_logged_out.connect_via(app)
def on_user_logged_out(sender, user):
    print('USER LOG OUT: made it in',user)

@identity_changed.connect_via(app)
def identity_changed_ok(sender,identity):
    print('Identity changed:',identity)

For my setup I am using python 3.3 and using the following: Flask==0.10.1,flask-login==0.2.11,flask-principal==0.4.0,flask-security==1.7.4,blinker==1.3. Having looked at the signals in both flask-login and flask-security I'm not sure why the flask-security signals would not be working.

EDIT:

If I add print(user_registered.receivers) to a route in my app it will show that I have a receiver: {139923381372400: <function user_registered_sighandler at 0x7f42737145f0>}. If I put this same print statement within the registerable.py of flask-security just before the user_registered.send(app._get_current_object(),user=user, confirm_token=token) then it lists no receivers: {}

EDIT2:

Problem appears to be related to using python 3.3. I created a python 2.7 environment and the user_registered code worked as expected.

Full code to reproduce:

from flask import Flask,render_template
from playhouse.flask_utils import FlaskDB
import os
from flask.ext.security import Security, PeeweeUserDatastore
from flask.ext.security.signals import user_registered
from flask.ext.login import user_logged_out
from peewee import *
from playhouse.signals import Model
from flask.ext.security import UserMixin,RoleMixin

app = Flask(__name__)

app.config['ADMIN_PASSWORD']='secret'
app.config['APP_DIR']=os.path.dirname(os.path.realpath(__file__))
app.config['DATABASE']='sqliteext:///%s' % os.path.join(app.config['APP_DIR'], 'blog.db')
app.config['SECRET_KEY'] = 'shhh, secret!'
app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = False
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False

flask_db = FlaskDB()
flask_db.init_app(app)
database = flask_db.database

class BaseModel(Model):
    class Meta:
        database=flask_db.database


class User(BaseModel, UserMixin):
    email=CharField()
    password=CharField()
    active = BooleanField(default=True)
    confirmed_at = DateTimeField(null=True)

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def is_authenticated(self):
        return True


class Role(BaseModel, RoleMixin):
    name = CharField(unique=True)
    description = TextField(null=True)


class UserRoles(BaseModel):
    user = ForeignKeyField(User, related_name='roles')
    role = ForeignKeyField(Role, related_name='users')
    name = property(lambda self: self.role.name)
    description = property(lambda self: self.role.description)


user_datastore = PeeweeUserDatastore(database, User, Role, UserRoles)
security = Security(app, user_datastore)

@user_registered.connect_via(app)
def user_registered_sighandler(sender,**extra):
    print("print-user_registered_sighandler")

@user_logged_out.connect_via(app)
def on_user_logged_out(sender, user):
    print('USER LOG OUT: made it in',user)

@app.route('/')
def index():
    print(user_registered.receivers)
    return render_template('base.html')

app.run(debug=True)

base.html template:

<!doctype html>
<html>
  <head>
    <title>Blog</title>
  </head>
  <body>
          <ul>
            {% if current_user.is_authenticated() %}
              <li><a rel='nofollow' href="{{ url_for('security.logout',next='/') }}">Log out</a></li>
              <li><a rel='nofollow' href="{{ url_for('security.register') }}">Register</a></li>
        {% else %}
        <li><a rel='nofollow' href="{{ url_for('security.login',next='/') }}">Login</a></li>
        <li><a rel='nofollow' href="{{ url_for('security.register') }}">Register</a></li>
            {% endif %}
            {% block extra_header %}{% endblock %}
          </ul>
  </body>
</html>

Source: (StackOverflow)

Flask signals: why is it not ok to modify data on signal?

Flask documentations says:

Also keep in mind that signals are intended to notify subscribers and should not encourage subscribers to modify data

I am wondering, why is so?

I'm using Flask-User library, and I would like to set some default fields for user when a user registers(e.g. set displayname to be equal to username) and then update the db. Flask-User sends user_registered signal when user registers. Why is it a bad idea to subscribe to the signal, and update db in it?


Source: (StackOverflow)

Advertisements

Importing a Flask-security instance into my views module breaks my webapp

I'm writing the sign up/sign in system for a ecommerce site, and using flask-security (http://pythonhosted.org/Flask-Security/) to handle the signup feature. Part of the basic setup requires the following signup.py module:

from flask.ext.security import SQLAlchemyUserDatastore, Security
from app.models import User, Role
from app import app, db

# Setup Flask Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

I then have to import the user_datastore and security objects into my views.py module as follows:

from app.signup import user_datastore, security

The thing is, as soon as I include the above import statement into my views module, my whole app crashes, and I get the following traceback error when I try to run my unit or behavior tests (edited for readability)

======================================================================
ERROR: Failure: AttributeError ('_FakeSignal' object has no attribute 'connect_via')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/nose/loader.py", line 413, in loadTestsFromName
    addr.filename, addr.module)
  File "/Library/Python/2.7/site-packages/nose/importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/Library/Python/2.7/site-packages/nose/importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/Users/faiyamrahman/programming/Python/WebApps/NibsNWhiskeyFull/tests/test_database.py", line 6, in <module>
    from app import app, db, models
  File "/Users/faiyamrahman/programming/Python/WebApps/NibsNWhiskeyFull/app/__init__.py", line 9, in <module>
    from app import views, models
  File "/Users/faiyamrahman/programming/Python/WebApps/NibsNWhiskeyFull/app/views.py", line 7, in <module>
    from app.signup import user_datastore
  File "/Users/faiyamrahman/programming/Python/WebApps/NibsNWhiskeyFull/app/signup.py", line 7, in <module>
    security = Security(app, user_datastore)
  File "/Users/faiyamrahman/programming/Python/WebApps/NibsNWhiskeyFull/flask/lib/python2.7/site-packages/flask_security/core.py", line 346, in __init__
    self._state = self.init_app(app, datastore, **kwargs)
  File "/Users/faiyamrahman/programming/Python/WebApps/NibsNWhiskeyFull/flask/lib/python2.7/site-packages/flask_security/core.py", line 368, in init_app
    identity_loaded.connect_via(app)(_on_identity_loaded)
AttributeError: '_FakeSignal' object has no attribute 'connect_via'

I have no idea what this means. I've tried reading the flask-security documentation, but I don't understand why it's happening. Thanks to anyone who takes a stab at this!


Source: (StackOverflow)

blinker does not work in Python 2.6

import blinker
from blinker import signal

class Ticket():
    @classmethod
    def update(cls):
    pass

ticket_created = signal('CREATED')
ticket_created.connect(Ticket.update)

This snippet of code works well on Python 2.7. But does not work on Python 2.6. I get this trace:

Traceback (most recent call last):
  File "btest.py", line 10, in <module>
    ticket_created.connect(Ticket.update)
  File "/home/gavika/env2/lib/python2.6/site-packages/blinker/base.py", line 113, in connect
    receiver_ref = reference(receiver, self._cleanup_receiver)
  File "/home/gavika/env2/lib/python2.6/site-packages/blinker/_utilities.py", line 134, in reference
    weak = callable_reference(object, callback)
  File "/home/gavika/env2/lib/python2.6/site-packages/blinker/_utilities.py", line 145, in callable_reference
    return BoundMethodWeakref(target=object, on_delete=callback)
  File "/home/gavika/env2/lib/python2.6/site-packages/blinker/_saferef.py", line 143, in __new__
    base.__init__(target, on_delete, *arguments, **named)
  File "/home/gavika/env2/lib/python2.6/site-packages/blinker/_saferef.py", line 185, in __init__
    self.weak_self = weakref.ref(im_self, remove)
TypeError: cannot create weak reference to 'classobj' object

Is there a way I could get this to work in 2.6 environment?


Source: (StackOverflow)