Live Chat

We'll need to share your messages (and your email address if you're logged in) with our live chat provider, Drift. Here's their privacy policy.

If you don't want to do this, you can email us instead at contact@anvil.works.

Blog - Page 7

Build a Business Dashboard with Python
22nd of August 2017

You make what you measure.
— Joe Kraus
Dashboards in Python: Visualise Your Performance

Business is like driving - what you’re looking at is what you steer towards. A dashboard is a way to make sure you’re looking at the most important parts of your business. The good news is that they’re quite straightforward to build – especially if you have Python to help you.

I’m going to put the goodies up front, for the geeky and impatient. This is a video of me building a dashboard that pulls data from a business database, and displays it on the web. Watch it now, or read on as we take a step-by-step guide to creating your own business dashboard.

See the code

So, how do I do it?

Step 1: Ask the right question

This is the most important part of measuring your business. You have to ask yourself what information is so important, you should see it every morning.

When you’re building a business, the most important questions aren’t always obvious. There are some great guides out there. I’d recommend Startup Metrics for Pirates (not just for start-ups!), and Adam D’Angelo’s talk on measurement from Y Combinator’s Startup School.

Broadly, though, there are two sorts of questions: Strategic metrics that show you where you want to go, like user acquisition rate, retention, or revenue growth; and tactical metrics that monitor how you’re getting there, such as A/B tests and short-lived marketing initiatives. At very least, you should have a dashboard that shows you your strategic metrics, and how they compare to historical performance.

Don't be afraid of hard questions.

Sometimes, the answer you need is right there in your database, and all you need is to query it. It's great when that happens, and we'll cover this simple case in our walkthrough.

But it's often more complicated than that: Perhaps you'll need data from your application database, your CRM system and an external analytics provider. Because we're using Python to compile the data for our dashboard, we have the flexibility to do that. So you have no excuse: Don't measure the wrong thing, just because it's easier.

Step 2: Get the answer from your database

Let’s imagine we’ve thought about it, and decided that our primary business concern is acquisition: How many new users are we signing up, and how is that changing from week to week?

For 99% of online businesses, this information will be in an SQL database somewhere. Connect with your command-line tool of choice, and write your query. Our example table looks like this, using Postgres:

myapp=> \d users
                 Table "public.users"
   Column    |            Type             | Modifiers                      
-------------+-----------------------------+-----------
 id          | integer                     | 
 email       | text                        | 
 signup_date | timestamp without time zone | 

A little trial and error, and we have a query that gives us the number of user sign-ups by week, for the last three months:

myapp=> SELECT COUNT(*), DATE_TRUNC('week', signup_date) AS d
             FROM users
             WHERE signup_date > NOW() - INTERVAL '3 months'
             GROUP BY DATE_TRUNC('week', signup_date)
             ORDER BY d;
Step 3: Put it online

We want to make this data visible on a web page. Anvil lets us create web apps with nothing but Python. We’re going to create an Anvil app: It will have a server module that uses the standard Python tools to extract the data from our database, and a client-side page to display it on the web (also in pure Python).

To connect to a Postgres database, we use the standard Psycopg2 library. We create a server module and write:

import psycopg2

conn = psycopg2.connect("host=db.myapp.com dbname=my_app user=postgres password=secret")

Now, we want to run that SQL query on demand. We’ll define a function that gets our data and returns it as a list:

@anvil.server.callable
def get_user_signups():
    cur = conn.cursor()
    cur.execute("""
        SELECT COUNT(*), DATE_TRUNC('week', signup_date) AS d
             FROM users
             WHERE signup_date > NOW() - INTERVAL '3 months'
             GROUP BY DATE_TRUNC('week', signup_date)
             ORDER BY d;
    """)
    return list(cur)

We’ve marked the function @anvil.server.callable. That’s all we need to make it accessible from client-side code when we build our web page. (No web server required!)

Calculating complex metrics

Remember earlier, when we said you probably want more than just a user count? This is where Python shines.

Cross-reference with a NoSQL database. Query your CRM via its API. Run statistical models with NumPy. Python is the swiss army knife of data analysis – why wouldn't you use it for your dashboard?

Step 4: Draw the plot

All that’s left is to display this data as a graph in our web app. We open Anvil’s visual designer and add a Plot component to our app’s main page. When the app opens, we call the query function we’ve just defined, and construct a line graph with the data:

signups = anvil.server.call('get_user_signups')

# Anvil plots use the Plot.ly API: https://plot.ly/python/#basic-charts
scatter = go.Scatter(x = [signup_time for (count,signup_time) in signups],
                     y = [count for (count,signup_time) in signups],
                     fill = 'tozeroy')

We want that code to run when the page first opens, so we put it in the __init__ method of our form. (We also import the plot API.)

Here’s the entire page source code, including the parts Anvil provides for you:

from plotly import graph_objs as go

class Form1(Form1):
  def __init__(self, **properties):
    self.init_components(**properties)

    # This code will run when the form opens.
    signups = anvil.server.call('get_user_signups')

    # Make a line plot of this data
    scatter = go.Scatter(x = [signup_time for (count,signup_time) in signups],
                         y = [count for (count,signup_time) in signups],
                         fill = 'tozeroy')

    # Display that plot on our page
    self.plot_1.data = scatter

That’s it! Here’s what it looks like, now we’re finished:

Screen-shot of the finished app

See source code in the Anvil editor

Step 5: Actually watch it

It feels silly to say it, but I know from personal experience: A dashboard you don’t look at is as bad as no dashboard at all. It’s actually worse, because knowing it’s there gives you a false sense of security.

Set your dashboard as your home page - or if you have a spare screen, display it in the corner of your office. And then, when it tells you something interesting, you might actually react!



I hope you’ve found this guide helpful. You can follow us on Twitter, or email me any questions or comments at meredydd@anvil.works. Finally, you can see the full source code for this example here:

See the code

Interactive plots for your apps
26th of July 2017

New: Graphs and charts for your Anvil app

Python is the world’s favourite language for data processing and visualisation – and when you use Anvil, Python is all you need to build web apps. Today, we’re making it even easier to present your data on the web.

You can now offer interactive charts right inside your Anvil apps, built and customised in just a few lines of code. The new Plot component is powered by the Plotly Python API, so you have a wealth of examples already online to get you started.

Plots like this are simple to create, and simple to customise:

You can open this example in Anvil right now, or read the docs to learn more.

You can also find more examples in the Plotly library docs .


Try this demo now




HTTP endpoints for your apps
17th of July 2017

New: Make an API for your Anvil app

Sometimes we want to connect other programs with our Anvil apps. Whether it’s a native mobile app, a shell script, or a web service like Twilio, most things expect to make REST or plain HTTP requests.

As of today, this is all it takes to publish an HTTP API that returns some JSON:

@anvil.server.http_endpoint("/greet/:name")
def greet(name, **qs):
  return {'message': 'Hello, ' + name + '!'}

We can demonstrate it with the curl command-line program:

$ curl https://http-endpoint-demo.anvilapp.net/_/api/greet/Joanne
{"message":"Hello, Joanne!"}

You can open this example in Anvil right now, or read the docs to learn more.


Try this demo now




Make the world better? Remove some Javascript.
27th June 2017

Compiling Python to Javascript

To write full-stack web apps in nothing but Python, you need to run Python code in the browser. Watch my talk at PyCon 2017, or scroll down for a transcript:

For more information about Skulpt, check out skulpt.org.

Or you can check out the pull request that implemented these changes.

Transcript:

Back when my friend Ian and I were idealistic students, we sat down and decided to make the world a better place, as you do. And we decided that the best way two developers could make the world a better place was to remove some Javascript from it.

The web is the greatest application delivery platform on Earth, and frankly it’s a stain on our profession that you need to know five different programming languages and three different frameworks if you want to make it do anything. Really, all you should need is to be able to code - ideally, in a friendly, readable language that’s easy to learn and isn’t full of unpleasant surprises.

There was an obvious candidate.

So, we built a tool for building full-stack web applications with nothing but Python.

We built a graphical interface builder for designing your pages, and let you write your client-side code in Python - so all the buttons, text fields etc you put on your page are just Python objects. We built a back-end server environment, also in Python, and a database with a pure Python API, all deployed in the cloud in one click.

But today I want to talk about this front-end code.

If you want to drive the items on your web page as pure Python objects, you’re going to need to run Python in the browser. If you’re going to run something in the browser, it’s going to have to be in Javascript.

Thankfully, there’s a great open-source project called Skulpt, that compiles Python to Javascript. So you can write Python to drive your app, and we can compile it to Javascript so that when you publish it online, your code actually runs in a user’s browser. We give Skulpt Python objects, it represents them as Javascript objects. We give it a Python function, and it produces a Javascript function for the browser to run.

There is a problem, though. Javascript, in its infinite wisdom, is 100% non-blocking. If you kick off a process that finishes later, you’d better provide a callback.

Here’s some code you might write in Python. Go get a record from the database, and if it’s not there, throw an error.

And here’s how you’d do it in Javascript. I count three separate callbacks here. I’m not exaggerating - this is an example straight from the documentation of the postgres library!

OK, so we have a Python-to-Javascript compiler, and it’s open source. What if we could turn this into this, automatically?

So, we go "git clone", and start exploring. It turns out that Skulpt has a classic compiler architecture, modeled quite closely on CPython: There’s a parser that turns Python code into a parse tree (these are all the files in the Skulpt source tree, by the way, if you want to follow along).
Then it walks over this parse tree and makes an abstract syntax tree, which is made of elements you might recognise - like variable assignments, function definitions, function calls, and so on. Then there’s a compiler that then walks this syntax tree and spits out Javascript.

So, this is what we need to modify to implement blocking code. We invent a new Javascript class that a function can return, to say “hey, I’m returning, but I’m not done yet; I’ve just blocked”. We call this a suspension.

So, when we’re compiling the AST, wherever we’re compiling a function call, we generate Javascript code that calls the function, and looks at the return value, and says, "is it a Suspension?". Because if it returned a Suspension, we’re blocking - and I'm going to have to suspend myself. We save all our variables and temporary values, our exception state, and where we are in the function, and then we return our own suspension with all that information in it.

And so our caller will recognise that we have suspended, and so it's going to have to suspend as well, and so on all the way back to the Javascript runtime.

When that operation completes - say the database gives us a response - we resume the Suspension. We call our function with the suspension, which then restores all our variables, jumps to the right place and resumes the original suspension, which restores all of its variables, and so on, until we can resume execution as normal.

So, that’s how we take simple blocking Python, and compile it into non-blocking Javascript so you don’t have to.

This has been a quick overview; if you’re interested you can check out Skulpt at skulpt.org - I’m one of the maintainers now, and we’re always looking for new contributors.

And if you're fed up to the back teeth with all this Javascript, and you want to forget it all and write full-stack web apps with nothing but Python, please check us out at www.anvil.works.

Thank you very much!




Smart Python Code Completion
15th of February 2017

That's right. It's here.

Every coder knows the pain: You know what you need to do, but you can’t remember the name of that function, or what order it takes its parameters. It’s time to fix that problem.

We are excited to announce that from today, the Anvil web IDE includes smart code completion. Anvil knows about your forms, your components, your variables - even your data tables. Now we’re giving that information to you in real-time, as you type. Our API documentation is great, but the best docs are the ones you never have to look at. Code completion means the options are always at your fingertips.

Smart code completion is available right now - just log in and start creating!


Start Now




Learn More

Get the best out of Anvil with our free email course.