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 3

Anvil News - May
9th of May 2018

It’s been another monster month for us.

It was great meeting everyone at PyCon, and the crowds around our table were awesome! Check out my 5-minute talk from the conference: Making the Web More Pythonic

As always, we’re improving Anvil all the time. Here are a few things you might have missed:

1. Beautiful apps: New Material Design theme

We’ve published a new Material Design theme! We’ve given our components a facelift and added swappable colour schemes, so it’s now even easier to build beautiful apps.

(Don’t worry, the old theme is still there - it’s now called “Classic”.)

2. Simple objects in Data Tables

If you want to store richer data, you can now add “Simple Object” columns to your Data Tables. These can store strings, numbers, lists, or dicts - that’s any JSON object. And you can search inside them with a powerful query system.

Find out more on our blog: https://anvil.works/blog/simple-object-storage

3. Looking after the details

Here are some things we’ve done this month to make Anvil even more pleasing to use:

  • Easier code navigation - you can hold down the Ctrl key and click on a function or variable to jump to its definition.

  • The new FlowPanel lets you lay out components side-to-side. It’s great for grouping buttons, links or labels right next to each other.

  • We’ve made it easier to drag and drop Link components, so it’s clearer whether you’re dropping something next to a Link or inside it. (I love this when I’m building sidebars for navigation!)

  • More options for displaying images in Image components: Shrink to fit, zoom to fill, or display your image at its original size no matter how big your page is.

  • Want your components closer together, or further apart? Now you can control the spacing in a ColumnPanel with the column_spacing property.

  • We’ve made the Toolbox easier to navigate by highlighting the most commonly used components.

  • Fixed-width layouts are easier now too, with the XYPanel. Most of the time, you won’t be needing a fixed-width layout, but when you do, it’s right there.

Happy building!

Meredydd

Making the Web More Pythonic
15th of May, 2018

The Web is not Pythonic. Can we improve that?

The Web is traditionally a pain to program. It's also seriously un-Pythonic.

At PyCon 2018, I asked: Can we make Web programming easier, by making it more Python-shaped?

Scroll down for transcript
Anvil logo
For more information about Anvil, check out anvil.works.
Transcript:

The Web, I assert, is seriously un-Pythonic. It's also famously a pain to program for. Are these two things related? Could we make the Web a nicer place to program, by making it more Pythonic?

Well, to start with, what do I mean by "the web is un-Pythonic"?

Think about a typical web app. You're going to have to turn your data into a bunch of different shapes along the way:

  1. Your data exists as rows in a database, accessed via SQL.
  2. You then transform it into model objects on the server, with methods and attributes to interact with them.
  3. Now, you have to represent these objects as JSON, and provide a whole bunch of REST endpoints for getting or manipulating them.
  4. On the client, you then transform these HTTP requests into Javascript objects, which have methods of their own.
  5. And then you have to transform these client objects into HTML DOM...
  6. ...and style that to produce pixels on a screen.

Oof.

At each of these boundaries, a bunch of boring and repetitive translation work happens. And that is an invitation to exactly the wrong sort of magic.

Let's take an entirely unfair pot-shot at SQLAlchemy, which is a library that manages the transformation of an SQL database into Python objects (and back). It's actually really good at it. You can even write neat query expressions like this: filter(Book.value<20).

Of course, the process of turning that Python expression into SQL is black magic. It involves metaclasses, and overloading standard Python operators to do something completely different to what they normally do.

And that's cool, if you do it once. But if you have this amount of magic at every boundary in this stack, you're setting yourself up for a bad time.

But of course, that's exactly what we do:

  • We have ORMs to translate databases into objects;
  • We have REST frameworks to help us represent objects as JSON;
  • We have JS frameworks (like Angular's resources) to help us turn patterns of HTTP requests into Javascript objects;
  • We have templating engines to represent JS objects as HTML DOM;
  • And we have CSS frameworks to help us display this DOM as the right pixels.

And they're all extremely leaky abstractions! To be a reasonably advanced user of any of these frameworks, you need to understand everything they do, on both sides of the transformation.

Aside: This is a leading cause of the "Framework of the Week" anti-pattern. You have a tool which is inherently unsatisfactory, because it's spanning one or more of these transitions and suffers from all these impedance mismatches. And just in order to use this tool, you need to know more or less everything you need to build one yourself. This presents an irresistible temptation. But of course the new one still isn't quite right...and around and around we go.

So, how does this situation stack up against The Zen of Python?

"There should be one obvious way to do it"?

Hoo, boy. Look at all these frameworks!

"Explicit is better than implicit"?

Transforming data implicitly is these frameworks' job.

"If you can't explain the implementation, it's a bad idea"?

Again, look at the sheer amount of magic in every level of this stack!

So, what might something more Pythonic look like?

At Anvil, we start by putting Python everywhere — even in the browser. (We use the Skulpt Python-to-Javascript compiler; check out my previous talk about it.)

OK, so if we're in Python, and making an HTTP request to a Python server, what happens?

Well, we make a function call into the requests library, and then some time later it emerges as a function call to a Flask endpoint.

Wait a second. If a function call was all we wanted, why not explicitly turn the whole thing into function calls?

So that's what we do. Have a function on the server, decorate it with @anvil.server.callable, and call it from the client with a function call.

Now we can pass arguments (even keyword arguments), and return values from the function. We don't have to marshal everything into an HTTP request any more — it's just a Python function call.

(The data still passes over HTTP, of course. Actually, we use an encrypted WebSocket.)

OK, so the next question is, "What sorts of data should you be able to pass into, or return out of, these functions?"

Well, strings, numbers, dicts, and lists are easy. That's just JSON. But we want to avoid translations, so we want to pass proper objects from the server to the client.

Unfortunately, this is a web server, serving lots of clients, so it has to be stateless: the server just can't afford to keep these objects in RAM.

So we support passing a special sort of object: a stateless server object.

What's in a stateless object? Well, it has an immutable ID, some method names, and some permissions. That's all. (So there's nothing else the server has to remember.)

We can call methods on this object from the client: it's just a server function call, like we saw on the last slide. We make sure the client can't call methods on arbitrary objects by signing the ID and permissions, and requiring that signature to call a method on an object. So the client can only call methods on an object that has been returned from a server function.

An excellent use case for this is...database rows! The object's ID is the unique ID of that row in the database; the methods are things like update() and delete(). And by implementing __getitem__() and __setitem__(), we can even use square-bracket lookup to get and set column values.

If we put this together, we can:

  • Make a simple function call to the server,
  • Look up a database row,
  • Return that row to the client as a Python object,
  • ...and use the values from that row in client code.

We've skipped a whole bunch of these translation steps! We've got one object, passed all the way from the database to client code.

And that's a little contribution to making the Web more Pythonic.

For more about Anvil, check out https://anvil.works.

Thank you very much.




Simple Object Storage
3rd of May 2018

New: Store richer data in Data Tables

Do you find yourself wanting to store more than just strings, numbers and dates in your tables? Perhaps you have complex records with dynamic fields, or perhaps you want to store lists of data without making a whole new table.

Today, we’re introducing a new type of column: the Simple Object. It can store lists, dicts, numbers, strings and (of course) None. (If you’re familiar with JSON, you’ll know this is another way of saying “any JSON value”.)

Add a Simple Object column to your table like this:

Creating a Simple Object column

Now you can store structured data in a single row of your table:

  app_tables.people.add_row(
    name = "Kermit the Frog",
    contact_details = {
      'phone': [
        {'type': 'work',
         'number': '555-555-5555'},
        {'type': 'home',
         'number': '555-123-4567'}
      ]
    })

Querying them is just as simple. If you supply an object to the Data Tables search() or get() method, you’ll match every value that contains those values, dictionary keys or list items. Here’s an example:

  def get_person_for_number(phone_number):
    # We have a phone call for this number. Who is it?

    return app_tables.people.get(
        contact_details = {'phone': [{'number': phone_number}]}
    )

You can read more about Simple Object columns in the Data Tables reference docs.

Anvil News - March
27th of March 2018

Hi everyone,

A lot has happened in Anvil in the last month, here are the highlights:

1. Building Y Combinator Startups in Anvil

How fast can you build a startup? We built full, working versions of two startups from the famous incubator - in just an hour or two each. See how easily you can build a startup with Anvil:

2. New Learning Centre

We’ve reorganised the Anvil documentation, and added a bunch of new how-to guides to our “Cookbook” section. Did you know…

Find all these and more at anvil.works/learn.

3. Do more with Anvil

We’re always making Anvil better. Here are some little improvements you might not have seen:

  • We’ve made it even easier to download files from your Anvil app. You can set the url property of a Link component to any Media object, even a temporary one.

  • Two-factor authentication - secure your access to the Anvil IDE by enabling two-factor auth on your account today. (Open the Anvil editor and choose My Account)

  • The Client Uplink lets you connect un-trusted code to your Anvil apps, just like the Uplink. Building the Internet of Things just got easier! (Read the docs)

  • Customise your Stripe credit card form - you can now set an icon_url with anvil.stripe.checkout()

4. Show and Tell in the Anvil forums

See what other people have built, and share your own apps, in the Anvil forums. Ask questions, get help, and get inspired.

I look forward to seeing you there!

YC Prototypes #2: Building Magic in 2.5 hours
23rd of March 2018

Day 2: Let’s make Magic (YC W15)

It’s Y Combinator’s week of Demo Days, and we’re prototyping one YC startup each day. (If you missed it, check out the first in this series, where we prototyped an e-parking service in an hour and a half.)

Magic (YC W15) is an SMS concierge that can do anything. Text them a request, however outlandish, and they will make it happen. Let’s put ourselves into the founders’ shoes, when they were just starting out. We don’t know if anyone wants this service, so we need a working product they can use. What do we need to build?

  • We need to see and respond to texts from our customers.

  • We need to charge customers for the things we provide (with a commission, of course). They shouldn’t need to enter their credit card every time.

  • We need to share this work between several people.

With Anvil, it turns out we can build this all in a couple of hours. Watch me build a fully working product in this time-lapse video, then scroll down for the play-by-play:

1. Two-way Conversation (45 mins)

We use Anvil’s built-in data tables to store customers and events (messages, notes, etc), and build pages to display them. We use the Users service to authenticate operators (ie us).

Within half an hour, we’ve got the basics: We can receive SMS using an HTTP endpoint from a service like Twilio, display the conversation, and send replies.

2. Take Payment (45 mins)

Now a customer can ask for something, we need them to pay for it! To make purchases truly frictionless, we’ll take their credit card once, then keep it on file for anything they need in the future.

Anvil’s Stripe support makes this simple. We make an app to collect the customer’s card details, and then we send them a link to open that app on their phone:

After that, the card is on file, and we can charge them at the click of a button. (We also note our profit margin for future reference.)

3. Coordinate many operators (50 mins)

If this app takes off, we’ll need help. We don’t want any messages to fall through the cracks, so we text all our operators when a new customer arrives. But we don’t want to notify every operator about every message – they’ll get drowned!

Instead, let’s track which customers need attention, and let operators “claim” customers. (We make sure two operators can’t claim the same customer by accident.)

The operator can mark a customer as Done (request resolved, no longer needs attention), or Can’t handle (still needs attention – “un-claim” the customer and text other operators for help).

If we need more information from the customer, the operator can select “Tell me when they reply”. The operator can go do something else: when the customer replies, we send an SMS to this operator only.

Prototype Complete (2 hours 20 minutes)

We’ve built the infrastructure for an SMS concierge in just a couple of hours. We can help people by text, take payment, and even coordinate a large team of operators if it suddenly gets popular. It’s a fully-working product that can take revenue right away, and scale as we grow.

Here’s how our final app works:

You can grab the source code yourself – click below to open the apps in the Anvil editor:

Copy Apps

Want to dig into how these apps work? Our tutorials show you all the pieces these apps are made from, and more.

Learn More

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