To build a widget, you write Python code. Your code runs slightly differently depending on the type of widget:


If you’ve built a script widget or a scheduled task, your code runs like an ordinary Python script: it executes from top to bottom when you click the Run button, or when the next scheduled interval arrives. The code runs on the server, in its own Python interpreter.

For now, only the owner of a script can run it. If you’re not the owner, you’ll need to fork it to make a copy and run it yourself.

A script must complete within 5 minutes of starting, or will terminate it with a “Server code took too long” error.

Learn more: uses the Anvil framework, and runs scripts as Anvil background tasks.


If you’ve created an HTTP API widget, it’s already got a URL on the public internet. Your widget is a Python module that uses the @route decorator to define paths it responds to.

For example, if your widget’s URL is and you decorate a function with @route('/hello'), then you can call that function by making an HTTP request to

When someone makes a request to your widget’s URL, the server loads your Python module in a new Python interpreter, then looks for a @route function that matches the request. If it finds one, it will call that function, and use its return value as the HTTP response.

If the request includes URL parameters, in the query string or as x-www-form-urlencoded data, will pass them to your function as keyword arguments. If the request includes a JSON body, you can retrieve the parsed data as anvil.server.request.body_json.

If your function returns a string, will make that a response of type text/plain. If you return a dictionary, a list or None, will encode it as JSON and return an application/json response.

Your function has 30 seconds to return a response. Otherwise, will terminate it and return an HTTP 500 error instead.

Learn more: routes work like Anvil’s HTTP Endpoints. So, for example, if you want to customise your HTTP response, you can return an anvil.server.HttpResponse object.


If you’ve created a GUI widget, it also already has a URL on the public internet. A GUI widget has three parts:

  • Design is the visual design of your GUI. You can use’s drag-and-drop editor to create and place UI components on your page. Each component is a Python object, which you can use from client code.

  • Client code is Python that runs on the “client side” – that is, in the web browser where the GUI is opened. Your client code defines a class that represents your GUI, and the components are available as instance variables on that class. The properties of components, which you can configure in the designer, are attributes on that object..

    So for example, if you have a TextBox called text_box_1, you can access its text property from code as self.text_box_1.text.

    Components can also raise events (for example, a Button component raises a click event when you click it). You can use the drag-and-drop designer to set up methods of your GUI class that run when events are raised. You’ll see a button for obvious events, like button clicks, when you select a component; you can find a full list of events in the Properties panel.

    Because client code runs in a web browser, it runs in a restricted subset of Python (approximately Python 3.7).

  • Server code is Python code that runs on the server. You can define functions in your server code and decorate them with @anvil.server.callable. You can then call those functions from client code by calling'name_of_function_here', ...arguments here...). You can pass simple Python objects as arguments to your server functions, and return simple Python objects from server code.

    When you use from client code, the server loads your Python module in a new Python interpreter, then finds the matching @anvil.server.callable function.

Learn more: There’s a lot going on here! If you want to read more about the concept of client vs server code, there’s an explanatory guide on the Anvil website.’s GUIs and server code work just like they do in Anvil, so if you want to dive deeper you can read Anvil’s full docs on user interfaces, client code and server code.

The server environment

Scripts, Scheduled Tasks, HTTP APIs and GUI Server Code runs on the server using Python 3.10. We use a few extra security features that allow us to provide the server environment for free to everybody. This means, for example, that you don’t have a persistent filesystem available in your code.

You can install packages from PyPI into the server environment for any widget. There’s a limit of 500MB of downloaded data and 10 minutes’ installation time for your packages.

The client environment compiles client-side Python into Javascript using the Skulpt compiler. This compiler supports a subset of Python 3.7. Some standard libraries are missing or incomplete – particularly libraries such as file manipulation that do not make much sense in a web browser. Skulpt also cannot compile third-party Python libraries.

If you need to use a library or language feature that is not available in the browser, don’t worry – you can make a function call to you widget’s Server code which runs in a full Python environment.

Do you still have questions?

Our Community Forum is full of helpful information and friendly experts.