Giter Club home page Giter Club logo

flasky's Introduction

Flasky

This repository contains the source code examples for the second edition of my O'Reilly book Flask Web Development.

The commits and tags in this repository were carefully created to match the sequence in which concepts are presented in the book. Please read the section titled "How to Work with the Example Code" in the book's preface for instructions.

For Readers of the First Edition of the Book

The code examples for the first edition of the book were moved to a different repository: https://github.com/miguelgrinberg/flasky-first-edition.

flasky's People

Contributors

miguelgrinberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flasky's Issues

"sqlalchemy.exc.OperationalError"

So I am reading the book and coding and coding it at the same time and look at the clones sometimes. So now I'm creating a user to try out the current_user.is_authenticated() in chapter 8 to see if does it shows that I am logged in or not. When I try to sign it with the user that I have created through the shell i get the following error

sqlalchemy.exc.OperationalError

OperationalError: (OperationalError) no such table: users u'SELECT users.id AS users_id, users.email AS users_email, users.username AS users_username, users.password_hash AS users_password_hash, users.role_id AS users_role_id \nFROM users \nWHERE users.email = ?\n LIMIT ? OFFSET ?' (u'[email protected]', 1, 0)

and this error from the traceback

File "/home/cycrups/Desktop/Flask/asghaal/app/auth/views.py", line 11, in login

user = User.query.filter_by(email=form.email.data).first()

Any idea where I might went wrong?

Flasky flash message problem

To replicate the problem in Flasky:

Enter wrong login credentials, message "Invalid username or password." should appear.
On browser, press "back" and "forward", same message should be there.

Any idea on how to fix this? Thanks!

A potential problem in api auth code

Hello Miguel.

In https://github.com/miguelgrinberg/flasky/blob/master/app/api_1_0/authentication.py, in the verify_password(email_or_token, password) function, g.current_user is getting set before getting the verification of the password provided :

if not user:
    return False
g.current_user = user
g.token_used = False
return user.verify_password(password)

It may be better if it was this way :

if not user or not user.verify_password(password):
    return False
g.current_user = user
g.token_used = False
return True

What do you think?

Thank you for your amazing book. Learning a lot!

Possible enhancement?

Hi Miguel,

I'm following along the tutorial and having a good time so far. I just wanted to mention a problem that I only just resolved. It may seem obvious, but I was having the hardest time trying to get to what would be shown in tag 3e, and the stack trace wasn't very clear to me. It occurred to me after an embarrassing while that I had to re-run hello.py in order to actually import Moment and get the datetime stuff working. I wonder if you would consider, at least in the beginning of the book, adding a few more gentle reminders about the need to do such things.

db.session.add(..) but without commit(()

Hi, i'm reading your book and at this point in Chapter 10. In model.py the "User" class has several db.session.add(self) but no db.session.commit(). I thought that every time an update in database there should be an commit() in the end but your code works fine. So i'm a little confused. Thank you for your patient.

15d: Selenium causes Firefox to launch, but does not visit URLs

I have checked out 15d, run python manage.py db upgrade, and pip install -r requirements/dev.txt prior to initiating the python manage.py test command. The latter causes the tests to run, and upon reaching the Selenium tests Firefox launches. However, a blank tab is all that results. The tests appear to hang in the terminal until the test_admin_home_page (test_selenium.SeleniumTestCase) ... skipped 'Web browser not available' error is thrown. This is the only test that throws an error.

Some cursory googling shows this may be a a Selenium defect, but I do not know how to adjust the Flasky code to rectify it.

I'm using Firefox 36.0.1 on OS X.

Issue with reconciling databases

Hi,

I've reached the end of Chapter 7. I noticed that when I attempt to submit a new name in the web form, I get this error:
OperationalError: (OperationalError) no such table: users u'SELECT users.id AS users_id, users.username AS users_username, users.role_id AS users_role_id \nFROM users \nWHERE users.username = ?\n LIMIT ? OFFSET ?' (u'new', 1, 0)

My data.sqlite database created by hello.py contains the roles and users tables, but naïvely running $ python manage.py runserver --host 0.0.0.0 seems to create data-dev.sqlite but not populate it with any tables, which I'm hoping is the sole cause of the error. I am just confused about how to apply the earlier instructions re: migrating to make the dev database a mirror of the original database.

unittest fails

@miguelgrinberg Hi Miguel, I am working through your book. I love it. Very clear and great didactics. Unfortunately, one of the unittest fails. I am running Windows 7 and Python 2.7.8. (myvenv is a batch-file that activates the venv and sets the environment variables.)

Here is what I did:

> git clone https://github.com/miguelgrinberg/flasky.git
> cd flasky
> virtualenv venv
> git checkout 8h
> myvenv
> pip install -r requirements.txt
> python manage.py db upgrade
> python manage.py test 2> error.log

Here is the error.log

test_app_exists (test_basics.BasicsTestCase) ... ok
test_app_is_testing (test_basics.BasicsTestCase) ... ok
test_duplicate_email_change_token (test_user_model.UserModelTestCase) ... ok
test_expired_confirmation_token (test_user_model.UserModelTestCase) ... ok
test_invalid_confirmation_token (test_user_model.UserModelTestCase) ... ok
test_invalid_email_change_token (test_user_model.UserModelTestCase) ... ok
test_invalid_reset_token (test_user_model.UserModelTestCase) ... ERROR
test_no_password_getter (test_user_model.UserModelTestCase) ... ok
test_password_salts_are_random (test_user_model.UserModelTestCase) ... ok
test_password_setter (test_user_model.UserModelTestCase) ... ok
test_password_verification (test_user_model.UserModelTestCase) ... ok
test_valid_confirmation_token (test_user_model.UserModelTestCase) ... ok
test_valid_email_change_token (test_user_model.UserModelTestCase) ... ok
test_valid_reset_token (test_user_model.UserModelTestCase) ... ok

======================================================================
ERROR: test_invalid_reset_token (test_user_model.UserModelTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "d:\flasky\tests\test_user_model.py", line 78, in test_invalid_reset_token
    self.assertTrue(u2.verify_password('dog'))
  File "d:\flasky\app\models.py", line 36, in verify_password
    return check_password_hash(self.password_hash, password)
  File "d:\flasky\venv\lib\site-packages\werkzeug\security.py", line 224, in check_password_hash
    return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval)
  File "d:\flasky\venv\lib\site-packages\werkzeug\security.py", line 117, in safe_str_cmp
    return _builtin_safe_str_cmp(a, b)
TypeError: 'unicode' does not have the buffer interface

----------------------------------------------------------------------
Ran 14 tests in 7.625s

FAILED (errors=1)

Any help? Thanks a lot.

SQLAlchemy error when adding users

When running the dev server at git tag '14a' (or later) I encounter the following error when adding a new User into the db:

sqlalchemy.exc.StatementError: utcnow() takes no arguments (1 given) (original cause: TypeError: utcnow() takes no arguments (1 given))

I'm using Python 3.4. According to http://stackoverflow.com/questions/22481905/sqlalchemy-python-3-default-column-value this is a known issue.

What version of Python should I be using for the flasky app?

Many thanks in advance.

Chapter 14 - User.to_json()

Good morning, Miguel! )

app/models.py line:244 14a checkout

json_user = {
    'url': url_for('api.get_post', id=self.id, _external=True),

Maybe endpoint must be 'api.get_user'?
Thanks!

3b errors?

Hi, I think there's an issue with 3b - browsing to the user page doesn't work for me.

Example 12-11 … add_self_follows():

I get TypeError: an integer is required when trying to run add_self_follows().
First steps taken:

(flask) $ git checkout 12e
(flask) $ pip install -r requirements/dev.txt
(flask) $ python manage.py db upgrade 

I receive the following Traceback:

(flask) $ python manage.py shell
>>> User.add_self_follows()

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "~/flasky/app/models.py", line 112, in add_self_follows
     for user in User.query.all():
  File "~/flasky/flask/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2241, in all
return list(self)
  File "~/flasky/flask/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 72, in instances
rows = [process[0](row, None) for row in fetch]
  File "~/flasky/flask/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 476, in     _instance
    populate_state(state, dict_, row, isnew, attrs)
  File "~/flasky/flask/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 305, in     populate_state
    populator(state, dict_, row)
 File "~/flasky/flask/lib/python2.7/site-packages/sqlalchemy/orm/strategies.py", line 151, in fetch_col
    dict_[key] = row[col]
TypeError: an integer is required

Any insight as to what I'm missing?

An encode error occur in Chapter11.3.1 if user.email is Null.

After execute command Post.generate_fake(100)in the chapter 11.3.1, an encode error occur like below:

  File "/flask/app/templates/base.html", line 62, in block "content"
    {% block page_content %}{% endblock %}
  File "/flask/app/templates/index.html", line 15, in block "page_content"
    {% include '_posts.html' %}
  File "/flask/app/templates/_posts.html", line 6, in top-level template code
    <img class="img-rounded profile-thumbnail" src="{{ post.author.gravatar(size=40) }}">
  File "/flask/app/models.py", line 183, in gravatar
    self.email.encode('utf-8')).hexdigest()
AttributeError: 'NoneType' object has no attribute 'encode'

After the git checkout 11c, there is no column named 'user.email' in data-dev.sqlite.
After executing the python manage.py db upgrade command, 'user.email' field of exiting data should be filled with Null, and this will cause an error on line self.email.encode('utf-8')).hexdigest() when generating the Gravatar URL.

What should we do about this issue, set user.email NOT NULL or just do some extra check on gravatar() of app/models.py?

Categories for posts

So I am trying to add a category model for the posts by doing the following:

class Post(db.Model):
    __tablename__ = 'posts'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80))
    body = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    body_html = db.Column(db.Text)
    comments = db.relationship('Comment', backref='post', lazy='dynamic')

    category_id =db.Column(db.Integer, db.ForeignKey('category.category_id'))
    category = db.relationship('Category')

    def __init__(self, title, category):
        self.title = title
        self.category = category


    @staticmethod
    def on_changed_body(target, value, oldvalue, initiator):
        allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blackquote', 'code', 'em', 'i', 'li', 'ol', 'pre', 'strong',
                        'ul', 'h1', 'h2', 'h3', 'p']
        target.body_html = bleach.linkify(bleach.clean(
            markdown(value, output_form='html'),
            tags=allowed_tags, strip=True))

    def __repr__(self):
        return '<Category %r>' % self.id

db.event.listen(Post.body, 'set', Post.on_changed_body)

First question am I doing it right? To my guess it's one-to-many since it's one category for many posts. And if I do the following I get errors on main/views.py

 post = Post(body=form.body.data,
                    author=current_user._get_current_object())

The error (using Pycharm IDE) for "body=form.body.data,
author=current_user._get_current_object()" is Unexpected argument.

Any ideas what's the right way?

Trying to add new tables in the models file

I was trying to add new functions in flasky. First, I added tables in models file, and used db upgrade command to create database. Then I did some operations on new tables in shell, but failed. I got an "OperationalError: (OperationalError) no such table" error. Why does the new tables not exist in database? I can do operation on Role, User..., the error occurs when I tried to do query operation on tables I add.

url_for()

I think return redirect(url_for('main.index')) should be correct instead of return redirect('main.index') here?

And further, the /login view could could be extended by the following code:

@auth.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated():
        return redirect(url_for('main.index'))
    form = LoginForm()
    ... 

The successfully logged-in user should not be able to see the login forms again? I don't know, what do you think?

CSRF token missing

I run the application with $ python manage.py runserver,
I can't login becuase of CSRF token missing,
can someone tell me how to fix it properly, thanks in advance.

and when I run the test code
there is one test fail - test_comments (test_api.APITestCase) ... FAIL

FAIL: test_comments (test_api.APITestCase)
Traceback (most recent call last):
File "/Users/guangbo/Sites/flasky/tests/test_api.py", line 217, in test_comments
'Good < a rel="nofollow" href="http://example.com" >post< /a >!')
AssertionError: False is not true

TypeError: 'unicode' does not have the buffer interface

I'm attempting to use this repo for the first time as I work through the book. I run into an error when trying to log in, after creating a user. I've tried going through the new user registration flow within the app (though I don't have gmail configured) and also tried adding a user as the book describes in chapter eight:

$ ./manage.py shell
>>> u = User(email='[email protected]', username='john', password='cat')
>>> db.session.add(u)
>>> db.session.commit()

From the terminal, the error shows as:

 $ ./manage.py runserver
 * Running on http://127.0.0.1:5000/
 * Restarting with reloader
127.0.0.1 - - [04/Jul/2014 19:08:05] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [04/Jul/2014 19:08:06] "GET /auth/login HTTP/1.1" 200 -
127.0.0.1 - - [04/Jul/2014 19:08:17] "POST /auth/login HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/caleb/dev/flasky/app/auth/views.py", line 13, in login
    if user is not None and user.verify_password(form.password.data):
  File "/home/caleb/dev/flasky/app/models.py", line 33, in verify_password
    return check_password_hash(self.password_hash, password)
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/werkzeug/security.py", line 224, in check_password_hash
    return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval)
  File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/werkzeug/security.py", line 117, in safe_str_cmp
    return _builtin_safe_str_cmp(a, b)
TypeError: 'unicode' does not have the buffer interface

The full error on the app itself is:

TypeError
TypeError: 'unicode' does not have the buffer interface

Traceback (most recent call last)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/caleb/dev/flasky/app/auth/views.py", line 13, in login
if user is not None and user.verify_password(form.password.data):
File "/home/caleb/dev/flasky/app/models.py", line 33, in verify_password
return check_password_hash(self.password_hash, password)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/werkzeug/security.py", line 224, in check_password_hash
return safe_str_cmp(_hash_internal(method, salt, password)[0], hashval)
File "/home/caleb/.virtualenvs/flasky/lib/python2.7/site-packages/werkzeug/security.py", line 117, in safe_str_cmp
return _builtin_safe_str_cmp(a, b)
TypeError: 'unicode' does not have the buffer interface
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.

Default config and test command

With the setup flasky is using, the default config is applied and an application is created using it, before another app is created using the testing config. What ways are there to avoid this? I am looking to either delete everything that has happened before create_app in unit tests, or change the initialization process. A simple solution would be to move the app = create_app(os.getenv('FLASK_CONFIG') or 'default') manager = Manager(app) code inside a manager command, but that is not possible..

TypeError: 'unicode' does not have the buffer interface

I run the final edition and when I log in it raise

TypeError: 'unicode' does not have the buffer interface

It seems that

return check_password_hash(self.password_hash, password)

a is str and b is unicode, I'm not sure what to do.

Some posts and comments get lost on Heroku

Hi Miguel, I have a problem when Flasky is deployed on Heroku. Some posts and comments simply get lost. They don't get returned to the homepage and they don't make it into the database.

Locally, the app runs without fault. I'm using Postgres both locally and on Heroku. Do you have any idea where the problem may lie? Is Heroku's SSL redirect prone to failure, perhaps when under high load?

Btw, I have to say, I really enjoyed the book. Thank you!

Possible issue with Flask-Mail Code

Hello,

I am following the chapter 6 on Email integration and everytime I try to send email using the code provided in the book I get following exception SMTPException: SMTP AUTH extension not supported by server.. I looked on the web and found a solution here http://flask.pocoo.org/snippets/85/. The difference is in the Flask-Mail gmail configuration.

BuildError: ('main.index', {}, None)

the code in app/auth/views.py is
if user is not None and user.verify_password(form.password.data):
login_user(user,form.remember_me.data);
return redirect(request.args.get('next') or url_for('main.index'));

the code in app/main/views.py is
@main.route('/',methods=['GET','POST'])
def index():
form = NameForm();
if form.validate_on_submit():
return redirect(url_for('.index'))
return render_template('index.html',form=form,name=session.get('name'),known=session.get('known',False),current_time=datetime.utcnow());

the tree of flask is
../flaskr/
├── app
│   ├── auth
│   │   ├── forms.py
│   │   ├── forms.pyc
│   │   ├── init.py
│   │   ├── init.pyc
│   │   ├── views.py
│   │   └── views.pyc
│   ├── init.py
│   ├── init.pyc
│   ├── main
│   │   ├── errors.py
│   │   ├── init.py
│   │   └── views.py
│   ├── models.py
│   ├── models.pyc
│   └── templates
│   ├── auth
│   │   └── login.html
│   ├── base.html
│   └── index.html

Chapter 8 static files

I believe the references to jquery and bootstrap should be moved from flasky/static to flasky/app/static.

Error in app/auth/views.py on 9a

I've been following these examples in the pre-release of the book and noticed when playing at stage 9a that the password reset wasn't including the username in the email.

However, after changing line 112 in app/auth/views.py from user=current_user to user=user the issue was rectified.

I'm assuming that current_user is empty since the password reset is issued to a user not logged in, and current_user is then anonymous.

I would have submitted my changes via Github but I'm a complete git newb so raising an issue instead!

I want get username from session instead of parameter what is in url

@main.route('/about')
def user():
     return '<h1>Hello,%s</h1>' %user.email;

@main.route('/about/<username>')
def user(username):
    user = User.query.filter_by(username=username).first();
    return '<h1>Hello,%s</h1>' %user.email;

can I get username from session or browser cookie?So I can set route concise. What should I do?

Chapter 11a,b checkout- "what's on your mind"

Hello-everything(minus the smtp error for mail) was working until Chapter 11. It is not pulling the HTML for the blog post box, for some reason. I've reset and updated database, et al, but have as yet to get it to come up. I also checked line my line the code as in the book and everything is there. I did skip forward and implemented the forgery.py examples and it worked, but the box below my username still does not show. Please advise. Thank you!

flasky

Selenium and flask server

I don't know it this is my specific problem.

In the file:
https://github.com/miguelgrinberg/flasky/blob/master/tests/test_selenium.py

You have a line:
threading.Thread(target=cls.app.run).start()

This raise below exception in my test.
File "/usr/share/python3.3/threading.py", line 901, in _bootstrap_inner
self.run()
File "/usr/share/python3.3/threading.py", line 858, in run
self._target(_self._args, *_self._kwargs)
File "/home/.../env/share/python3.3/site-packages/flask/app.py", line 772, in run
run_simple(host, port, self, **options)
File "/home/.../env/share/python3.3/site-packages/werkzeug/serving.py", line 708, in run_simple
run_with_reloader(inner, extra_files, reloader_interval)
File "/home/.../env/share/python3.3/site-packages/werkzeug/serving.py", line 609, in run_with_reloader
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
ValueError: signal only works in main thread

So I had to change that lines to:
kwargs = dict(use_reloader=False)
threading.Thread(target=cls.app.run, kwargs=kwargs).start()

Because use_reloader is set to True as default.

Env:
PLD Linux + pyenv + python3.3
Flask==0.10.1
Flask-Babel==0.9
Flask-Script==2.0.5
Jinja2==2.7.3
MarkupSafe==0.23
Werkzeug==0.9.6
itsdangerous==0.24
pytz==2014.4
speaklater==1.3

Possible issue with importing environment from .env

Hello!

Not sure this is suitable for creating an issue, but I thought this might interest other people using flasky and/or your book.

I keep forgetting to set those private environment variables, so I initially created an export.sh script that exports all I need. Then I noticed the code below in config.py:

if os.path.exists('.env'):
    print('Importing environment from .env...')
    for line in open('.env'):
        var = line.strip().split('=')
        if len(var) == 2:
            os.environ[var[0]] = var[1]

I thought I would try to re-use that,so I created a .env file with the variables I need, but I'm having some issues with it.
When starting the app, I see the line "Importing environment from .env..." appear twice. Is that expected?

(flasky) $ ./manage.py runserver
Importing environment from .env...
* Running on http://127.0.0.1:5000/
* Restarting with reloader
Importing environment from .env...

Also, though I defined the *DATABASE_URL to use postgres in the .env, it still uses sqlite. So am I doing something wrong? Are these only certain variables that can be set in the .env file?

issue with auth.unconfirmed redirect

Hi!

I have some troubles with using code from example:

@auth.before_app_request
def before_request():
    if current_user.is_authenticated():
        current_user.ping()
        if not current_user.confirmed \
                and request.endpoint[:5] != 'auth.':
            return redirect(url_for('auth.unconfirmed'))


@auth.route('/unconfirmed')
def unconfirmed():
    if current_user.is_anonymous() or current_user.confirmed:
        return redirect(url_for('main.index'))
    return render_template('auth/unconfirmed.html')

while I'm logging in as confirmed user, everything is fine
but if i login as unconfirmed, unconfirmed.html is never shown

It looks like 'before_request()' captures requests for 'auth. unconfirmed' and this makes impossible to show this page to unconfirmed users (the go for main page).

Or .. May be I missed something?

Generate fake users and posts (11c)

User.generate_fake(100)
Post.generate_fake(100)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'Post' is not defined
wrong

What's wrong maybe?Thanks!

Question about advanced API design

What is the best way to design the API so that it can be used by both the client and the server? My view methods are getting cluttered and I was thinking a lot of my logic should be moved into the the API.

I changed the existing flasky API blueprint so that it acts like a thin middleman.

@api.route('/posts/<int:id>')
def get_post(id):
    return apiLogic.get_post(id)

I did this with the assumption that if I needed to access a post from the client-side I could use jQuery to send an HTTP request to the endpoint /posts/<int:id>. Additionally, if I wanted to render a page server side I could directly call apiLogic.get_post(id).

However, calling apiLogic.get_post(id) directly from a separate blueprint means I lose the permission-checking logic from blueprint_before_request. Would it be poor design to issue HTTP requests from the backend onto itself to get around this problem?

Perhaps I'm thinking about API design in flask incorrectly, do you have any advice?

3a templates

On the example of 3a and 3b (maybe onwards since I stopped there), the hello.py file doesn't include the correct directory of the templates.

Currently
screen shot 2014-08-06 at 9 53 03 pm

but it should be
screen shot 2014-08-06 at 9 53 36 pm

Where would you add Whoosh Indexes?

I'm trying to add fulltext search with Flask-Whoosh and I added searchable but when I try to use .whoose_search I get an error and saw this issue.
gyllstromk/Flask-WhooshAlchemy#13

So I assume I need to add the indexes but where do I add them?

I added the following to manage.py but I get a RuntimeError

from flask.ext.migrate import Migrate, MigrateCommand
import flask.ext.whooshalchemy as whooshalchemy

app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)
whooshalchemy.whoosh_index(app, Post)

raise RuntimeError('application not registered on db ' RuntimeError: application not registered on db instance and no application bound to current context

Heroku push rejected

I am sorry this is the third time I am posting an issue here for you to help me, but after I tried many many 'solutions' i found around the web my problem wouldn't be fixed.
So I am trying to deploy the app with git push. Git respository is already commited and works just fine, but when I get to the git push heroku master I start getting an error about no Cedar-supported...

$ heroku buildpacks:set git://github.com/heroku/heroku-buildpack-python.git
Buildpack set. Next release on esouqbahrain will use git://github.com/heroku/heroku-buildpack-python.git.
Run `git push heroku master` to create a new release using this buildpack.

$ git push heroku master
Counting objects: 3849, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3653/3653), done.
Writing objects: 100% (3849/3849), 12.73 MiB | 2.23 MiB/s, done.
Total 3849 (delta 1409), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Fetching custom git buildpack... done
remote: 
remote:  !     Push rejected, no Cedar-supported app detected
remote: HINT: This occurs when Heroku cannot detect the buildpack
remote:       to use for this application automatically.
remote: See https://devcenter.heroku.com/articles/buildpacks
remote: 
remote: Verifying deploy.....
remote: 
remote: !       Push rejected to esouqbahrain.
remote: 
To https://git.heroku.com/esouqbahrain.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/esouqbahrain.git'

Any idea for the fix? Thank you in advance

Some improvement suggestions

Thanks for great Flask examples. I have some minor improvement suggestions:

  • The foreign keys could use ondelete='CASCADE' constraints, thus leading to much faster deletion
  • Password column could use PasswordType of SQLAlchemy-Utils
  • The project could use Flask-Gravatar
  • Model jsonifying could happen outside of model in order to fully separate these concerns. The serialization could use the wonderful Marshmallow library
  • Lot of model / view functionality could be moved to a separate service layer (in order to avoid the bloated model problem)
  • The validations should be stricter, providing for example a name for user which is more than 64 chars will result in database errors. This could be easily done using WTForms-Alchemy
  • page = int(request.args.get('page', 1)) -> page = request.args.get('page', 1, type=int) to avoid errors in case user provides non integer page parameter

Unicode issue.

Hi, I have a problem when deploy the app in production when connecting with MySQL db.

Here is how i did it:

  • First i enter MySQL REPL create a new database called "mydatabase"
  • Here is my code:
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand

app = Flask(__name__, static_path='/static')

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:password@localhost/mydatabase?charset=utf8'

db = SQLAlchemy(app)
from views import *
from models import *
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)


if __name__ == '__main__':
    manager.run()

Here is what looks like in my models.py:

from run import db, app

class Table1(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.Unicode(256))
  • Then i delete /migrates folder which i use sqlite as database in development and run
    python run.py db init
    python run.py db migrate
    python run.py db upgrade
    Everything looks normal.

  • However when test in production, there are some encoding issue, for instance, when i save english words to test_1.name(test_1 is an instance of Table1), it shows correctly. However when i save test_1.name to some Unicode characters, it shows "??????". Here is what is shows in python interpreter:

    test_1 = Table1.query.filter_by(id=1).first()
    test_1.name
    u'?????'

How can i deal with such situation? Thank you.

Chapter 7 Large Application Structure

I checkout 7a and then I execute this command: ./manage.py runserver --host 0.0.0.0
There is an error:

Traceback (most recent call last):
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/qinf/flasky/app/main/views.py", line 13, in index
    user = User.query.filter_by(username=form.name.data).first()
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2367, in first
    ret = list(self[0:1])
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2228, in __getitem__
    return list(res)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2438, in __iter__
    return self._execute_and_instances(context)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2453, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 729, in execute
    return meth(self, multiparams, params)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 322, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 826, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 958, in _execute_context
    context)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1159, in _handle_dbapi_exception
    exc_info
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 199, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 951, in _execute_context
    context)
  File "/home/qinf/test_flask/venv/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 436, in do_execute
    cursor.execute(statement, parameters)
OperationalError: (OperationalError) no such table: users u'SELECT users.id AS users_id, users.username AS users_username, users.role_id AS users_role_id \nFROM users \nWHERE users.username = ?\n LIMIT ? OFFSET ?' (u'test', 1, 0)

It is an error with the database. It says it has no the table 'users'.
The code in the directory are:
qq20150111232901

I guess I did not create the database.
Is the command I run before is wrong?(command: ./manage.py runserver --host 0.0.0.0)

Chapter 8 - Protecting Routes

where I could add this code ?

from flask.ext.login import login_required

@app.route('/secret')
@login_required
def secret():
return 'Only authenticated users are allowed!'

Chapter 6 - Email

I checkout 6b, and I want to send an email for test.But it raised an exception. I use virtual machine(CentOS 7). The exception as follows:

(venv)➜  flasky git:(09d4ff0) ✗ python hello.py runserver --host 0.0.0.0
 * Running on http://0.0.0.0:5000/
192.168.182.1 - - [10/Jan/2015 22:03:06] "GET / HTTP/1.1" 200 -
192.168.182.1 - - [10/Jan/2015 22:03:10] "POST / HTTP/1.1" 302 -
192.168.182.1 - - [10/Jan/2015 22:03:10] "GET / HTTP/1.1" 200 -
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
    self.run()
  File "/usr/lib64/python2.7/threading.py", line 764, in run
    self.__target(*self.__args, **self.__kwargs)
  File "hello.py", line 63, in send_async_email
    mail.send(msg)
  File "/home/qinf/flasky/venv/lib/python2.7/site-packages/flask_mail.py", line 491, in send
    with self.connect() as connection:
  File "/home/qinf/flasky/venv/lib/python2.7/site-packages/flask_mail.py", line 144, in __enter__
    self.host = self.configure_host()
  File "/home/qinf/flasky/venv/lib/python2.7/site-packages/flask_mail.py", line 158, in configure_host
    host = smtplib.SMTP(self.mail.server, self.mail.port)
  File "/usr/lib64/python2.7/smtplib.py", line 250, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/lib64/python2.7/smtplib.py", line 311, in connect
    (code, msg) = self.getreply()
  File "/usr/lib64/python2.7/smtplib.py", line 362, in getreply
    raise SMTPServerDisconnected("Connection unexpectedly closed")
SMTPServerDisconnected: Connection unexpectedly closed

I use local ip, but i can connect with the internet. I changed some configurations: mail, port, username, password. The hello.py as fllow:

import os
from threading import Thread
from flask import Flask, render_template, session, redirect, url_for
from flask.ext.script import Manager, Shell
from flask.ext.bootstrap import Bootstrap
from flask.ext.moment import Moment
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.mail import Mail, Message

basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
app.config['SQLALCHEMY_DATABASE_URI'] =\
    'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['MAIL_SERVER'] = 'smtp.163.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_TLS'] = True
#app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME')
#app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD')
app.config['MAIL_USERNAME'] = mail
app.config['MAIL_PASSWORD'] = password
app.config['FLASKY_MAIL_SUBJECT_PREFIX'] = '[Flasky]'
app.config['FLASKY_MAIL_SENDER'] = 'Flasky Admin <[email protected]>'
#app.config['FLASKY_ADMIN'] = os.environ.get('FLASKY_ADMIN')
app.config['FLASKY_ADMIN'] = another_mail

manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
mail = Mail(app)


class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    users = db.relationship('User', backref='role', lazy='dynamic')

    def __repr__(self):
        return '<Role %r>' % self.name


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    def __repr__(self):
        return '<User %r>' % self.username


def send_async_email(app, msg):
    with app.app_context():
        mail.send(msg)


def send_email(to, subject, template, **kwargs):
    msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject,
                  sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.html', **kwargs)
    thr = Thread(target=send_async_email, args=[app, msg])
    thr.start()
    return thr


class NameForm(Form):
    name = StringField('What is your name?', validators=[Required()])
    submit = SubmitField('Submit')


def make_shell_context():
    return dict(app=app, db=db, User=User, Role=Role)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)


@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500


@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.name.data).first()
        if user is None:
            user = User(username=form.name.data)
            db.session.add(user)
            session['known'] = False
            if app.config['FLASKY_ADMIN']:
                send_email(app.config['FLASKY_ADMIN'], 'New User',
                           'mail/new_user', user=user)
        else:
            session['known'] = True
        session['name'] = form.name.data
        return redirect(url_for('index'))
    return render_template('index.html', form=form, name=session.get('name'),
                           known=session.get('known', False))


if __name__ == '__main__':
    manager.run()

I did not find where the problem is. Thank you for your patience.

How could I update chinese language(like 我) to MySQL

@main.route('/edit-about',methods=['GET','POST'])
@login_required
def edit_about():
    form = EditAboutForm();
    if form.validate_on_submit():
        current_user.about_me = form.about_me.data;
        try:
            db.session.add(current_user);
        flash('Your about has been updated');
    form.about_me.data = current_user.about_me;
    return render_template('edit_about.html',form=form)

The error is like this.
OperationalError: (OperationalError) (1366, "Incorrect string value: '\xE6\x88\x91' for column 'about_me' at row 1") 'UPDATE users SET about_me=%s, about_me_html=%s WHERE users.id = %s' ('\xe6\x88\x91', '

\xe6\x88\x91

', 1L)

Is SQLite support Chinese.But MySQL doesn't?

Missing database when cloning the repo.

If you clone the repo and try to run python manage.py runserver the application does not run because the database is missing. I know that the tutorial is meant to be run in a sequence, but I guess it wouldn't hurt if you had something like this in create_app():

def create_app():
        db.init_app(app)
        with app.app_context():
            #Extensions like Flask-SQLAlchemy now know what the "current" app
            #is while within this block. 
            db.create_all()

Taken from here

Can't create db

Dear Miguel,

thanks you for your book,

I have some troubles, I am on chapter 8a.

I can't create a db, db init, db downgrade etc - it's ok,
but when I start a server and add some text to form - I have this error:

sqlalchemy.exc.OperationalError

OperationalError: (OperationalError) no such table: users u'SELECT users.id AS users_id, users.username AS users_username, users.role_id AS users_role_id, users.password_hash AS users_password_hash \nFROM users \nWHERE users.username = ?\n LIMIT ? OFFSET ?' (u'dfh', 1, 0)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.