8: Advanced Topics

Expectations

From here on out, your project is going to vary from everyone else’s. Once your models are done, you’ve now got to build out each view and template that will serve the workflow of your MVP. Work with your teacher to identify what your MVP needs to do, (we’ll call this your requirements based off of the SRS stage of the IEEE software lifecycle). Once we work out what exactly you’re building in your module, we’ll populate your Trello backlog with loads of tasks. And as we solve those weird tasks, we’ll start to build the collection of topics below.

Learning Targets

  • I can research and hack together an MVP.

Session

Decorators

http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/

The term decorators in programming refers to a sort of flag or notice put at the start of a method to signal some sort of special treatment. We use @login_required to trigger Flask-Security’s verification that the user is carrying the encrypted token from our system given to a confirmed user. I would imagine verification of authority and privileges is the most common reason to use a decorator in Flask. We use them in Java to notify the system we’re overriding a parent’s method.

Forms

The form is our primary method of collecting information from the user. Depending on your application's need, you may need to looking closely into wtforms. Meanwhile, here are a few recipes that have been requested.

In case you forgot what a drop-down looks like?

When filling out a form, you may want to have a drop-down of a user's friends or some other set of data unique to that user. How can you provide those dynamic options within a form template?

The most typically recommended answer is the QuerySelectField.

And what if you want one drop-down to populate the options of another dropdown?

Build Options From a View

Just use a SelectField with no real options and populate them after you build the form.

https://stackoverflow.com/questions/46921823/dynamic-choices-wtforms-flask-selectfield

Placeholders

https://stackoverflow.com/questions/9749742/python-wtforms-can-i-add-a-placeholder-attribute-when-i-init-a-field

Examples:

Captcha

SQLAlchemy and Databases

backref VS back_populates

http://docs.sqlalchemy.org/en/latest/orm/backref.html#relationships-backref

Two back_populates equals one backref. Using backref declares a two-way relationship. It’s more efficient than dropping a back_populates on both ends of the relationship but I prefer it because I’ve been confused too many times staring at a class wondering about its relationships unaware that another class has declared a relationship backref in a different file.

Relationship Loading: Lazy?

http://docs.sqlalchemy.org/en/latest/orm/loading_relationships.htmlLet’s say you want to query the database for a user’s contacts with a built-in relationship such as current_user.contacts. You can get a list back from the database with just that one command. However, what if you know you’ll always need additional filters on that query. You don’t want the results quite so fast, instead you’d like the SQLAlchemy query not to complete its task but rather to keep the search open and ready for additional filtering or sorting.

Configuring Flask-Mail

https://pythonhosted.org/Flask-Mail/

This line needs to be in your settings.py:

SECURITY_EMAIL_SENDER = private.ADMIN_EMAIL

JavaScript

Confirmation Buttons

Just as we keep a custom.css file, your project should have a custom.js function. Something like this could be very handy. Now you can just add class=”confirmation” attribute to any <a></a> and it’ll have a JS-powered confirmation window.

$('.confirmation').on('click', function () {
return confirm('Are you sure?');
});

AJAX: Server Without Reloads

Actions of our app are triggered by routes in our view. If you type in the url of your site, /index, your browser sends a GET request to that route to the homepage route in your app. Your browser loads the page. But what if you want to avoid refreshing the page? What if you want to send a message from a modal window and press submit without losing your spot on the current page?

Passing Variables from Flask to JavaScript

Calling a JavaScript Method on a Button

<a onclick="hidePaidBills()" href="javascript:void(0);" data-toggle="tooltip" data-placement="top" title="hide paid"><i class="fa fa-eye"></i></a>

// HIDE PAID BILLS
function hidePaidBills(){
$('.bill-paid').each(function() {
$(this).hide();
})

Sending SMS Messages with Twillio

https://www.twilio.com/docs/sms/quickstart/python

Updating Dependencies

We use VirtualEnv as a sort of bubble that contains our version of Python, Flask, and all the many other libraries used. Each library is likely to see improvements and security fixes. It’s important to keep this codebase updated but it’s an awfully risky process. Updates might change how some of the libraries work and may force you to change or cause new bugs. Best practice is to keep a previous version of your requirements.txt handy and to build thorough unit tests.

Before asking pip to do a lot of work, you may want it upgrade it first: pip install --upgrade pip

Update all libraries (copied from StackOverflow)

sudo -H python3 -m pip freeze --local | grep -v '^-e' | cut -d = -f 1 | xargs -n1 sudo python3 -m pip install -U

Create a requirements document:

pip freeze > requirements.txt

Test to make sure the app works. If it doesn't, undo changes tracked by git to get you your previous version of the requirements.txt. Reinstall your dependencies based on all the previously recorded versions.

Unit Tests

http://flask.pocoo.org/docs/0.12/testing/

The most responsible way to build software is to start with unit tests. A script will mimic various types of users as they test every function on your site. The unit test will report when something acts differently than expected. I struggle with keeping to this discipline. A more sophisticated implementation of Flask’s unit test system will be the best sign of my own professional growth in this area.