Integrating Stripe in the Flask web framework

{ Repost from my personal blog @ https://blog.codezero.xyz/integrating-stripe-in-flask } Stripe is a developer and a user-friendly payment infrastructure provider. Stripe provides easy to use SDKs in different programming languages allowing us to easily collect payments on our website or mobile application. Flask is a web microframework for Python based on Werkzeug, Jinja 2. Flask makes building web applications in python a breeze. Make sure you have your Flask app ready. Let's start with installing the required dependency. The Stripe python SDK. You can get it by running. pip install stripe Don't forget to add the same in your requirements.txt. (if you have one that is.) Now, head over to Stripe: Register and create a new Stripe account to get your test keys. If you don't wish to create an account at this time, you can use the following test keys, but you'll not be able to see the payments in the stripe dashboard. Publishable Key: pk_test_6pRNASCoBOKtIshFeQd4XMUh Secret Key: sk_test_BQokikJOvBiI2HlWgH4olfQ2 We'll need to set the secret key in the SDK. import stripe STRIPE_PUBLISHABLE_KEY = 'pk_test_6pRNASCoBOKtIshFeQd4XMUh' STRIPE_SECRET_KEY = 'sk_test_BQokikJOvBiI2HlWgH4olfQ2' stripe.api_key = STRIPE_SECRET_KEY Let's create a page with a form for us to handle the Stripe payment. <!DOCTYPE html> <html> <head> <title>Pay now</title> </head> <body> <h4>Pay $250.00 by clicking on the button below.</h4> <form action="/payment" method="POST"> <script src="https://checkout.stripe.com/checkout.js" class="stripe-button" data-key="pk_test_6pRNASCoBOKtIshFeQd4XMUh" data-description="A payment for the Hello World project" data-name="HelloWorld.com" data-image="/images/logo/hw_project.png" data-amount="25000"></script> </form> </body> </html> We're using Stripe's Checkout library to get the payment details from the user and process. Also, keep in mind that the checkout library has to be loaded directly from https://checkout.stripe.com/checkout.js. Downloading it and serving locally will not work. The script tag, accepts a lot of parameters. A few important ones are, data-key - The Publishable Key. data-amount - The amount to be charged to the user in the lowest denomination of the currency. (For example, 5 USD should be represented as 500 cents) data-name - The name of your site or company that will be displayed to the user. data-image - The path to an image file (maybe a logo) that you'd like to be displayed to the user. More configuration options can be seen at Stripe: Detailed Checkout Guide. This script would automatically create a Pay with Card button which would open the stripe Checkout lightbox when clicked by the user. Once the payment process is completed the following parameters are submitted to the form's action endpoint (the form inside which this script is located), along with any other elements that were in the form. stripeToken - The ID of the token representing the payment details stripeEmail - The email address the user entered during the Checkout process Along with the Billing address details and Shipping address details if applicable and enabled We'll need to write a Flask method to handle the input that were submitted by Stripe to proceed with the transaction and charge the user. Let's add a new Flask route to respond when submitting the form. @app.route('/payment', methods=['POST']) def payment_proceed(): # Amount in cents amount = 25000…

Continue ReadingIntegrating Stripe in the Flask web framework

Flask-SocketIO Notifications

In the previous post I explained about configuring Flask-SocketIO, Nginx and Gunicorn. This post includes integrating Flask-SocketIO library to display notifications to users in real time. Flask Config For development we use the default web server that ships with Flask. For this, Flask-SocketIO fallsback to long-polling as its transport mechanism, instead of WebSockets. So to properly test SocketIO I wanted to work directly with Gunicorn (hence the previous post about configuring development environment). Also, not everyone needs to be bothered with the changes required to run it. class DevelopmentConfig(Config): DEVELOPMENT = True DEBUG = True # If Env Var `INTEGRATE_SOCKETIO` is set to 'true', then integrate SocketIO socketio_integration = os.environ.get('INTEGRATE_SOCKETIO') if socketio_integration == 'true': INTEGRATE_SOCKETIO = True else: INTEGRATE_SOCKETIO = False # Other stuff SocketIO is integrated (in development env) if the developer has set the INTEGRATE_SOCKETIO environment variable to "true". In Production, our application runs on Gunicorn, and SocketIO integration must always be there. Flow To send message to a particular connection (or a set of connections) Flask-SocketIO provides Rooms. The connections are made to join a room and the message is sent in the room. So to send message to a particular user we need him to join a room, and then send the message in that room. The room name needs to be unique and related to just one user. The User database Ids could be used. I decided to keep user_{id} as the room name for a user with id {id}. This information (room name) would be needed when making the user join a room, so I stored it for every user that logged in. @expose('/login/', methods=('GET', 'POST')) def login_view(self): if request.method == 'GET': # Render template if request.method == 'POST': # Take email and password from form and check if # user exists. If he does, log him in. login.login_user(user) # Store user_id in session for socketio use session['user_id'] = login.current_user.id # Redirect After the user logs in, a connection request from the client is sent to the server. With this connection request the connection handler at server makes the user join a room (based on the user_id stored previously). @socketio.on('connect', namespace='/notifs') def connect_handler(): if current_user.is_authenticated(): user_room = 'user_{}'.format(session['user_id']) join_room(user_room) emit('response', {'meta': 'WS connected'}) The client side is somewhat similar to this: <script src="{{ url_for('static', filename='path/to/socket.io-client/socket.io.js') }}"></script> <script type="text/javascript"> $(document).ready(function() { var namespace = '/notifs'; var socket = io.connect(location.protocol + "//" + location.host + namespace, {reconnection: false}); socket.on('response', function(msg) { console.log(msg.meta); // If `msg` is a notification, display it to the user. }); }); </script> Namespaces helps when making multiple connections over the same socket. So now that the user has joined a room we can send him notifications. The notification data sent to the client should be standard, so the message always has the same format. I defined a get_unread_notifs method for the User class that fetches unread notifications. class User(db.Model): # Other stuff def get_unread_notifs(self, reverse=False): """Get unread notifications with titles, humanized receiving time and Mark-as-read links. """ notifs = [] unread_notifs =…

Continue ReadingFlask-SocketIO Notifications

Programmer principles

As programmers we develop our programming skills and learn something every single day. We write code and solve many troubles. But is our aim to simply write code? I am sure it is not. I think writing code just for doing it is not interesting, and it’s definitely not Open Event team’s objective. Personally, I like reading code like a poem. We should always try to eliminate bad practises and ugly code. There are a few principles how to do it. Let me share them with you now. SOLID principle SOLID  is a mnemonic acronym introduced by Michael Feathers, and it simply means five basic principles of object oriented programming. These principles, when applied together, make it more likely that a programmer will create a system that is easy to maintain and extend over time. They are guidelines that can be applied while working on software to remove code smells by causing the programmer to refactor the software's source code.  It is also a part of an overall strategy of agile. So, here they are: S - Single responsibility principle This principle means that there should never be more than one reason for a class to change. In other words, a class should have only one potential change in a software's specification. You should not add everything into your class. The best practise here is to check if the logic you are introducing should be in this class or not. Responsibility is the heart of this principle, so to rephrase there should never be more than one responsibility per class. Use layers for a help. And try to divide big classes into smaller ones. O - Open/closed principle Software entities like classes, module and functions should be open for extension, but closed for modification. All of them should be private by default. To make an object behaving differently without modifying it use abstractions, or place behavior(responsibility) in derivative classes. If properties of the abstracted class need to be compared or organized together, another abstraction should handle this. This is the basis of the "keep all object variables private" argument. L - Liskov substitution principle Functions that use pointers or references to base classes have to be able to use objects of derived classes without knowing/alerting the correctness of a program A great example you can find here. If you are using a method defined at a base class upon an abstracted class, the function must be implemented properly on the subtype class. A great example provided here http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/  you can find below. “ A rectangle is a plane figure with four right angles. It has a width, and a height. Now, take a look at the following pseudo-code: rect = new Rectangle(); rect.width  = 10; rect.height = 20; assert 10 == rect.width assert 20 == rect.height We simply set a width and a height on a Rectangle instance, and then we assert that both properties are correct. So far, so good. Now we can improve our definition by saying that…

Continue ReadingProgrammer principles

Mark Notifications Read on Click

Notification has become a really important way of informing users about the various activities related to them in web apps. There are different types of notification such as web app notification, email notification, desktop notification, push notification, etc. We are going to primarily talk about web app notification and mainly about how to mark them as read. Create Notification Creating a notification is plain and simple. You have a json or an object which stores the notification message corresponding to a particular activity. Whenever that activity occurs in the backend, you call the send notification module, which adds the information to the database and shows it in the notification page. As simple as that. Marking Notification as Read The main functioning of this is plain and simple as well. You have a URL, which on getting a request from the user, marks the notification as read in the database. That's it. We know how to do this using a button or a link. But the question here is how to mark a notification as read on clicking any part of the notification?? The obvious answer is, well, put the entire notification inside an anchor tag and you are done, right? Well, it would work in many cases. But what if the design structure is such that this doesn't work somehow. Somehow enclosing the notification inside a particular anchor tag doesn't solve the purpose. What do we do then? Identify Whether Inside a DIV The main problem here actually is how to identify whether the click is inside the enclosing div or somewhere else. Once we solve this problem, we can send an ajax request to the mark read URL and our job is done. So, to identify that a click is indeed inside a div, we use the event.target property of the event clicked. The target event property returns the element that triggered the event. So we check whether event.target has the "notification" class in our case. If it does not have the "notification" class we check in all it's parent nodes. We get the parent nodes using the "parent()" function and check whether any of that has notification. If either of the 2 occurs, we consider that the click is inside the div. And thus mark the notification as read. So, once this is done, we mark the notification as read in the backend and our job is done...

Continue ReadingMark Notifications Read on Click

Setting up Nginx, Gunicorn and Flask-SocketIO

One of my previous posts was on User Notifications (another blog). There I discussed a possible enhancement to notifications by using WebSocket API. This week I worked on the same using Flask-SocketIO library. Its development required setting up the backend, this post is about the same. Flask-SocketIO and Gunicorn From the Flask-SocketIO page itself: Flask-SocketIO gives Flask applications access to low latency bi-directional communications between the clients and the server. On the client-side the developer is free to use any library that works on the Socket.io protocol. Flask-SocketIO needs an asynchronous service to work with and gives a choice from the three: Eventlet (eventlet.net), Gevent (gevent.org) and Flask development server. I used it with Eventlet. pip install flask-socketio pip install eventlet We were already using Gunicorn as our webserver, so integrating Eventlet only required specifying the worker class for Gunicorn. gunicorn app:app --worker-class eventlet -w 1 --bind 0.0.0.0:5000 --reload This command would start the gunicorn webserver, load the Flask app and bind it to port 5000. The worker class has to be specified as eventlet, using only one worker (-w 1). --reload option helps during development, it restarts the server if the python code changes. The problem with Gunicorn occurs when working with static files. Gunicorn is not made to serve static assests like CSS stylesheets, JS scripts, etc. It should only be used to serve requests that require the Python application. We were serving static assets with Gunicorn and you could see the static files not changing at the browser during development (even if the server is restarted). The correct way to handle this was to use Nginx as a proxy server that serves static files, and passes other requests to the Flask application (running at Gunicorn). Nginx We use Vagrant for development. To test our application, a port in the host machine has to be forwarded to another port in the guest machine. We forward 8001 Host port to 5000 in Guest. config.vm.network "forwarded_port", guest: 5000, host: 8001 To serve requests with Nginx we need it listening to port 5000 in our Virtualbox. It should serve the static files itself and should pass other requests to the Gunicorn server running the python application. The Gunicorn server should be running on another port, 5001 let's assume. The following Nginx configuration does this: server { listen 5000; location /static { alias /vagrant/app/static; autoindex on; } location / { proxy_pass http://127.0.0.1:5001; proxy_redirect http://127.0.0.1:5001/ http://127.0.0.1:8001/; } } You can see the static files (which are served at /static in out application) are being served directly. /vagrant/app/static is the directory where our static assets reside inside vagrant. autoindex on lets you browse static file directories in the browser. For other locations (URIs) the request is passed onto port 5001 where our Gunicorn server is running. Many responses from the Gunicorn server might contain URLs in the headers, like the Location header. This URL is going to have the domain and port of the Gunicorn server, since Flask is running on this server. This…

Continue ReadingSetting up Nginx, Gunicorn and Flask-SocketIO

Autocomplete Address Form using Google Map API

Google map is one of the most widely used API of Google as most of the websites use Google map for showing address location. For a static address it's pretty simple. All you need to do is mention the address and the map will show the nearest location. Problem arrives when the address is dynamically putted by the user. Suppose for an event in event organizer server, one enters the location. The main component used while taking input location is Google Autocomplete. But we went a step further and parsed the entire address based on city, state, country, etc. and allowed user to input the details as well which gave them the nearest location marked in Map if autocomplete couldn't find the address. Autocomplete Location As we can see, in the above input box we get suggestions by Google Map on entering first few letters of our address. To this, we need the API https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap. You can find an example code of how to do this here. After this is done, what we wanted is not to just include this address, but to provide a form to fill up the entire address in case some parts were missing on this address. The function that the autocomplete listens to is "place_changed" . So once we click on one of the options, this event is triggered. Once the event is triggered, we use the autocomplete.getPlace() to get the complete address json. The json looks something like this: Now what we do is we create a form with input fields having the id same as the ones we require(e.g., country, administrative_area_level_1, locality, etc.). After that we select the long_name or the short_name from this json and put the value in the corresponding input field with the ids. The code for the process after getting the json is elaborated here. Editing Address Form After doing this it looks something like this: However, now the important part is to show the map according to this fields. Also, every time we update a field, the map should be updated. For this we use a hack. Instead of removing the initial location field completely, we hide the field but keep the binding to autocomplete intact. As a result the map is shown when we select a particular address. Now when we update the fields in the address form, we append the value of this field to the value in the initial location field. Though the field is hidden but it is still bound to autocomplete. As a result as soon as we append something to the string contained in the field, the map gets updated. Also, the updated value gets stored to the DB. Thus, with every update in field, the pointer is moved to the nearest location formed by appending all the data from the form. After saving the location data to DB, if we wish to edit it, we can get back the json by making the same request with the location value. And then we will get back the…

Continue ReadingAutocomplete Address Form using Google Map API

Building interactive elements with HTML and javascript: Interact.js + resizing

{ Repost from my personal blog @ https://blog.codezero.xyz/building-interactive-elements-with-html-and-javascript-interact-js-resizing/ } In a few of the past blog posts, we saw about implementing resizing with HTML and javascript. The functionality was pretty basic with simple resizing. In the last blog post we saw about interact.js. interact.js is a lightweight, standalone JavaScript module for handling single-pointer and multi-touch drags and gestures with powerful features including inertia and snapping. Getting started with Interact.js You have multiple option to include the library in your project. You can use bower to install (bower install interact) (or) npm (npm install interact.js) (or) You could directly include the library from a CDN (https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.2.6/interact.min.js). Implementing resizing Let's create a simple box using HTML. We'll add a class called resizable to it so that we can reference it to initialize Interact.js <div class="resizable"> Use right/bottom edge to resize </div> We need to create an interact instance. Once the instance is created, we have to call the resizable method on it to add resize support to the div. interact('.resizable') .resizable({ edges: { right: true, bottom: true } }) .on('resizemove', function (event) { }); Inside the resizable method, we can pass configuration options. The edgesconfig key allows us to specify on which all edges, resizing should be allowed. Right now, we have allowed on the right and bottom edges. Similarly we can have resizing support in the top and left edges too. The resizemove event is triggered by interact every time the user tries to resize the div. From the event, we can get the box that is being resized, (i.e) the target by accessing event.target. The event object also provides us event.rect.width and event.rect.height which is the width and height of the div after resizing. We'll not set this as the width of the div so that, the user is able to see the width change. var target = event.target; // update the element's style target.style.width = event.rect.width + 'px'; target.style.height = event.rect.height + 'px'; We can also instruct Interact.js to preserve the aspect ratio of the box by adding an option preserveAspectRatio: true to the configuration object passed to resizable method during initialization. JavaScript interact('.resizable') .resizable({ edges: { right: true, bottom: true } }) .on('resizemove', function (event) { var target = event.target; // update the element's style target.style.width = event.rect.width + 'px'; target.style.height = event.rect.height + 'px'; }); Resizing and drag-drop (with Interact.js) were used to create the Scheduler tool at Open Event. The tool allows event/track organizers to easily arrange the sessions into their respective rooms by drag-drop and also to easily change the timings of the events by resizing the event block. The entire source code of the scheduler can be viewed at app/static/js/admin/event/scheduler.js in the Open Event Organizer server's GitHub repository. Demo: https://jsfiddle.net/xdfocdty/

Continue ReadingBuilding interactive elements with HTML and javascript: Interact.js + resizing

Configuring Codacy: Use Your Own Conventions

Screenshot from 2016-07-23 01:08:20

All the developers agree on at least one thing – writing clean code is necessary. Because as someone anonymous said, always write a code as if the developer who comes after you is a homicidal maniac who knows your address. So, yeah, writing clean code is very important. Codacy helps in code reviewing and code quality monitoring. You can set codacy in any of your github project. It automatically identifies new static analysis issues, code coverage, code duplication and code complexity evolution in every commit and pull request.

(more…)

Continue ReadingConfiguring Codacy: Use Your Own Conventions

ETag based caching for GET APIs

Many client applications require caching of data to work with low bandwidth connections. Many of them do it to provide faster loading time to the client user. The Webapp and Android app had similar requirements. Previously they provided caching using a versions API that would keep track of any modifications made to Events or Services. The response of the API would be something like this: [{ "event_id": 6, "event_ver": 1, "id": 27, "microlocations_ver": 0, "session_ver": 4, "speakers_ver": 3, "sponsors_ver": 2, "tracks_ver": 3 }] The number corresponding to "*_ver" tells the number of modifications done for that resource list. For instance, "tracks_ver": 3 means there were three revisions for tracks inside the event (/events/:event_id/tracks). So when the client user starts his app, the app would make a request to the versions API, check if it corresponds to the local cache and update accordingly. It had some shortcomings, like checking modifications for a individual resources. And if a particular service (microlocation, track, etc.) resource list inside an event needs to be checked for updates, a call to the versions API would be needed. ETag based caching for GET APIs The concept of ETag (Entity Tag) based caching is simple. When a client requests (GET) a resource or a resource list, a hash of the resource/resource list is calculated at the server. This hash, called the ETag is sent with the response to the client, preferably as a header. The client then caches the response data and the ETag alongside the resource. Next time when the client makes a request at the same endpoint to fetch the resource, he sets an If-None-Match header in the request. This header contains the value of ETag the client saved before. The server grabs the resource requested by the client, calculates its hash and checks if it is equal to the value set for If-None-Match. If the value of the hash is same, then it means the resource has not changed, so a response with resource data is not needed. If it is different, then the server returns the response with resource data and a new ETag associated with that resource. Little modifications were needed to deal with ETags for GET requests. Flask-Restplus includes a Resource class that defines a resource. It is a pluggable view. Pluggable views need to define a dispatch_request method that returns the response. import json from hashlib import md5 from flask.ext.restplus import Resource as RestplusResource # Custom Resource Class class Resource(RestplusResource): def dispatch_request(self, *args, **kwargs): resp = super(Resource, self).dispatch_request(*args, **kwargs) # ETag checking. # Check only for GET requests, for now. if request.method == 'GET': old_etag = request.headers.get('If-None-Match', '') # Generate hash data = json.dumps(resp) new_etag = md5(data).hexdigest() if new_etag == old_etag: # Resource has not changed return '', 304 else: # Resource has changed, send new ETag value return resp, 200, {'ETag': new_etag} return resp To add support for ETags, I sub-classed the Resource class to extend the dispatch_request method. First, I grabbed the response for the arguments provided to RestplusResource's…

Continue ReadingETag based caching for GET APIs

User Notifications

The requirement for a notification area came up when I was implementing Event-Role invites feature. For not-existing users that were not registered in our system, an email with a modified sign-up link was sent. So just after the user signs up, he will be accepted as that particular role. Now for users that were already registered to our platform a dedicated area was needed to let the user know that he has been invited to be a role at an event. Similar areas were needed for Session invites, Call for papers, etc. To take care of these we thought of implementing a separate notifications area for the user, where such messages could be sent to registered users. Issue Base Model I kept base db model for a user notification very basic. It had a user field that would be a Foreign key to a User class object. title and message would contain the actual data that the user would read. message can contain HTML tags, so if someone wants to display the notification with some markup he could store that in the message. The user might also want to know when a notification was received. The received_at field stores a datetime object for the same purpose. There is also has_read field that was later added. It stores a boolean value that tells if the user has marked the notification as Read. class Notification(db.Model): """ Model for storing user notifications. """ id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) user = db.relationship('User', backref='notifications') title = db.Column(db.String) message = db.Column(db.Text) action = db.Column(db.String) received_at = db.Column(db.DateTime) has_read = db.Column(db.Boolean) def __init__(self, user, title, message, action, received_at, has_read=False): self.user = user self.title = title self.message = message self.action = action self.received_at = received_at self.has_read = has_read action field helps the Admin identify the notification. Like if it is a message for Session Schedule change or an Event-Role invite. When a notification is logged, the administrator could tell what exactly the message is for. Unread Notification Count The user must be informed if he has received a notification. This info must be available at every page so he doesn't have to switch over to the notification area to check for new ones. A notification icon at the navbar perhaps. The data about this notification count had to be available at the navbar template at every page. I decided to define it as a method in the User class. This way it could be displayed using the User object. So if the user was authenticated, the icon with the notification count could be displayed. class User(db.Model): """User model class """ # other stuff def get_unread_notif_count(self): return len(Notification.query.filter_by(user=self, has_read=False).all()) {% if current_user.is_authenticated %} <!-- other stuff --> <li> <a class="info-number" href="{{ url_for('profile.notifications_view') }}"> <i class="fa fa-envelope-o"></i> <span class="badge bg-green">{{ current_user.get_unread_notif_count() | default('', true) }}</span> </a> </li> <!-- other stuff --> {% endif %} If the count is zero, count number is not displayed. Possible Enhancement The notification count comes with the HTML generated by the template at…

Continue ReadingUser Notifications