<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ryan</title>
    <description>The latest articles on DEV Community by Ryan (@codingwithryan).</description>
    <link>https://dev.to/codingwithryan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png</url>
      <title>DEV Community: Ryan</title>
      <link>https://dev.to/codingwithryan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codingwithryan"/>
    <language>en</language>
    <item>
      <title>AnkiBuddy: Automating Flashcard Creation for Medical Students</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Mon, 18 Aug 2025 15:03:39 +0000</pubDate>
      <link>https://dev.to/anvil/ankibuddy-automating-flashcard-creation-for-medical-students-1n</link>
      <guid>https://dev.to/anvil/ankibuddy-automating-flashcard-creation-for-medical-students-1n</guid>
      <description>&lt;h2&gt;
  
  
  Executive Summary
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.ankibuddy.com/" rel="noopener noreferrer"&gt;AnkiBuddy&lt;/a&gt; transforms the way medical students create study materials by using AI to generate high-quality &lt;a href="https://apps.ankiweb.net/" rel="noopener noreferrer"&gt;Anki&lt;/a&gt; flashcards from PDF documents in minutes - eliminating hours of manual card creation. Built by Dr. David Topf and using &lt;a href="https://anvil.works?utm_source=devto_ankibuddy_case_study" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt;, AnkiBuddy went from initial idea to working prototype in just 2 months, with Anvil enabling rapid iteration and continuous improvement ever since.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built by a solo developer&lt;/li&gt;
&lt;li&gt;Prototype ready in 2 months&lt;/li&gt;
&lt;li&gt;Users: 18,000+&lt;/li&gt;
&lt;li&gt;Customer lifetime value: €70
&lt;/li&gt;
&lt;li&gt;MoM user growth: 32%&lt;/li&gt;
&lt;li&gt;50,000+ PDFs parsed&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Anvil has allowed me to do this as a solo entrepreneur. Any other solo entrepreneur that builds a software product needs to basically be a full stack developer who's also had experience with DevOps and has the skills to build a business.&lt;br&gt;
Dr. David Topf&lt;br&gt;
Founder and CEO, AnkiBuddy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Challenge: When Manual Study Card Creation Meets Medical School
&lt;/h2&gt;

&lt;p&gt;Every medical student knows the struggle: You have tonnes of PDF study materials, and you know that spaced repetition with flashcards is one of the most effective ways to learn. But creating quality flashcards manually is incredibly time-consuming. Turning a single PDF into comprehensive Anki cards can take hours.&lt;/p&gt;

&lt;p&gt;David's sister Danielle, a medical student, experienced this firsthand. She asked David how she could use AI to transform her medical study summaries into flashcards. As David recalls, "When she showed me how long it takes her to manually generate Anki cards, I wanted to try to help".&lt;/p&gt;

&lt;h3&gt;
  
  
  What If We Let AI Do the Heavy Lifting?
&lt;/h3&gt;

&lt;p&gt;David saw an opportunity - what if AI could handle the tedious process of reading through study materials and creating well-structured flashcards? This wasn't just about automation, it was about creating scientifically-sound study materials that would actually improve learning outcomes.&lt;/p&gt;

&lt;p&gt;The idea became AnkiBuddy: an AI-powered platform that transforms PDF study materials into customizable, high-quality Anki flashcards optimized for medical education.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: AI-Powered Flashcard Generation
&lt;/h2&gt;

&lt;p&gt;AnkiBuddy is a web-based platform that lets medical students upload their study materials and receive well-structured Anki flashcards within minutes. The platform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyzes PDF content using AI&lt;/li&gt;
&lt;li&gt;Generates professionally-structured flashcards&lt;/li&gt;
&lt;li&gt;Allows easy customization and personalization of cards&lt;/li&gt;
&lt;li&gt;Integrates with existing Anki workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdti0asvse6dhucmf65hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdti0asvse6dhucmf65hr.png" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No more spending hours manually creating cards. No more inconsistent formats. Just high-quality study materials, ready when you need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building AnkiBuddy: Rapid Development with Anvil
&lt;/h2&gt;

&lt;p&gt;David had already worked hard building an AI-powered PDF parser using Python - the next challenge was building a UI and getting it all deployed online. That's where Anvil came in.&lt;/p&gt;

&lt;p&gt;He'd already learned Python for the AI part of the app, so he reached for Anvil to simplify the web development process and handle his DevOps and hosting. Within two months of working with Anvil, David had a working prototype of AnkiBuddy which he could give to users.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It basically simplified it to a place where, if I learn Python and I learn the rules of Anvil, I can do pretty much what I want.&lt;br&gt;
Dr. David Topf&lt;br&gt;
Founder and CEO, AnkiBuddy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More than just accelerating development, Anvil allowed David to offload database management, DevOps, and hosting. It saved him the headaches of navigating complex cloud platforms like AWS - letting him focus entirely on building his product and business.&lt;/p&gt;

&lt;p&gt;He also took advantage of the support package offered by Anvil to help maximise his development speed and get answers to questions fast.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I completely underestimated how valuable the support plan would be. I’ve been able to work directly with the Anvil development team. They’re not just responsive; they’re some of the most skilled engineers I’ve ever encountered.&lt;br&gt;
Dr. David Topf&lt;br&gt;
Founder and CEO, AnkiBuddy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Results: From Idea to Impact
&lt;/h2&gt;

&lt;p&gt;Since its launch, AnkiBuddy has helped 18,000 medical students transform their study workflows. It has proven that there's real demand for AI-powered study tools that are tuned to specific needs.&lt;/p&gt;

&lt;p&gt;Anvil has enabled fast iteration ever since the prototype was launched. When users reported bugs or suggested improvements, David could implement changes in no time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fomq1fxugqge88psml4vn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fomq1fxugqge88psml4vn.png" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AnkiBuddy is a perfect example of how modern AI can solve real educational challenges and how the right development platform can help solo entrepreneurs move from idea to impact in record time.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Information
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AnkiBuddy&lt;/strong&gt; creates high-quality Anki flashcards from your PDF study materials in minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.ankibuddy.com/" rel="noopener noreferrer"&gt;Visit ankibuddy.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re new to &lt;strong&gt;Anvil&lt;/strong&gt; and want to see how you can build powerful web apps using just Python—up to 7× faster than traditional development:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works?utm_source=devto_ankibuddy_case_study" rel="noopener noreferrer"&gt;Learn more about Anvil&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have questions or want to get in touch? Visit &lt;a href="https://anvil.works/contact?utm_source=devto_ankibuddy_case_study" rel="noopener noreferrer"&gt;anvil.works/contact&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>startup</category>
    </item>
    <item>
      <title>What makes Anvil so easy to learn?</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Fri, 18 Jul 2025 10:47:59 +0000</pubDate>
      <link>https://dev.to/anvil/what-makes-anvil-so-easy-to-learn-3ggi</link>
      <guid>https://dev.to/anvil/what-makes-anvil-so-easy-to-learn-3ggi</guid>
      <description>&lt;h1&gt;
  
  
  Anvil's Shallow Learning Curve
&lt;/h1&gt;

&lt;p&gt;When evaluating a new dev tool, a common question is "How long will it take to learn?". Lengthy learning curves cost time, effort, and money - but one of the beauties of Anvil is its shallow learning curve.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don’t want all the things slowing me down. I don’t want learning curves, I don’t want any of that. I want it quick, and that’s what Anvil gave me. — &lt;strong&gt;Shonna Smith, Product Manager, Consultant&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anvil lets you become productive in days, not months. This isn't just a marketing claim, it's an experience shared by many Anvil users. Let's take a look at why Anvil is quick to learn.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Is Anvil Easy To Learn?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. It's All Python
&lt;/h3&gt;

&lt;p&gt;It's all Python, and much like Python, the learning curve of Anvil is gentle and shallow.&lt;/p&gt;

&lt;p&gt;You don't need to learn new languages or frameworks for each layer of your web app - saving you time. You can use Python for UI components, front-end code, back-end code and interacting with your database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Simple Anvil event handler - just Python
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;button_click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;event_args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Updating the display text of a label component
&lt;/span&gt;    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_label&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name_box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. No Boilerplate Code
&lt;/h3&gt;

&lt;p&gt;Anvil eliminates the need for boiler plate code and setup. The platform wraps common tasks like database access, user authentication, and API endpoints in easy-to-use APIs, letting you focus on what your application does.&lt;/p&gt;

&lt;p&gt;Consider how much effort you typically spend on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up projects&lt;/li&gt;
&lt;li&gt;Configuring build tools&lt;/li&gt;
&lt;li&gt;Managing deployment pipelines&lt;/li&gt;
&lt;li&gt;Creating databases and access controls&lt;/li&gt;
&lt;li&gt;Building secure user authentication&lt;/li&gt;
&lt;li&gt;Configuring email services and servers&lt;/li&gt;
&lt;li&gt;Checking software security&lt;/li&gt;
&lt;li&gt;Developing API endpoints&lt;/li&gt;
&lt;li&gt;Setting up version control&lt;/li&gt;
&lt;li&gt;Implementing secrets management&lt;/li&gt;
&lt;li&gt;Integrating external services&lt;/li&gt;
&lt;li&gt;Connecting to IoT devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anvil simplifies and handles all this and more for you, dramatically saving you time. It has the added benefit of making your app more secure - less code equals fewer opportunities for vulnerabilities.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If data is ever at risk in the journey, we can't move forward with a solution, full stop... They've thought about all of this so that you don't have to. - &lt;strong&gt;Jacque Van Niekerk, Data Scientist, CFC Underwriting&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  3. Extensive Documentation
&lt;/h3&gt;

&lt;p&gt;Anvil's documentation and tutorials are extensive. They cover everything from the basics to advanced topics, making it easy to get up to speed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/learn/tutorials?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;Try a tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/docs/overview?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;Read the docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, we have an extremely active &lt;a href="https://anvil.works/forum?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;community forum&lt;/a&gt; where you can ask questions if you're stuck, share knowledge, and get help from our team.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Traditional Web Architecture
&lt;/h3&gt;

&lt;p&gt;Anvil follows the traditional web architecture approach, with a separation between client and server code. This makes it familiar, easy to understand, and maintain. &lt;/p&gt;

&lt;p&gt;For people who aren't familiar with web architecture, i.e. non-web developers, it's still useful. The clear separation of concerns makes it easier for you to debug and think about. The underlying principles are also widely understood by other people, meaning they can help even without experience of Anvil.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/articles/client-vs-server?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;Learn more about client vs server&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A Different Kind of Investment With Real-World Impact
&lt;/h2&gt;

&lt;p&gt;Anvil being quick to learn means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster time-to-market for your applications&lt;/li&gt;
&lt;li&gt;Reduced training costs for your team&lt;/li&gt;
&lt;li&gt;Lower risk when evaluating the platform&lt;/li&gt;
&lt;li&gt;Increased productivity rather than delayed returns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the impact has been felt by many Anvil users:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We wanted a web app urgently during the Covid-19 lockdown. With only intermediate skills in Python, and no knowledge of HTML/CSS/JavaScript/Flask/Django etc, Anvil enabled us to share a Minimum Viable Product in just 7 days.-&lt;strong&gt;Peter Fison, Managing Director, South West London TV&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Ready to see how shallow Anvil's learning curve is? Or do you have some questions?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try Anvil's &lt;a href="https://anvil.works/learn/tutorials/feedback-form?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;intro tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ask questions on our friendly &lt;a href="https://anvil.works/forum?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;community forum&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="//mailto:sales@anvil.works"&gt;Talk to an Anvil engineer&lt;/a&gt; to discuss your specific use case&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://anvil.works?utm_source=devto_learning_curve" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>learning</category>
      <category>programming</category>
    </item>
    <item>
      <title>How We Brought the GOV.UK Design System into Anvil</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Mon, 02 Jun 2025 14:57:16 +0000</pubDate>
      <link>https://dev.to/anvil/how-we-brought-the-govuk-design-system-into-anvil-4a1f</link>
      <guid>https://dev.to/anvil/how-we-brought-the-govuk-design-system-into-anvil-4a1f</guid>
      <description>&lt;h1&gt;
  
  
  Case Study: Implementing Any Design System in Anvil
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;New to Anvil? Welcome! &lt;a href="https://anvil.works?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; lets you build full-stack web apps using only Python. No need to juggle JavaScript, HTML, CSS, Python, SQL and all their frameworks. &lt;strong&gt;Just code in Python&lt;/strong&gt; and bring your app to life!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.figma.com/blog/design-systems-101-what-is-a-design-system/" rel="noopener noreferrer"&gt;Design systems&lt;/a&gt; are invaluable for creating professional web apps. Implementing your design system in Anvil, by creating custom drag-and-drop components, layouts, and themes, streamlines development for both yourself and others. Today, I’ll show you one I built from scratch to demonstrate what’s possible in Anvil.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtsdoxp882moowwn9lqr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtsdoxp882moowwn9lqr.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this case study, I'm using &lt;a href="https://design-system.service.gov.uk/" rel="noopener noreferrer"&gt;GOV.UK's design system&lt;/a&gt;. It's a great example of a comprehensive design system, which standardises styles, helps construct components and takes accessibility seriously. It provides all the benefits of using a well thought out design system when creating a web app - so it's perfect to show you what you can achieve in Anvil.&lt;/p&gt;




&lt;h2&gt;
  
  
  The finished product
&lt;/h2&gt;

&lt;p&gt;The proof is in the pudding so, before I dig into how I implemented the system in Anvil, here's an example of using the finished design system in the Anvil editor. Here's me using the design system as a dependency and creating a GOV.UK form by simply dragging and dropping components into the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg2mvuhqen3kr2xlaj2p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg2mvuhqen3kr2xlaj2p.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can even clone this app and play around yourself:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://anvil.works/build#clone:ESWLOEKGXMN2N24H=WGCFPUA34JSRPR23KVU4FJXJ" rel="noopener noreferrer"&gt;Clone the Example&lt;/a&gt;
&lt;/h4&gt;




&lt;h2&gt;
  
  
  How it's built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://design-system.service.gov.uk/" rel="noopener noreferrer"&gt;GOV.UK's design system website&lt;/a&gt; provides all the HTML and CSS needed to implement their design system. They break everything down into individual &lt;a href="https://design-system.service.gov.uk/components" rel="noopener noreferrer"&gt;components&lt;/a&gt; and &lt;a href="https://design-system.service.gov.uk/styles/page-template/" rel="noopener noreferrer"&gt;page templates&lt;/a&gt;. Since Anvil allows for extensive customisation, I was able to use a few of its out-of-the-box features to recreate them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom HTML Layouts
&lt;/h3&gt;

&lt;p&gt;The first step was to implement GOV.UKs page template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ysdi0nvi4ztm86qpcmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ysdi0nvi4ztm86qpcmy.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anvil’s &lt;a href="https://anvil.works/docs/ui/layouts/html-layouts?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;custom HTML Layouts&lt;/a&gt; let me use the HTML from the &lt;a href="https://design-system.service.gov.uk/styles/page-template/" rel="noopener noreferrer"&gt;design system's page templates&lt;/a&gt;. All I had to do was insert &lt;a href="https://anvil.works/docs/ui/layouts/html-layouts#adding-slots" rel="noopener noreferrer"&gt;slots&lt;/a&gt; in the HTML to define where components can be added to the Layout when it is used by other Forms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Here's a slimmed down example of the GOV.UK's footer --&amp;gt;
&amp;lt;footer class="govuk-footer" role="contentinfo"&amp;gt;
    &amp;lt;!-- To let developers add components to the footer, I simply defined
    the anvil-slot. --&amp;gt;
    &amp;lt;div anvil-slot="footer-items"&amp;gt;
        &amp;lt;!-- And added usage details for the Anvil designer. --&amp;gt;
        &amp;lt;p anvil-if-slot-empty="footer-items" class="anvil-designer-only"&amp;gt;&amp;lt;i&amp;gt;Drag footer links or components here&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/footer&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To see how simple it is to create layouts from scratch, check out our docs:&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://anvil.works/docs/ui/layouts/html-layouts" rel="noopener noreferrer"&gt;Read the docs on custom layouts&lt;/a&gt;
&lt;/h4&gt;
&lt;h3&gt;
  
  
  Components from HTML
&lt;/h3&gt;

&lt;p&gt;For GOV.UK’s individual components, I used Anvil's ability to &lt;a href="https://anvil.works/docs/ui/custom-components/html-components?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;create components from scratch in HTML&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I simply copied and pasted the HTML from the design system and added the &lt;code&gt;anvil-name&lt;/code&gt; attribute to the elements I wanted to access in code.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- The Component's HTML is the same as the design system plus the `anvil-name` attribute --&amp;gt;
&amp;lt;input anvil-name="govuk-input" class="govuk-input"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With &lt;code&gt;anvil-name&lt;/code&gt; assigned, I could easily reference those elements in Python using Anvil’s &lt;a href="https://anvil.works/docs/ui/custom-components/html-components#accessing-elements?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;dom_nodes API&lt;/a&gt;. This let me to select individual elements, insert new content, apply new styles, and modify attributes—all while keeping the structure of the original design system intact.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Here's are some simple getter and setter functions for the text input component I built
@property
def label_text(self):
    return self.dom_nodes["govuk-label"].textContent

@label_text.setter
def label_text(self, value):
    self.dom_nodes["govuk-label"].textContent = value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Anvil stands out by giving you full access to any &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element" rel="noopener noreferrer"&gt;HTML element's APIs&lt;/a&gt; directly from Python code. There are no limits imposed by Anvil's abtraction.&lt;/p&gt;

&lt;p&gt;Check out our tutorial on building custom components from HTML:&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://anvil.works/learn/tutorials/access-html-elements-in-python?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Learn how to create components&lt;/a&gt;
&lt;/h4&gt;


&lt;h2&gt;
  
  
  Ready to get started?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;We’ve got full documentation and tutorials&lt;/strong&gt; to help you get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://anvil.works/learn/tutorials/using-layouts-to-create-multi-page-app?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Multi-page apps with Layouts tutorial&lt;/a&gt; - Learn how to structure your app using layouts.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://anvil.works/docs/ui/layouts/html-layouts?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Custom HTML Layouts docs&lt;/a&gt; - Recreate page templates as Anvil layouts.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://anvil.works/learn/tutorials/access-html-elements-in-python?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Creating custom components from scratch tutorial&lt;/a&gt; - Follow a step-by-step guide to creating your first custom component.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://anvil.works/docs/ui/custom-components/html-components?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Components from HTML docs&lt;/a&gt; - Build individual components and access their attributes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These resources will help you with everything you need to bring your design system into Anvil.&lt;/p&gt;

&lt;p&gt;Any questions? Our &lt;a href="https://anvil.works/forum?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Community Forum&lt;/a&gt; is full of helpful information and Anvil experts.&lt;/p&gt;


&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://anvil.works?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://anvil.works/build?utm_source=devto_govuk_design" rel="noopener noreferrer"&gt;Sign up for Anvil&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Want to build an app of your own? Get started with one of our tutorials:&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>python</category>
      <category>webdev</category>
      <category>design</category>
      <category>designsystem</category>
    </item>
    <item>
      <title>Have a product idea? Use this SaaS template!</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Mon, 10 Feb 2025 12:06:44 +0000</pubDate>
      <link>https://dev.to/anvil/have-a-product-idea-use-this-saas-template-459l</link>
      <guid>https://dev.to/anvil/have-a-product-idea-use-this-saas-template-459l</guid>
      <description>&lt;h2&gt;
  
  
  Welcome to Anvil's SaaS Template
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://anvil.works/build#clone:SUTICB6NGVZM7J5S=CB3DXR7V65FYL6UQOF2VQF5L" rel="noopener noreferrer"&gt;Anvil's SaaS (Software as a Service) template&lt;/a&gt; is a solid starting point and foundation for your subscription-based SaaS product. This template uses &lt;a href="https://stripe.com" rel="noopener noreferrer"&gt;Stripe's&lt;/a&gt; API for subscription management, and includes simplified user permissions for you to use throughout your app. It's an ideal starting point for your project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://stripe.com" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt; provides tools for businesses to accept, manage, and process payments online and in person, offering features like customizable APIs, fraud prevention, subscription billing, and global currency support.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;p&gt;In this guide, we’ll walk through the key components of the template, covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Introduction&lt;/strong&gt;: Briefly learn about Anvil and the benefits of using this template.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prerequisites&lt;/strong&gt;: What you’ll need to get started.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template Structure&lt;/strong&gt;: A high-level overview of the app’s architecture and Stripe integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template Setup&lt;/strong&gt;: Step-by-step instructions to get the template up and running with your account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing The App&lt;/strong&gt;: Test the integration and explore the template’s functionality from a user’s perspective. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make The app Your Own&lt;/strong&gt;: With the integration set up, it's time to make the app your own.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Anvil
&lt;/h3&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://dev.to/"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You're going to need to know the basics of Anvil before using this template, so I'd recommend following our &lt;a href="https://anvil.works/learn/tutorials/feedback-form?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;10-minute intro tutorial&lt;/a&gt;. This should give you enough knowledge to begin using the SaaS template.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use Anvil's SaaS template?
&lt;/h3&gt;

&lt;p&gt;This template is a solid foundation for building your own SaaS app. It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full &lt;a href="https://stripe.com" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt; payment and checkout&lt;/li&gt;
&lt;li&gt;Subscription management synced with the app&lt;/li&gt;
&lt;li&gt;Account management synced with Stripe&lt;/li&gt;
&lt;li&gt;Easy-to-configure user permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, it's an ideal starting point for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this guide you will need the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An understanding of Python&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://dashboard.stripe.com/login" rel="noopener noreferrer"&gt;Stripe account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Basic knowledge of Anvil (a great place to start is with Anvil's &lt;a href="https://anvil.works/learn/tutorials/feedback-form?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;Feedback form tutorial&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding the template's structure
&lt;/h2&gt;

&lt;p&gt;The template is divided into two main parts: the Stripe integration and the Anvil app. Stripe manages payments, subscriptions, and invoicing, while the Anvil app handles user authentication and permissions.&lt;/p&gt;

&lt;p&gt;The app relies on the following Stripe features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.stripe.com/customer-management" rel="noopener noreferrer"&gt;Customer Portals&lt;/a&gt; - allows our customers to self-manage their payment details, invoices, and subscriptions in one place.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.stripe.com/payments/checkout/pricing-table" rel="noopener noreferrer"&gt;Pricing Tables&lt;/a&gt; - displays our prices, configured easily from our Stripe dashboard and takes users into Stripes checkout flow.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.stripe.com/api" rel="noopener noreferrer"&gt;APIs&lt;/a&gt; - to send data and requests to our Stripe account.

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.stripe.com/api/prices/list" rel="noopener noreferrer"&gt;Retrieve price list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.stripe.com/api/customers/retrieve" rel="noopener noreferrer"&gt;Retrieve a customer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.stripe.com/api/subscriptions/cancel" rel="noopener noreferrer"&gt;Cancel a subscription&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.stripe.com/api/customers/delete" rel="noopener noreferrer"&gt;Delete a customer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://docs.stripe.com/webhooks" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt; - to send data to our Anvil app when an event happens in Stripe.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;customer.subscription.updated&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;customer.created&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Here's an API flow to help visualise the integration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fapi-call-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fapi-call-diagram.png" width="800" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's a user flow diagram to visualise the functionality available to the end user:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fuser-flow-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fuser-flow-diagram.png" width="800" height="848"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting up the template
&lt;/h2&gt;

&lt;p&gt;This section will guide you through getting started with the template, understanding its features, and further developing it to suit your needs.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 - Cloning The Template
&lt;/h3&gt;

&lt;p&gt;Start by cloning the template app with the following link:&lt;br&gt;
&lt;a href="https://anvil.works/build#clone:SUTICB6NGVZM7J5S=CB3DXR7V65FYL6UQOF2VQF5L" rel="noopener noreferrer"&gt;https://anvil.works/build#clone:SUTICB6NGVZM7J5S=CB3DXR7V65FYL6UQOF2VQF5L&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2 - Stripe Account Setup
&lt;/h3&gt;

&lt;p&gt;Next, we'll set up our Stripe account. &lt;a href="https://dashboard.stripe.com/login" rel="noopener noreferrer"&gt;Register for a Stripe account&lt;/a&gt; and login. Then enter your &lt;a href="https://support.stripe.com/questions/business-information-requirements-to-use-stripe?locale=en-GB" rel="noopener noreferrer"&gt;business details&lt;/a&gt; to start capturing recurring revenue (or skip this step if you're only going to use &lt;a href="https://stripe.com/docs/test-mode?locale=en-GB" rel="noopener noreferrer"&gt;Stripe's test mode&lt;/a&gt;). Lastly, activate Stripe's &lt;a href="https://stripe.com/docs/test-mode?locale=en-GB" rel="noopener noreferrer"&gt;test mode&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3 - Add The API Key
&lt;/h3&gt;

&lt;p&gt;For the integration to work, we need to add your Stripe API key to the app. You can find your keys by clicking on "Developers", on the bottom left corner of the Stripe dashboard, and going to the API keys tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fdevelopers-button-stripe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fdevelopers-button-stripe.png" width="521" height="826"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy your &lt;a href="https://stripe.com/docs/keys" rel="noopener noreferrer"&gt;Stripe account's Secret key&lt;/a&gt; and, in the SaaS template app's &lt;a href="https://anvil.works/docs/security/encrypting-secret-data?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;App Secrets&lt;/a&gt;, set the value of "stripe_test_api_key" to your key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fapp-secrets-location.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fapp-secrets-location.png" width="504" height="808"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4 - Creating A Pricing Table
&lt;/h3&gt;

&lt;p&gt;Next, we need to create a pricing table for our customers to use. Start in the Anvil app editor, &lt;a href="https://anvil.works/docs/deployment-new-ide/quickstart?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;publish this app&lt;/a&gt; and take a copy of the URL - we'll use this in later in this step.&lt;/p&gt;

&lt;p&gt;In the Stripe dashboard, &lt;a href="https://dashboard.stripe.com/test/products?active=true" rel="noopener noreferrer"&gt;navigate to the Products catalogue&lt;/a&gt;, select the &lt;a href="https://dashboard.stripe.com/test/pricing-tables" rel="noopener noreferrer"&gt;Pricing tables tab&lt;/a&gt;, and create a &lt;a href="https://stripe.com/docs/payments/checkout/pricing-table" rel="noopener noreferrer"&gt;pricing table&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the textbox under "Products" and select "Add new product". &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fadd-a-product.png" width="692" height="458"&gt;
&lt;/li&gt;
&lt;li&gt;Name your product 'Personal', give it a &lt;a href="https://stripe.com/docs/products-prices/how-products-and-prices-work#what-is-a-price" rel="noopener noreferrer"&gt;price&lt;/a&gt; and save it by clicking 'Add product'. Then, click 'Continue' onto the next step. &lt;/li&gt;
&lt;li&gt;In the Payment settings, under "Confirmation page", select "Don't show confirmation page" and enter your &lt;strong&gt;published app's URL&lt;/strong&gt;. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fpricing-table.png" width="800" height="471"&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Step 5 - Adding The Pricing Table To Your App
&lt;/h3&gt;

&lt;p&gt;Stripe's website should take you to your &lt;a href="https://dashboard.stripe.com/test/pricing-tables" rel="noopener noreferrer"&gt;pricing table's page (if not, follow this link and select your pricing table)&lt;/a&gt;. Now, we'll embed the pricing table in our SaaS app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the code for the pricing table. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fstripe-dashboard-pricing-table-code.png" width="800" height="378"&gt;
&lt;/li&gt;
&lt;li&gt;Open the StripePricing Form in the Anvil Editor. Then &lt;a href="https://anvil.works/docs/ui/components/forms#HTML-Forms-&amp;amp;-Custom-HTML-Forms?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;edit the custom HTML&lt;/a&gt; by clicking the three dots at the top of the designer. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fedit-html-button.png" width="800" height="314"&gt;
&lt;/li&gt;
&lt;li&gt;Paste the code into the StripePricing Form's custom HTML.&lt;/li&gt;
&lt;li&gt;Lastly, add &lt;code&gt;anvil-name="stripe-pricing-table"&lt;/code&gt; to the &lt;code&gt;stripe-pricing-table&lt;/code&gt; tag. The final HTML should look like this:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fstripe-pricing-html.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fstripe-pricing-html.png" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 6 - Setting Up The Webhooks
&lt;/h3&gt;

&lt;p&gt;We need Stripe to tell us when a new customer is created and when their subscription is updated so we can update our Users table with the Stripe subscription details. We'll use &lt;a href="https://www.redhat.com/en/topics/automation/what-is-a-webhook" rel="noopener noreferrer"&gt;webhooks&lt;/a&gt; to do this. &lt;a href="https://docs.stripe.com/webhooks/quickstart" rel="noopener noreferrer"&gt;There is a guide to setting up webhooks in Stripe here&lt;/a&gt; but let me give you brief instructions.&lt;/p&gt;
&lt;h4&gt;
  
  
  Customer Created
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;a href="https://dashboard.stripe.com/test/webhooks" rel="noopener noreferrer"&gt;Webhooks page&lt;/a&gt; in Stripe by selecting the "Developers" link in the bottom left and navigating to the webhooks tab. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fdevelopers-webhook-dashboard.png" width="800" height="455"&gt;
&lt;/li&gt;
&lt;li&gt;Click the "Create an event destination" button.&lt;/li&gt;
&lt;li&gt;Set the endpoint URL to your published app's URL with "/&lt;em&gt;/api/stripe/stripe_customer_created" added to the end - i.e. "&lt;a href="https://my-saas.anvil.app/" rel="noopener noreferrer"&gt;https://my-saas.anvil.app/&lt;/a&gt;&lt;/em&gt;/api/stripe/stripe_customer_created". &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fendpoint-url.png" width="800" height="711"&gt;
&lt;/li&gt;
&lt;li&gt;Then click "+ select events" and select "customer.created" under events to listen for. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fsearching-events.png" width="800" height="282"&gt;
&lt;/li&gt;
&lt;li&gt;From now on, this will call the &lt;code&gt;stripe_customer_created&lt;/code&gt; function in your Anvil app's StripeFunctions module when a customer is created. Here's an image of the set-up webhook:&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fwebhook-setup.png" width="543" height="779"&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Subscription Updated
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add another endpoint in Stripe.&lt;/li&gt;
&lt;li&gt;Set the endpoint URL to your published app's URL with "\/_/api/stripe/stripe_subscription_updated" added to the end i.e. "&lt;a href="https://my-saas.anvil.app/%5C_/api/stripe/stripe%5C_subscription%5C_updated" rel="noopener noreferrer"&gt;https://my-saas.anvil.app/\_/api/stripe/stripe\_subscription\_updated&lt;/a&gt;"&lt;/li&gt;
&lt;li&gt;Then select "customer.subscription.updated" under events to listen for.&lt;/li&gt;
&lt;li&gt;From now on, this will call the &lt;code&gt;stripe_subscription_updated&lt;/code&gt; function in the StripeFunctions Server Module every time a customer is created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Ffinished-webhooks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Ffinished-webhooks.png" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 7 - Setting Up The Customer Portal
&lt;/h3&gt;

&lt;p&gt;Let's quickly set up a way for users to manage their subscription. Go to the Stripe dashboard and use the search bar at the top to find the customer portal screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fcustomer-portal-location.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fcustomer-portal-location.png" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set up a &lt;a href="https://dashboard.stripe.com/settings/billing/portal" rel="noopener noreferrer"&gt;customer portal&lt;/a&gt;, activate the test link and copy it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fcustomer-portal-setup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fcustomer-portal-setup.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then open the SaaS app's AccountManagement form and point the "manage_subscription_link" component's URL to the copied link:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fmanage-subscription-button.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fmanage-subscription-button.png" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're going to let users manage their email address from the Account page of our app, so we'll disable the ability for users to change their email in their customer portal. The SaaS template syncs email updates with Stripe automatically. Back in the &lt;a href="https://dashboard.stripe.com/settings/billing/portal" rel="noopener noreferrer"&gt;customer portal&lt;/a&gt; config page, uncheck the "Email address" checkbox under customer information:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fcustomer-portal-email-checkbox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fcustomer-portal-email-checkbox.png" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With these steps completed, your Stripe integration is ready for testing.&lt;/p&gt;


&lt;h2&gt;
  
  
  Testing The App
&lt;/h2&gt;

&lt;p&gt;The template has a number of &lt;a href="https://anvil.works/docs/client/alerts-and-notifications#notifications?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;Notifications&lt;/a&gt; which will guide you through testing the app as a user. This will both test the integration we've set up and let you experience what the app is like as a user. &lt;a href="https://anvil.works/docs/editor#the-anvil-editor?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;Run the app&lt;/a&gt; and follow along with the in-app instruction notifications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fnotification-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fnotification-example.png" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a user flow diagram for you to see all the actions you can take with the template:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fuser-flow-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Ftemplates%2Fsaas-template%2Fuser-flow-diagram.png" width="800" height="848"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Making The App Your Own
&lt;/h2&gt;

&lt;p&gt;Now that your Stripe integration is set up and you've experienced the app from a user's perspective, it's time to make this app your own.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 - Remove The Template Notifications
&lt;/h3&gt;

&lt;p&gt;First, we can search (&lt;em&gt;ctrl+shift+F&lt;/em&gt;) for the "# TEMPLATE EXPLANATION ONLY" comments and delete the relevant code below.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2 - Using User Permissions
&lt;/h3&gt;

&lt;p&gt;For a SaaS app to earn money, you'll want to have premium features that are restricted to paid users on specific plans - this is where user permissions come in.&lt;/p&gt;
&lt;h4&gt;
  
  
  What's Included With The Template
&lt;/h4&gt;

&lt;p&gt;The template comes with a bespoke function and decorator designed to simplify managing user permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user_has_subscription&lt;/code&gt;: A function that works with &lt;a href="https://anvil.works/docs/api/anvil.server.html#callable?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;&lt;code&gt;@anvil.server.callable&lt;/code&gt;&lt;/a&gt;. It verifies whether the user's subscription is included in the list of subscriptions authorized to use the function decorated by &lt;code&gt;@anvil.server.callable&lt;/code&gt;. If permission is denied, a &lt;a href="https://anvil.works/docs/api/anvil.server#PermissionDenied?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;&lt;code&gt;PermissionDenied&lt;/code&gt;&lt;/a&gt; exception is thrown.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@catch_permission_errors&lt;/code&gt;: A decorator that catches any &lt;a href="https://anvil.works/docs/api/anvil.server#PermissionDenied?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;&lt;code&gt;anvil.server.PermissionDenied&lt;/code&gt;&lt;/a&gt; exceptions raised by the decorated client-side function. If permission is denied, it prompts the user to upgrade their subscription.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Using The Functions Together
&lt;/h4&gt;

&lt;p&gt;You can use &lt;code&gt;@anvil.server.callable&lt;/code&gt;, &lt;code&gt;user_has_subscription&lt;/code&gt; and &lt;code&gt;@catch_permission_errors&lt;/code&gt; together as follows:&lt;/p&gt;
&lt;h5&gt;
  
  
  1. You restrict access to a function with &lt;code&gt;@anvil.server.callable&lt;/code&gt; and &lt;code&gt;user_has_subscription&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;To restrict access to a premium function to users with a valid subscription, start by decorating the premium function with &lt;code&gt;@anvil.server.callable&lt;/code&gt;. You can pass &lt;code&gt;@anvil.server.callable&lt;/code&gt;'s &lt;code&gt;require_user&lt;/code&gt; argument &lt;code&gt;user_has_subscription&lt;/code&gt;. &lt;code&gt;user_has_subscription&lt;/code&gt; takes a list of allowed subscriptions and checks if the logged-in user’s subscription matches any entry in the list.&lt;/p&gt;

&lt;p&gt;From the template, this example function is only allowed to be run by users with a "personal" subscription:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Here's an example of a function that would require a paid subscription
&lt;/span&gt;&lt;span class="nd"&gt;@anvil.server.callable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;require_user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;user_has_subscription&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;personal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_percentage_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;percentage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the user has an active subscription which is in the allowed subscriptions passed to &lt;code&gt;user_has_subscription&lt;/code&gt;, the function will run. If they don’t meet the subscription requirement, a permissions error is raised and caught by &lt;code&gt;@catch_permission_errors&lt;/code&gt; - let me show you how to use &lt;code&gt;@catch_permission_errors&lt;/code&gt;.&lt;/p&gt;
&lt;h5&gt;
  
  
  2. You use &lt;code&gt;@catch_permission_errors&lt;/code&gt; on the client-side to prompt user
&lt;/h5&gt;

&lt;p&gt;With the server-side function restricted, it's time to prompt users to upgrade if they try to use a premium feature without the right subscription - for this, you can use &lt;code&gt;@catch_permission_errors&lt;/code&gt;. &lt;code&gt;@catch_permission_errors&lt;/code&gt; will catch any &lt;code&gt;anvil.server.PermissionDenied&lt;/code&gt; exceptions thrown by our server-side function and prompt users to upgrade if they don’t meet the subscription requirement.&lt;/p&gt;

&lt;p&gt;From the example in the template:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Catch_permission_errors catches exceptions that are thrown by a user not being subscribed and gives them a notification to upgrade
&lt;/span&gt;  &lt;span class="nd"&gt;@catch_permission_errors&lt;/span&gt;
  &lt;span class="c1"&gt;# This function is a simple example function to show you functionality that is gated behind a paywall
&lt;/span&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_button_click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;event_args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;This method is called when the button is clicked&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number_1_textbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number_2_textbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

      &lt;span class="c1"&gt;# This makes a call to a restricted function 
&lt;/span&gt;      &lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anvil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;calculate_percentage_of&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number_1_textbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;number_2_textbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And that's it, you can restrict any number of features this way.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3 - Take Stripe out of test mode
&lt;/h3&gt;

&lt;p&gt;When you're ready to go live, switch Stripe from &lt;a href="https://docs.stripe.com/test-mode" rel="noopener noreferrer"&gt;test mode&lt;/a&gt; to live mode.&lt;/p&gt;

&lt;p&gt;Next, update the app's account management link (configured in step 7) to use the &lt;a href="https://docs.stripe.com/customer-management/activate-no-code-customer-portal#url-parameters" rel="noopener noreferrer"&gt;customer portal's live link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, replace the API keys in your Anvil app with the production keys.&lt;/p&gt;


&lt;h1&gt;
  
  
  What next?
&lt;/h1&gt;

&lt;p&gt;Start building a product with Anvil! We love to see what you create with Anvil, so be sure to share your new apps on our &lt;a href="https://anvil.works/forum/c/show-and-tell" rel="noopener noreferrer"&gt;Show and Tell Forum&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://anvil.works/?utm_source=devto_using_saas_template" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;.&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>python</category>
      <category>saas</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using Layouts to Create a Multi-Page App</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Thu, 01 Aug 2024 11:08:21 +0000</pubDate>
      <link>https://dev.to/anvil/streamline-ui-design-with-anvils-reusable-layouts-4d6p</link>
      <guid>https://dev.to/anvil/streamline-ui-design-with-anvils-reusable-layouts-4d6p</guid>
      <description>&lt;h1&gt;
  
  
  Building reusable UIs with Layouts
&lt;/h1&gt;

&lt;p&gt;When you create a multi-page app, there will be parts of the UI that will be shared across multiple &lt;a href="https://anvil.works/docs/ui/forms?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Forms&lt;/a&gt; - for example, a navigation bar. &lt;a href="https://anvil.works/docs/ui/themes-and-layouts?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Layouts&lt;/a&gt; let you create user interfaces that multiple Forms can use. I'm going to show you how to create one.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll build a homepage Layout with a navigation sidebar, and we'll use it as the Layout for the other Forms in our app. When a user clicks a link in the sidebar, the app will open a new Form that has different content but the same navigation menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnkmu2x0oj25ozbd90b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjnkmu2x0oj25ozbd90b9.png" alt="The final app which uses a Layout to navigate between pages" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Layouts?
&lt;/h2&gt;

&lt;p&gt;In Anvil, a &lt;a href="https://anvil.works/docs/ui/layouts?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Layout&lt;/a&gt; is a Form that can be used by other Forms to define their structure. A Layout Form can have components added to it. Any Form using the same Layout will all have those same components. When you create a Layout Form, you add Slots into the design. Slots define where Forms using the Layout can add components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foexsscuclolhp4pywhp7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foexsscuclolhp4pywhp7.png" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along this tutorial you will need to know basic Python and you should know the basics of Anvil. If you're new to Anvil, why not &lt;a href="https://anvil.works/learn/tutorials/feedback-form?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;try our introductory Feedback Form tutorial&lt;/a&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  Contents
&lt;/h2&gt;

&lt;p&gt;These are the steps that we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Step 1 - Create an Anvil app&lt;/li&gt;
&lt;li&gt;
Step 2 - Create a homepage Layout&lt;/li&gt;
&lt;li&gt;
Step 3 - Create a navigation menu&lt;/li&gt;
&lt;li&gt;
Step 4 - Add a slot&lt;/li&gt;
&lt;li&gt;
Step 5 - Use the Layout&lt;/li&gt;
&lt;li&gt;
Step 6 - Wire up the navigation menu&lt;/li&gt;
&lt;li&gt;
Step 7 - Make the link look selected&lt;/li&gt;
&lt;li&gt;
Step 8 - Test the app&lt;/li&gt;
&lt;li&gt;
Step 9 - Optional: Change the homepage Layout&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1 - Create your Anvil app
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://anvil.works/login?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Log in&lt;/a&gt; to Anvil and click 'Blank App'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxkme26wg3v3jth73zaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxkme26wg3v3jth73zaj.png" width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you're asked what you'd like your page to look like, select Material Design 3:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6t568nhophe8ofni5gu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6t568nhophe8ofni5gu.png" width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the name at the top of the screen and give your app a name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4eufc0b6a1uimoqwkrt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4eufc0b6a1uimoqwkrt.png" alt="Rename your app by clicking on the title" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 - Create your homepage template
&lt;/h2&gt;

&lt;p&gt;Our app already has a Form added called Form1, which we'll turn into our homepage Layout. Open Form1 and change the name to "Homepage":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8vl4bqxibb86fk0ec2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8vl4bqxibb86fk0ec2h.png" alt="Rename Form1" width="481" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, click the three dot icon above the form and select "Use as layout":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05g79831rm9kb05z0nvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05g79831rm9kb05z0nvp.png" alt="Use Homepage as a Layout" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The first time you use Layouts in your app, you’ll need to migrate the app to use the new UI features. If the app hasn’t yet been migrated, you’ll see a popup message when you change your Form to a Layout. This is an irreversible change to our app, so please be aware if you’re migrating an app you’ve built with the old Anvil Designer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's add a description of our Layout in the form's configuration menu. This information shows up when deciding which template a new form should use. Click the three dot icon above the form again and select "Edit properties and events". Then add a description.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkmhhhsvduy5f4k7dbbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkmhhhsvduy5f4k7dbbu.png" alt="Editing the Homepage’s metadata" width="800" height="932"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's great. Next up, let's build a navigation UI in our ayout for other forms to inherit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 - Creating our navigation menu UI
&lt;/h2&gt;

&lt;p&gt;Let's start by adding a &lt;a href="https://anvil.works/docs/client/components/containers#columnpanel?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Column Panel&lt;/a&gt; into the sidebar of our Form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvkmgeywzlji7w304amx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvkmgeywzlji7w304amx.png" alt="Adding a column panel to our form" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we can drag two &lt;a href="https://anvil.works/docs/client/components/basic#link?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Link&lt;/a&gt; components into the Column Panel - one for each Form that will use this Layout. We'll change the first link's text to "About Us" and the second link's text to "Contact Us".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbmxl17l99o9paui08sxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbmxl17l99o9paui08sxr.png" alt="Adding links to our nav bar" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, let's give our app a title by dragging a Label into the title section on the top left of the &lt;code&gt;Homepage&lt;/code&gt; Form. Then change the Label's role to &lt;code&gt;Title&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2fux17thrk6oq1dkt8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft2fux17thrk6oq1dkt8p.png" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 - Adding a slot
&lt;/h2&gt;

&lt;p&gt;Now that we've built the Layout we want our other Forms to use, let's add a Slot. Slots define where components can be inserted by Forms that use the Layout.&lt;/p&gt;

&lt;p&gt;We’ll add a Slot to the &lt;code&gt;content_panel&lt;/code&gt; of our &lt;code&gt;Homepage&lt;/code&gt; by dragging in a “Slot” from Toolbox on to the right of the designer.&lt;/p&gt;

&lt;p&gt;Each Slot has a name. We can rename our slot using the object palette. Let's call it &lt;code&gt;main_slot&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvc4qimnm2efs3y4x4k7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvvc4qimnm2efs3y4x4k7.png" alt="Adding and renaming a Slot" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be aware that if you delete or rename a Slot from a Layout that is being used by another Form, any components that were inside that Slot will not know where to go. You can find them in the Orphaned Components Panel and add them back to your page. For more information, see our &lt;a href="https://anvil.works/docs/ui/layouts#orphaned-components?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;documentation on Layouts&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great, our Layout's UI is complete. Now it's time to create some Forms that use our Layout.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 - Using the Layout
&lt;/h2&gt;

&lt;p&gt;We're now going to create two Forms called "AboutUs" and "ContactUs" that use our Layout Form. Later, we'll add click event functions to the Links we added in the previous step so that they open the corresponding Form when clicked.&lt;/p&gt;

&lt;p&gt;First, we'll create &lt;code&gt;AboutUs&lt;/code&gt; by clicking "Add Form" in the &lt;a href="https://anvil.works/docs/editor#app-browser?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;App Browser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy99wq4rgm7bwga7ke8f7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy99wq4rgm7bwga7ke8f7.png" alt="Image description" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, select the Homepage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudhpl7m8h92xtre44icb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudhpl7m8h92xtre44icb.png" alt="Select the Homepage template." width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then rename the Form to "AboutUs", the same way we renamed the &lt;code&gt;Homepage&lt;/code&gt; Form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7nteqwi8hznvw4kdfn6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7nteqwi8hznvw4kdfn6.png" alt="The app browser with the AboutUs page created." width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, let's add a label to the main slot and change its text. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fci1xukpuckjdu2glft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fci1xukpuckjdu2glft.png" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repeat this process for the &lt;code&gt;ContactUs&lt;/code&gt; page, adding another label with some different text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsh8ejs0d4opjx0ldcpsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsh8ejs0d4opjx0ldcpsq.png" alt="The Contact Us form with some different text" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have two Forms using our Layout, all we have to do is wire up the sidebar links so they open the corresponding Form when clicked.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 - Wiring up the navigation menu
&lt;/h2&gt;

&lt;p&gt;Open the &lt;code&gt;Homepage&lt;/code&gt; Form and select the "About Us" link in the navigation menu. Let's first rename the Link so that it's easier to reference in code. In the floating Object Palette, click on &lt;code&gt;link_1&lt;/code&gt; and rename the Link to &lt;code&gt;about_us_link&lt;/code&gt;. Next, select &lt;code&gt;on click event&lt;/code&gt;, this will open up the code view for our Form and create an &lt;a href="https://anvil.works/docs/client/events?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;event handler&lt;/a&gt; function for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fladyrtg0mfokg8a0gz1k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fladyrtg0mfokg8a0gz1k.png" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the event function, we'll use the &lt;code&gt;open_form&lt;/code&gt; function to open our &lt;code&gt;AboutUs&lt;/code&gt; page by passing in the name of the Form as a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def about_us_link_click(self, **event_args):
  """This method is called when the link is clicked"""
  open_form('AboutUs')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, every time the "About Us" link is clicked, it will load the corresponding page. We will also do the same for the "Contact Us" link by renaming the link, adding the &lt;code&gt;click&lt;/code&gt; event and opening the relevant Form in the function.&lt;/p&gt;

&lt;p&gt;Lastly, let's create a &lt;code&gt;reset_links&lt;/code&gt; function for the Forms using our template to use. Create the function and inside, set every Link component's &lt;a href="https://anvil.works/docs/client/themes-and-styling/roles?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;role&lt;/a&gt; to a blank string:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def reset_links(self, **event_args):
  self.contact_us_link.role = ''
  self.about_us_link.role = ''
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7 - Making the Link look selected
&lt;/h2&gt;

&lt;p&gt;Our final step is to make it so that when we click one of the links in our navigation menu, it looks selected. This will make it easier to tell what page we are already on. &lt;/p&gt;

&lt;p&gt;Select the &lt;code&gt;AboutUs&lt;/code&gt; Form in the designer and in the &lt;a href="https://anvil.works/docs/editor#events?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;Events section&lt;/a&gt; of the properties panel, click the blue button next to the &lt;a href="https://anvil.works/docs/client/components#the-show-and-hide-events?utm_source=dev_to_using_layouts" rel="noopener noreferrer"&gt;"Show" event&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpicff086e7f9qtpj0l2v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpicff086e7f9qtpj0l2v.png" alt="Adding a Show event handler to our form" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open up the code view and add a function that will run every time the &lt;code&gt;AboutUs&lt;/code&gt; Form is &lt;a href="https://anvil.works/docs/client/components#the-show-and-hide-events" rel="noopener noreferrer"&gt;shown&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Inside the function, we can interact with the Layout our Form is using with &lt;code&gt;self.layout&lt;/code&gt;. This gives us the ability to call functions defined in our Layout and change the properties of the Layout's components. Let's reset the links and set the &lt;a href="https://dev.to/docs/ui/custom-styling/roles"&gt;role&lt;/a&gt; of the &lt;code&gt;Homepage.about_us_link&lt;/code&gt; to be "selected".&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def form_show(self, **event_args):
    """This method is called when the form is shown on the screen"""
    self.layout.reset_links()
    self.layout.about_us_link.role = 'selected'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Repeat this process for &lt;code&gt;ContactUs&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 8 - Testing the app
&lt;/h2&gt;

&lt;p&gt;To see the app in action, click the "Run" button at the top of the screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9wlo8wp3e8fig4hk613.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq9wlo8wp3e8fig4hk613.png" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click each link in the sidebar, and the relevant page should appear using our Layout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jcww9vb036h2ht0ms80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jcww9vb036h2ht0ms80.png" alt="Navigating between our different Forms" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 9 - Optional: Changing the Homepage Layout
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This part is optional! The best way to learn any new technology is to challenge your understanding. Why not challenge yourself to reinforce what you’ve learnt and learn more?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of the best things about Layouts is making a change to the Layout is instantly propagated to all forms using the Layout. So, why not make some changes to our homepage form and see how it affects the other forms. You could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add another link to the navigation sidebar and wire it up&lt;/li&gt;
&lt;li&gt;Add a slot to the sidebar in &lt;code&gt;Homepage&lt;/code&gt; so that other Forms using the Layout can add more links to the navigation menu&lt;/li&gt;
&lt;li&gt;Chain Layouts together. Try creating an "Admin" page which uses the &lt;code&gt;Homepage&lt;/code&gt; Layout and, in turn, make that a Layout. The admin page could have its own naigation menu inside the homepage's main slot with links for "Profile" and "Contact Preferences".&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Clone the App
&lt;/h2&gt;

&lt;p&gt;You can open the &lt;a href="https://anvil.works/build#clone:N5AOYXWUWTWMY6P3%3dNMROJLZXN4SXNXQSPM5GQDTK" rel="noopener noreferrer"&gt;source code for the finished Anvil app here&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://anvil.works/" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;.&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>python</category>
      <category>anvil</category>
    </item>
    <item>
      <title>Streamline UI design with Anvil’s reusable Layouts</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Wed, 17 Apr 2024 13:38:15 +0000</pubDate>
      <link>https://dev.to/anvil/streamline-ui-design-with-anvils-reusable-layouts-1pdn</link>
      <guid>https://dev.to/anvil/streamline-ui-design-with-anvils-reusable-layouts-1pdn</guid>
      <description>&lt;p&gt;&lt;a href="https://anvil.works/docs/ui/layouts" rel="noopener noreferrer"&gt;Layouts&lt;/a&gt; simplify UI design by letting you create reusable page structures that can be shared across multiple Forms. For example, you can design a Layout with a navigation bar, and any Form using this Layout will inherit the navigation bar. This makes UI building easier, faster and more consistent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjiaods5mm04wkbrh31o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjiaods5mm04wkbrh31o.png" alt="Image description" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What are the benefits?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Better reusability with shared Layouts
&lt;/h3&gt;

&lt;p&gt;A Layout can be used by many different Forms. This means when you edit a Layout, you'll instantly see the changes across the Forms that use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Simpler app navigation
&lt;/h3&gt;

&lt;p&gt;Layouts make building page navigation into your apps simpler than ever. Create a navigation bar in your Layout and share it between Forms. Then, you only need one line of code to navigate switch pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def page_1_link_click(self, **event_args):
    """This method is called when the link is clicked"""
    open_form("Page1")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This make building consistent navigation straightforward and fast.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Greater flexibility, less code
&lt;/h3&gt;

&lt;p&gt;You can create complex UI structures by nesting Layouts within each other.&lt;/p&gt;

&lt;p&gt;For example, say you want to extend a homepage Layout with a nested admin panel Layout. You can create an admin panel Layout that uses the homepage Layout, which in turn gets used by other Forms.&lt;/p&gt;


&lt;h2&gt;
  
  
  Ready to get started?
&lt;/h2&gt;

&lt;p&gt;We've got full &lt;a href="https://anvil.works/docs/ui/layouts" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; and a &lt;a href="https://anvil.works/learn/tutorials/using-layouts-to-create-multi-page-app" rel="noopener noreferrer"&gt;brand new tutorial&lt;/a&gt; to show you exactly how to get started with Layouts.&lt;/p&gt;


&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://anvil.works/" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;. Check out our 80 second overview of Anvil:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3V-3g1mQ5GY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;a href="https://anvil.works/build" rel="noopener noreferrer"&gt;Try Anvil for free!&lt;/a&gt;
&lt;/h2&gt;




&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>python</category>
      <category>web</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introducing Four Improvements To Anvil’s Custom Components</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Tue, 19 Dec 2023 15:23:47 +0000</pubDate>
      <link>https://dev.to/anvil/introducing-four-improvements-to-anvils-custom-components-11db</link>
      <guid>https://dev.to/anvil/introducing-four-improvements-to-anvils-custom-components-11db</guid>
      <description>&lt;h2&gt;
  
  
  We've made it simpler to build and use custom components in Anvil
&lt;/h2&gt;

&lt;p&gt;Anvil's Custom Components allow you to build reusable UI components and use them through your app and others. We've recently made them easier to use and more flexible in a few different ways. Let me walk you through them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Live Updates in the Editor&lt;/li&gt;
&lt;li&gt;Categorize and Add Toolbox Icons&lt;/li&gt;
&lt;li&gt;Categorize Custom Component Properties&lt;/li&gt;
&lt;li&gt;Custom containers are simpler to build&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  1. Live Updates in the Editor
&lt;/h3&gt;

&lt;p&gt;We've introduced live updates for custom components in the Anvil Editor. Now, as you make changes to your custom component, you'll instantly see those changes reflected in the designer. Components now run in the designer the same as they do in a live deployed app. This real-time behavior speeds up the development process and helps you fine-tune your components with ease.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kJu8KZKk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://anvil.works/blog/img/simpler-custom-components/progress-bar-example.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kJu8KZKk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://anvil.works/blog/img/simpler-custom-components/progress-bar-example.gif" width="800" height="360"&gt;&lt;/a&gt;&lt;a href="https://anvil.works/forum/t/progressbar-component-again/18656"&gt;Tobais’s progress bar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only does live updates mean the components reflect your changes immediately, it also has other benefits like exceptions being thrown and flagged to you immediately in the &lt;a href="https://anvil.works/docs/client/new-designer#live-custom-components?utm_source=dev-to_4_improvements_custom_components"&gt;designer output&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Categorize and Add Toolbox Icons
&lt;/h3&gt;

&lt;p&gt;We understand that as you add dependencies to your app, managing custom components in the toolbox can become challenging. To help you keep things organized, you can now &lt;a href="https://anvil.works/docs/client/custom-components#configuring-custom-components?utm_source=dev-to_4_improvements_custom_components"&gt;categorize custom components and change their icons&lt;/a&gt;. This makes them easier to locate and manage in the Editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PJEwuAXa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://anvil.works/blog/img/simpler-custom-components/styled-custom-components.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PJEwuAXa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://anvil.works/blog/img/simpler-custom-components/styled-custom-components.png" width="800" height="783"&gt;&lt;/a&gt;Custom components in the Toolbox&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Categorize Custom Component Properties
&lt;/h3&gt;

&lt;p&gt;In addition to categorizing components, you can now categorize your custom component's properties. This feature allows you to organize properties logically, making it simpler to configure your custom components. No more hunting for that one property buried deep in the list – categorize them for quick and easy access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JV8vMCfI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://anvil.works/blog/img/simpler-custom-components/component-properties.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JV8vMCfI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://anvil.works/blog/img/simpler-custom-components/component-properties.png" width="800" height="633"&gt;&lt;/a&gt;The menu for customising a property, including categorisation options&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Turn custom components into containers
&lt;/h3&gt;

&lt;p&gt;For the first time ever, it's possible for you to build your own &lt;a href="https://anvil.works/docs/client/custom-components/html-components#making-a-custom-component-a-container?utm_source=dev-to_4_improvements_custom_components"&gt;custom containers&lt;/a&gt;! You can write your own custom HTML components and turn them into containers so that other components can be dragged and dropped inside.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JJ7ZVDCd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://anvil-website-static.s3.eu-west-2.amazonaws.com/blog/simpler-custom-components/container-example.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JJ7ZVDCd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://anvil-website-static.s3.eu-west-2.amazonaws.com/blog/simpler-custom-components/container-example.gif" width="800" height="450"&gt;&lt;/a&gt;An example custom container&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/docs/client/custom-components/html-components#making-a-custom-component-a-container?utm_source=dev-to_4_improvements_custom_components"&gt;Check out the docs&lt;/a&gt; to learn how to build custom containers.&lt;/p&gt;




&lt;p&gt;With these new improvements, custom components in Anvil are easier to use, more flexible and more efficient than ever before. Try them out today and experience the power of Anvil's improved custom components for yourself! Happy app building!&lt;/p&gt;

&lt;h4&gt;&lt;a href="https://anvil.works/docs/client/custom-components#making-a-custom-component-a-container?utm_source=dev-to_4_improvements_custom_components"&gt;See the custom component docs -&amp;gt;&lt;/a&gt;&lt;/h4&gt;




&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://dev.to/"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;. Check out our 80 second overview of Anvil:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3V-3g1mQ5GY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://anvil.works/build"&gt;Try Anvil for free!&lt;/a&gt;
&lt;/h2&gt;





&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e7r_Krcc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--t0GUPtjs--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/458094/b913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>python</category>
      <category>webdev</category>
      <category>anvil</category>
      <category>news</category>
    </item>
    <item>
      <title>Build Better Python Web Apps With Your Data</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Fri, 03 Feb 2023 14:57:38 +0000</pubDate>
      <link>https://dev.to/anvil/build-better-python-web-apps-with-your-data-4l1</link>
      <guid>https://dev.to/anvil/build-better-python-web-apps-with-your-data-4l1</guid>
      <description>&lt;h1&gt;
  
  
  Build Better Python Web Apps With Your Data
&lt;/h1&gt;

&lt;p&gt;Do you want a quick introduction to &lt;a href="https://anvil.works/docs/working-with-files/data-files?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;Anvil's Data File service&lt;/a&gt;? Then &lt;strong&gt;check out our new 100 second video&lt;/strong&gt; where we plot data from a CSV file using &lt;a href="https://pandas.pydata.org/" rel="noopener noreferrer"&gt;Pandas&lt;/a&gt; and Anvil's Data Files service.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/TEUXht5kxgM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Anvil is &lt;strong&gt;free to use&lt;/strong&gt;. &lt;a href="https://anvil.works/build?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;Start building now!&lt;/a&gt;
&lt;/h4&gt;




&lt;h1&gt;
  
  
  Prefer text to video? Read on to learn how to use Data Files
&lt;/h1&gt;

&lt;p&gt;Python is great for working with data. With &lt;a href="https://anvil.works?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; you can build web apps to interact with datasets and machine-learning models entirely in Python.&lt;/p&gt;

&lt;p&gt;In this article, I’ll show you how to use Anvil’s &lt;a href="https://anvil.works/docs/working-with-files/data-files?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;Data Files service&lt;/a&gt; to attach static data to your web app. We’re going to upload a CSV dataset and plot the data from it using &lt;a href="https://pandas.pydata.org/" rel="noopener noreferrer"&gt;Pandas&lt;/a&gt;. Then, we’ll display the plot online for everyone to see - all in Python.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vniguvtqm6proz3i31b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vniguvtqm6proz3i31b.png" alt="Contents" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Uploading our CSV
&lt;/h2&gt;

&lt;p&gt;We start by uploading our dataset into our app’s &lt;a href="https://anvil.works/docs/working-with-files/data-files?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;Data Files service&lt;/a&gt;. I’m using some example data of Apple’s stock price over time which you can &lt;a href="https://anvil.works/articles/img/data-files-100-seconds/dataset.csv" rel="noopener noreferrer"&gt;&lt;strong&gt;download here&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Farticles%2Fdata-files-100-seconds%2Fuploading-file.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Farticles%2Fdata-files-100-seconds%2Fuploading-file.gif" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;Adding the CSV data to our app
  &lt;/p&gt;




&lt;h2&gt;
  
  
  Plotting our data
&lt;/h2&gt;

&lt;p&gt;Now, let’s write a &lt;a href="https://anvil.works/docs/server?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;server function&lt;/a&gt; called &lt;code&gt;plot_data&lt;/code&gt; to plot our CSV data. We can use the &lt;a href="https://anvil.works/docs/api/anvil.files#data_files?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;&lt;code&gt;data_files&lt;/code&gt;&lt;/a&gt; object to get the path to the file we just uploaded, and load it into Pandas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@anvil.server.callable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plot_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="c1"&gt;# Read the CSV file into a DataFrame using the Data Files path
&lt;/span&gt;  &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dataset.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We’ll use &lt;a href="https://plotly.com/python/pandas-backend/" rel="noopener noreferrer"&gt;Plotly's Pandas backend&lt;/a&gt; to plot our dataset as a line graph and return that figure from our server function.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@anvil.server.callable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plot_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="c1"&gt;# Read the CSV file into a DataFrame using the Data Files path
&lt;/span&gt;  &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dataset.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="c1"&gt;# Then plot the graph using the Plotly backend
&lt;/span&gt;  &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;fig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APPL Stock Price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Farticles%2Fdata-files-100-seconds%2Fplotting-data.gif" width="960" height="540"&gt;Writing server-side code to plot our data
  



&lt;h2&gt;
  
  
  Building our front-end
&lt;/h2&gt;

&lt;p&gt;Now let’s build a front-end to display our graph. Drag and drop a &lt;a href="https://anvil.works/docs/client/components/plots?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;Plot component&lt;/a&gt; onto the page from the &lt;a href="https://anvil.works/docs/editor?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;toolbox&lt;/a&gt; on the right.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Farticles%2Fdata-files-100-seconds%2Fbuilding-front-end.gif" width="960" height="540"&gt;Dragging and dropping a Plot component into our form
  


&lt;p&gt;Then switch to the app's &lt;a href="https://anvil.works/docs/client/python?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;front-end Python&lt;/a&gt; code. In the &lt;code&gt;__init__&lt;/code&gt; method, we call the &lt;code&gt;plot_data()&lt;/code&gt; server function we created earlier and set our &lt;a href="https://anvil.works/docs/api/anvil#Plot?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;plot's figure property&lt;/a&gt; to the graph that is returned.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="c1"&gt;# Set Form properties and Data Bindings.
&lt;/span&gt;  &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init_components&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# Any code you write here will run when the form opens.
&lt;/span&gt;  &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anvil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;plot_data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Farticles%2Fdata-files-100-seconds%2Ffront-end-code.gif" width="960" height="540"&gt;Writing the front-end code which gets our graph
  



&lt;h2&gt;
  
  
  Running our app
&lt;/h2&gt;

&lt;p&gt;When we run the app, it will load the dataset and plot it with Pandas.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Farticles%2Fdata-files-100-seconds%2Frunning-app.gif" width="960" height="540"&gt;Running our app to test it
  


&lt;p&gt;You can use Anvil’s Data Files to &lt;a href="https://anvil.works/learn/tutorials/deploy-machine-learning-model?utm_source=devto_data_files_100" rel="noopener noreferrer"&gt;load and run machine learning models&lt;/a&gt;, complicated datasets, and more. To find out more about Anvil and using Data Files, check out the links below.&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>crypto</category>
      <category>discuss</category>
    </item>
    <item>
      <title>This is how to deploy a machine learning model with Anvil</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Wed, 04 Jan 2023 17:24:59 +0000</pubDate>
      <link>https://dev.to/anvil/this-is-how-to-deploy-a-machine-learning-model-with-anvil-47c8</link>
      <guid>https://dev.to/anvil/this-is-how-to-deploy-a-machine-learning-model-with-anvil-47c8</guid>
      <description>&lt;h1&gt;
  
  
  Deploying your model to the web
&lt;/h1&gt;

&lt;p&gt;Deploying machine learning models is tricky. The skills used to create a model are very different to the skills needed to deploy the model for end-users to interact with. With Anvil, it’s easy to deploy ML models to the web, and we can do it &lt;strong&gt;entirely in Python - no need to wrestle with HTML, CSS, JavaScript or web hosting&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In this short tutorial, we'll use Anvil to turn an ML model into an interactive web application. We will use the classic &lt;a href="https://en.wikipedia.org/wiki/Iris_flower_data_set" rel="noopener noreferrer"&gt;iris classification problem&lt;/a&gt;, for which I have a pre-trained model using &lt;a href="https://scikit-learn.org" rel="noopener noreferrer"&gt;&lt;code&gt;sklearn&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://joblib.readthedocs.io" rel="noopener noreferrer"&gt;&lt;code&gt;joblib&lt;/code&gt;&lt;/a&gt; (if you want to see how I trained this model, &lt;a href="https://anvil.works/learn/tutorials/google-colab-to-web-app" rel="noopener noreferrer"&gt;check out this tutorial&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We will create an interactive web app that collects the iris measurements from the user, use our model to classify the flower, and return the classification back to our user. Here's what it will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fapp-demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fapp-demo.gif" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;Demo of the finished app
  &lt;/p&gt;

&lt;p&gt;For this tutorial you will need to know basic Python.&lt;/p&gt;

&lt;p&gt;These are the steps that we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 1 - Create your Anvil app&lt;/li&gt;
&lt;li&gt;Step 2 - Design your page&lt;/li&gt;
&lt;li&gt;Step 3 - Run Python code when you click the button&lt;/li&gt;
&lt;li&gt;Step 4 - Upload our model&lt;/li&gt;
&lt;li&gt;Step 5 - Configure our server environment&lt;/li&gt;
&lt;li&gt;Step 6 - Use our model&lt;/li&gt;
&lt;li&gt;Step 7 - Publish our app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 - Create your Anvil app
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/login"&gt;Log in&lt;/a&gt; to Anvil and click 'New Blank App'. Choose the Material Design theme.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wcmv2z6j1i9ltmumtje.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wcmv2z6j1i9ltmumtje.png" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;Location of the Create App button
  &lt;/p&gt;

&lt;p&gt;First, name the app. Click on the name at the top of the screen and give it a name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixkqi77b4ot5wo1fx7iy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixkqi77b4ot5wo1fx7iy.png" width="800" height="422"&gt;&lt;/a&gt;&lt;br&gt;Rename your app by clicking on the title
  &lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 - Design your page
&lt;/h2&gt;

&lt;p&gt;To classify the species of iris a flower comes from, we need to collect several measurements, so let's design the user interface for entering that data.&lt;/p&gt;

&lt;p&gt;We construct the UI by dragging-and-dropping components from the Toolbox. Let's start by dropping a Card into our form -- this will be a neat container for the other components. Then let's add a Label and a TextBox into the card component:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fdrag-drop-textbox.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fdrag-drop-textbox.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;Dragging a Card component, Label component and TextBox component into Form1
  &lt;/p&gt;

&lt;p&gt;Next we will set up the label and TextBox components to collect the sepal length. Select the &lt;code&gt;Label&lt;/code&gt; we just added and, in the properties panel on the right, change the text to 'Sepal length: '. Then select the &lt;code&gt;TextBox&lt;/code&gt; we added and change the name to &lt;code&gt;sepal_length&lt;/code&gt;, and the placeholder text to '(cm)'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fediting-textbox.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fediting-textbox.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;Editing the Label and TextBox
  &lt;/p&gt;

&lt;p&gt;Repeat this process adding labels and text boxes for the other parameters we need: &lt;strong&gt;sepal width&lt;/strong&gt;, &lt;strong&gt;petal length&lt;/strong&gt; and &lt;strong&gt;petal width&lt;/strong&gt;. This will capture all the information we need to classify each iris flower.&lt;/p&gt;

&lt;p&gt;Next, let's add a Button to run the classifier. Name it &lt;code&gt;categorise_button&lt;/code&gt; and change the text to 'Categorise'. Clicking this button will trigger a Python function to classify the iris measurements using our model. (We'll set that up in a moment.)&lt;/p&gt;

&lt;p&gt;Finally, let's add a Label where we'll display our results. Put it below the button, call it &lt;code&gt;species_label&lt;/code&gt; and untick the &lt;code&gt;visible&lt;/code&gt; tick box in the properties panel so it doesn't appear immediately. In step 3 we will create an event handler function that makes the label visible, and uses it to display data returned from our model.&lt;/p&gt;

&lt;p&gt;Our app should now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoxp4rlp77gfhnjqhdk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoxp4rlp77gfhnjqhdk5.png" width="800" height="451"&gt;&lt;/a&gt;&lt;br&gt;How our app's UI should look
  &lt;/p&gt;

&lt;p&gt;In the next step we will add some code to control what happens when a user pushes the &lt;strong&gt;Categorise&lt;/strong&gt; button.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 - Run Python code when you click the button
&lt;/h2&gt;

&lt;p&gt;We want our &lt;code&gt;categorise_button&lt;/code&gt; to do something when it's clicked, so let's add a click event.&lt;/p&gt;

&lt;p&gt;With the button selected, go to the bottom of the properties panel. Then click the blue button with two arrows in it next to the click event box. This will open our code view and create a function called &lt;code&gt;categorise_button_click()&lt;/code&gt;. From now on, every time the button is clicked by a user, this function will be called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fclick-event.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fclick-event.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;br&gt;Click event being added to the Categorise button
  &lt;/p&gt;

&lt;p&gt;We want to call a function on our app's server side to interact with our model, and pass it the measurements the user has entered into our web app. When the server function returns our answer, we'll display it as text on the &lt;code&gt;species_label&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;To do this we add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;categorise_button_click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;event_args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;This method is called when the button is clicked&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Call the server function and pass it the iris measurements
&lt;/span&gt;    &lt;span class="n"&gt;iris_category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;anvil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;predict_iris&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sepal_length&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sepal_width&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;petal_length&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;petal_width&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# If a category is returned set our species 
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;iris_category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;species_label&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
      &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;species_label&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The species is &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;iris_category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we have a basic UI and functionality, let's upload our model to our example app.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 4 - Upload our model
&lt;/h2&gt;

&lt;p&gt;Data Files are files that you, as the app developer, can attach to your app. These files are available in your &lt;a href="https://dev.to/docs/server"&gt;Server Modules&lt;/a&gt;. You can do this via the built-in &lt;a href="https://dev.to/docs/working-with-files/data-files"&gt;Data File Service&lt;/a&gt;. The Data Files service is useful for machine learning models, large datasets and data that stays constant.&lt;/p&gt;

&lt;p&gt;In our Anvil app, click the &lt;strong&gt;+&lt;/strong&gt; button in the Sidebar Menu, and select &lt;strong&gt;Data Files&lt;/strong&gt;:&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgjnfhvky4evgvv97yw7t.png" width="800" height="634"&gt;Click the + button in the Sidebar Menu, and select Data Files
  


&lt;p&gt;Then, let's upload a classification model for our UI to use. For this guide, I've created an example iris classifier model - download it here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/learn/tutorials/img/deploy-a-machine-learning-model/knn.skmodel" rel="noopener noreferrer"&gt;https://anvil.works/learn/tutorials/img/deploy-a-machine-learning-model/knn.skmodel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you've downloaded this file to your computer, upload it into your app's Data Files by clicking the &lt;strong&gt;Upload&lt;/strong&gt; button and selecting the model from your files.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Fdocs%2Fworking-with-files%2Fdata-files%2Fuploading-a-file.gif" width="800" height="451"&gt;Uploading the model to our Data Files
  


&lt;p&gt;Next, let's create a server function that uses the model to classify our user's data.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5 - Configure our server environment
&lt;/h2&gt;

&lt;p&gt;Now that our model is uploaded, we need to configure the &lt;a href="https://anvil.works/docs/server/custom-packages" rel="noopener noreferrer"&gt;server environment&lt;/a&gt; to include all the packages we need to run it.&lt;/p&gt;

&lt;p&gt;We'll start by selecting settings from the Sidebar Menu and opening 'Python versions'.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fghlltzivunfba7e0h59u.png" width="" height=""&gt;Selecting the Python version
  


&lt;p&gt;Then, in the Python version dropdown, select 'Python 3.10'. Under 'Base packages', select 'Edit requirements.txt directly'.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnkemrti3l7rxwvsspjs.png" width="800" height="676"&gt;Editing our app's environment
  


&lt;p&gt;Finally, paste the following list of requirements into the text box:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;joblib==1.1.0
numpy==1.21.6
scikit-learn==1.1.2
scipy==1.9.0
sklearn==0.0
threadpoolctl==3.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With our server environment configured, it's time to start using our model in a function.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 6 - Access our saved model file
&lt;/h2&gt;

&lt;p&gt;We can access our saved model file using the &lt;a href="https://anvil.works/docs/api/anvil.files" rel="noopener noreferrer"&gt;&lt;code&gt;data_files&lt;/code&gt;&lt;/a&gt; API in a &lt;a href="https://anvil.works/docs/server" rel="noopener noreferrer"&gt;Server Module&lt;/a&gt;. Then we can load it into &lt;a href="https://scikit-learn.org" rel="noopener noreferrer"&gt;scikit-learn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To start, let's add a Server Module to our app by clicking '+ Add Server Module' in the &lt;a href="https://anvil.works/docs/editor#app-browser" rel="noopener noreferrer"&gt;App Browser&lt;/a&gt;.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh31furbmgctymwjf5655.png" width="384" height="480"&gt;Position of the '+ Add Server Module' button in the App Browser
  


&lt;p&gt;At the top of our server module, let's import the &lt;code&gt;joblib&lt;/code&gt; library we need to load our model and import &lt;code&gt;load_iris&lt;/code&gt; from &lt;code&gt;sklearn&lt;/code&gt;'s built-in iris dataset.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_iris&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;joblib&lt;/span&gt;

&lt;span class="c1"&gt;# Loading sklearn's built-in iris dataset
&lt;/span&gt;&lt;span class="n"&gt;iris&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_iris&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With the dataset loaded, we can create a function that takes our iris data and returns the name of the iris species. Let’s create a &lt;code&gt;predict_iris&lt;/code&gt; function and add the &lt;a href="https://anvil.works/docs/server#calling-server-functions-from-client-code" rel="noopener noreferrer"&gt;&lt;code&gt;@anvil.server.callable&lt;/code&gt;&lt;/a&gt; decorator so the function can be called from our app's client-side code.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@anvil.server.callable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;predict_iris&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sepal_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sepal_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;petal_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;petal_width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Inside the &lt;code&gt;predict_iris&lt;/code&gt; function, we'll load our model from the Data Files service. To do this, we will get the path to the model file on disk using &lt;code&gt;data_files['knn.skmodel']&lt;/code&gt;, we can then use &lt;a href="https://joblib.readthedocs.io/en/latest/generated/joblib.load.html" rel="noopener noreferrer"&gt;&lt;code&gt;joblib.load()&lt;/code&gt;&lt;/a&gt; to reconstruct our model from the file.&lt;/p&gt;

&lt;p&gt;Once we have reconstructed our model, pass our iris flower data to &lt;a href="https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html#sklearn.neighbors.KNeighborsClassifier.predict" rel="noopener noreferrer"&gt;&lt;code&gt;model.predict()&lt;/code&gt;&lt;/a&gt; and return the name of the flower.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@anvil.server.callable&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;predict_iris&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sepal_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sepal_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;petal_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;petal_width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;joblib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;knn.skmodel&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="n"&gt;classification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="n"&gt;sepal_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sepal_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;petal_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;petal_width&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;classification&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Back in step 3 of this tutorial, we wrote &lt;code&gt;anvil.server.call('predict_iris', ...)&lt;/code&gt; in our &lt;code&gt;categorise_button_click()&lt;/code&gt; function on the &lt;a href="https://anvil.works/articles/client-vs-server" rel="noopener noreferrer"&gt;client side&lt;/a&gt;. Adding the &lt;a href="https://anvil.works/docs/server#calling-server-functions-from-client-code" rel="noopener noreferrer"&gt;&lt;code&gt;@anvil.server.callable&lt;/code&gt;&lt;/a&gt; decorator to our server-side &lt;code&gt;predict_iris()&lt;/code&gt; function means it can be called from the client.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 7 - Publish our app
&lt;/h2&gt;

&lt;p&gt;Now we've finished our app, all we have to do is test it and &lt;a href="https://anvil.works/beta-docs/deployment-new-ide/quickstart#publish-your-app" rel="noopener noreferrer"&gt;publish&lt;/a&gt; it online for people to use.&lt;/p&gt;

&lt;p&gt;Let's quickly test the app to make sure it works. We can click the 'Run' button in the top right of the &lt;a href="https://anvil.works/beta-docs/editor#the-anvil-editor" rel="noopener noreferrer"&gt;Anvil Editor&lt;/a&gt; to run the app in split view and try it out.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2FTesting-data-files-app.gif" width="1024" height="1024"&gt;Running the app in the editor
  


&lt;p&gt;If there is an issue, the App Console will appear and show the exception that was thrown. You can click on the exception and the editor will take you to the line of code that caused it.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Ffixing-a-bug.gif" width="1024" height="1024"&gt;Fixing a bug
  


&lt;p&gt;With the app tested, we can click the 'Publish' button at the top right of the editor. Then select 'Publish this app' and use the public URL provided or enter your own.&lt;/p&gt;


  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanvil-website-static.s3.eu-west-2.amazonaws.com%2Flearn%2Ftutorials%2Fdeploy-a-machine-learning-model%2Fpublishing-app.gif" width="400" height="224"&gt;Publishing the finished app
  


&lt;p&gt;That's it, our app is now finished and online for anyone to use!&lt;/p&gt;


&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We now have an interactive app based on our machine learning model. We've designed a UI, written client-side Python, uploaded our machine learning model, written server-side code that uses our model and deployed the app online for anyone to use - all with nothing but Python!&lt;/p&gt;
&lt;h3&gt;
  
  
  Clone the App
&lt;/h3&gt;

&lt;p&gt;For those of you who want to see the source code for this app:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/build#clone:GMXRQOGCBCX6YXWT%3dZC4GCEYQEOO5B7V3PMDOGZT5" rel="noopener noreferrer"&gt;https://anvil.works/build#clone:GMXRQOGCBCX6YXWT%3dZC4GCEYQEOO5B7V3PMDOGZT5&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I've added some images to improve the final app. To do this I simply added an &lt;a href="https://anvil.works/docs/client/components/basic#image" rel="noopener noreferrer"&gt;image component&lt;/a&gt; to the app and set its source based on the returned iris classification. The sources I used are in the below challenges section.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  What next?
&lt;/h2&gt;

&lt;p&gt;Head to the &lt;a href="https://anvil.works/learn" rel="noopener noreferrer"&gt;Anvil Learning Centre&lt;/a&gt; for more tutorials, or head to our &lt;a href="https://anvil.works/learn/examples" rel="noopener noreferrer"&gt;examples page&lt;/a&gt; to see how to build some complex apps in Anvil.&lt;/p&gt;

&lt;p&gt;Why not check out the &lt;a href="https://anvil.works/forum" rel="noopener noreferrer"&gt;Anvil Community Forum&lt;/a&gt;? There are a lot of knowledgeable people there, and it's a great place to get help.&lt;/p&gt;
&lt;h3&gt;
  
  
  Optional: Challenge yourself
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This part is optional!&lt;/strong&gt; The best way to learn any new technology is to challenge your understanding. Why not challenge yourself to reinforce what you’ve learnt and learn more?&lt;/p&gt;
&lt;h4&gt;
  
  
  Challenge 1 - Add an image to your app
&lt;/h4&gt;

&lt;p&gt;Add an &lt;a href="https://anvil.works/docs/client/components/basic#image" rel="noopener noreferrer"&gt;&lt;code&gt;Image&lt;/code&gt; component&lt;/a&gt; to your app's interface and set its source based on the returned iris classification. You can set the source of the image to one of the following three URLs in the &lt;code&gt;categorise_button_click&lt;/code&gt; function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Virginica: &lt;a href="https://upload.wikimedia.org/wikipedia/commons/f/f8/Iris_virginica_2.jpg" rel="noopener noreferrer"&gt;https://upload.wikimedia.org/wikipedia/commons/f/f8/Iris_virginica_2.jpg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Versicolor: &lt;a href="https://upload.wikimedia.org/wikipedia/commons/2/27/Blue_Flag%2C_Ottawa.jpg" rel="noopener noreferrer"&gt;https://upload.wikimedia.org/wikipedia/commons/2/27/Blue_Flag%2C_Ottawa.jpg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Setosa: &lt;a href="https://upload.wikimedia.org/wikipedia/commons/5/56/Kosaciec_szczecinkowaty_Iris_setosa.jpg" rel="noopener noreferrer"&gt;https://upload.wikimedia.org/wikipedia/commons/5/56/Kosaciec_szczecinkowaty_Iris_setosa.jpg&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Challenge 2 - Store your results in a Data Table
&lt;/h4&gt;

&lt;p&gt;Try storing the classification results in Anvil's built-in database.&lt;/p&gt;

&lt;p&gt;Hint: Add a &lt;a href="https://anvil.works/docs/data-tables" rel="noopener noreferrer"&gt;Data Table&lt;/a&gt; to your app to store the classification results. Then, use Anvil's &lt;a href="https://anvil.works/docs/api/anvil.tables#Table" rel="noopener noreferrer"&gt;&lt;code&gt;add_row()&lt;/code&gt;&lt;/a&gt; in your app's &lt;code&gt;predict_iris&lt;/code&gt; function. This will add a row to your database each time a classification is completed.&lt;/p&gt;
&lt;h4&gt;
  
  
  Challenge 3 - Turn the app into an HTTP API
&lt;/h4&gt;

&lt;p&gt;You can build an HTTP API for your app by decorating the &lt;code&gt;predict_iris&lt;/code&gt; function with the &lt;a href="https://anvil.works/docs/http-apis/creating-http-endpoints#the-http-endpoint-decorator" rel="noopener noreferrer"&gt;&lt;code&gt;@anvil.server.http_endpoint&lt;/code&gt; decorator&lt;/a&gt;. Why not try creating an API for your app for other people to use?&lt;/p&gt;


&lt;h2&gt;
  
  
  New to Anvil?
&lt;/h2&gt;

&lt;p&gt;If you're new to Anvil, welcome! &lt;a href="https://anvil.works/" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Yes – Python that runs in the browser. Python that runs on the server. Python that builds your UI. A drag-and-drop UI editor. We even have a built-in Python database, in case you don’t have your own.&lt;/p&gt;

&lt;p&gt;Why not have a play with the app builder? &lt;strong&gt;It's free!&lt;/strong&gt; Click here to get started:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/build" rel="noopener noreferrer"&gt;https://anvil.works/build&lt;/a&gt;&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>Introducing Anvil’s Python-based Data Files API</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Thu, 08 Dec 2022 20:06:41 +0000</pubDate>
      <link>https://dev.to/anvil/introducing-anvils-python-based-data-files-ap-87k</link>
      <guid>https://dev.to/anvil/introducing-anvils-python-based-data-files-ap-87k</guid>
      <description>&lt;h1&gt;
  
  
  The New Data Files Service
&lt;/h1&gt;

&lt;p&gt;Python has lots of great libraries for interacting with files, large datasets and machine learning models. And today we are happy to announce a new feature in Anvil to make it easier than ever to use large files and machine learning models in your Python code. &lt;strong&gt;We are launching Anvil's new &lt;a href="https://dev.to/docs/working-with-files/data-files"&gt;Data Files Service&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---ENw2tWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqy5rodrd7tv6pcodtjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---ENw2tWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqy5rodrd7tv6pcodtjn.png" alt="Data Files Panel" width="880" height="600"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What are we releasing?
&lt;/h2&gt;

&lt;p&gt;Data Files are files that you, as the app developer, can attach to your app. These files are available in your &lt;a href="https://anvil.works/docs/server#server-modules"&gt;Server Modules&lt;/a&gt;. Data Files can be uploaded and accessed using the new built-in Data Files service.&lt;/p&gt;

&lt;p&gt;There's a new API to access and manage Data Files. Accessing files is as simple as using square brackets:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;data = pandas.read_csv(data_files['my_spreadsheet.csv'])&lt;/code&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  What can I use it for?
&lt;/h1&gt;

&lt;p&gt;Any application that uses bulk static data! For example, you might build a dashboard that queries a CSV of static data using &lt;code&gt;pandas&lt;/code&gt;. Or you might build an app around a machine-learning model, which loads a file of stored weights into PyTorch, Tensorflow or scikit-learn.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get started right now
&lt;/h2&gt;

&lt;p&gt;Check out our &lt;a href="https://dev.to/docs/working-with-files/data-files/quickstart"&gt;Quick Start guide&lt;/a&gt; to learn about using the Data Files Service.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://anvil.works/docs/working-with-files/data-files/quickstart"&gt;Data Files Quickstart Guide&lt;/a&gt;
&lt;/h4&gt;




&lt;h2&gt;
  
  
  Deploy a machine learning model
&lt;/h2&gt;

&lt;p&gt;We've got a brand new tutorial to show you how to deploy an ML model and use it in your Anvil app:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://anvil.works/learn/tutorials/deploy-machine-learning-model"&gt;Deploy an ML model with the Data Files Service&lt;/a&gt;
&lt;/h4&gt;




&lt;h2&gt;
  
  
  More about Anvil
&lt;/h2&gt;

&lt;p&gt;If you're new here, welcome! &lt;a href="https://dev.to/"&gt;Anvil&lt;/a&gt; is a platform for building full-stack web apps with nothing but Python. No need to wrestle with JS, HTML, CSS, Python, SQL and all their frameworks – just &lt;strong&gt;build it all in Python&lt;/strong&gt;. Check out our 80 second overview of Anvil:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3V-3g1mQ5GY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://anvil.works/build"&gt;Try Anvil for free!&lt;/a&gt;
&lt;/h2&gt;





&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JS5U2W8C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--t0GUPtjs--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/458094/b913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>python</category>
      <category>webdev</category>
      <category>programming</category>
      <category>news</category>
    </item>
    <item>
      <title>Python Web Applications in 80 Seconds</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Tue, 01 Nov 2022 13:42:36 +0000</pubDate>
      <link>https://dev.to/anvil/python-web-applications-in-80-seconds-1gnm</link>
      <guid>https://dev.to/anvil/python-web-applications-in-80-seconds-1gnm</guid>
      <description>&lt;h2&gt;
  
  
  The Pythonic Way to Build Web Apps: Anvil in 80 Seconds
&lt;/h2&gt;

&lt;p&gt;Do you want to learn how Python can be used for web development? Then check out our new 80 second video:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3V-3g1mQ5GY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Anvil is &lt;strong&gt;free to use&lt;/strong&gt;. &lt;a href="https://anvil.works/build"&gt;Start building now!&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Prefer text to video? Read on to learn all about Anvil
&lt;/h2&gt;

&lt;p&gt;If you can write Python, then &lt;a href="https://anvil.works/"&gt;Anvil&lt;/a&gt; is all you need to build and deploy web applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wj15GWfI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/intro.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wj15GWfI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/intro.gif" alt="Article Thumbnail" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Anvil, you can design your app with a drag-and-drop UI builder and write Python code that runs in the web browser and on the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_EYsHyD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/design-your-pages.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_EYsHyD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/design-your-pages.gif" alt="Dragging a new button into the UI and writing client-side Python" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anvil comes with a built-in database backed by &lt;a href="https://www.postgresql.org/"&gt;Postgres&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9NSK-4yB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iz4o04a4px5mzhws7elx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9NSK-4yB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iz4o04a4px5mzhws7elx.png" alt="A database table backed by Postgres" width="880" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can put it all &lt;a href="https://anvil.works/docs/deployment/quickstart"&gt;online with two clicks&lt;/a&gt; — just choose a web address:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DdcS35P2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/online-in-two-clicks.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DdcS35P2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/online-in-two-clicks.gif" alt="Deploying the app online" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use all the normal &lt;a href="https://anvil.works/docs/server/packages"&gt;Python libraries&lt;/a&gt; to process your data or connect to external databases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0rf9iiv5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/python-libraries.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0rf9iiv5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/python-libraries.gif" alt="Import all the normal Python libraries" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anvil helps you save time and stay secure by providing &lt;a href="https://anvil.works/docs/users"&gt;built-in user authentication&lt;/a&gt; for your apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gPwe4CHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/built-in-auth.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gPwe4CHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/built-in-auth.gif" alt="Anvil comes with built-in user authentication" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect code running anywhere on the Internet to your Anvil app using the &lt;a href="https://anvil.works/docs/uplink"&gt;Anvil Uplink&lt;/a&gt;. This includes code running in &lt;a href="https://jupyter.org/"&gt;Jupyter notebooks&lt;/a&gt;, &lt;a href="https://colab.research.google.com/?utm_source=scs-index"&gt;Google Colab&lt;/a&gt;, &lt;a href="https://aws.amazon.com/sagemaker/"&gt;AWS SageMaker&lt;/a&gt;, IoT devices and your own computer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O11cbWKL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/connect-external-code.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O11cbWKL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/connect-external-code.gif" alt="Connect your Anvil app to code running anywhere on the internet" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anvil has a built-in integration with &lt;a href="https://stripe.com/gb"&gt;Stripe&lt;/a&gt; that means you can run a payment form with a single line of code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HXc-_gcq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/stripe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HXc-_gcq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/stripe.gif" alt="Run a payment form with a single line of code." width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your apps can send and receive email using the built-in &lt;a href="https://anvil.works/docs/email"&gt;Email Service&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WJhWbEOQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/send-email.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WJhWbEOQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/send-email.gif" alt="Send and receive email with the built in Email Service" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can connect your Anvil app with services from &lt;a href="https://anvil.works/docs/integrations/google"&gt;Google&lt;/a&gt;, &lt;a href="https://anvil.works/docs/integrations/microsoft"&gt;Microsoft&lt;/a&gt;, &lt;a href="https://anvil.works/docs/integrations/facebook"&gt;Facebook&lt;/a&gt; and much, much more!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TJnU-53N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/google-microsoft-okta.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TJnU-53N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/google-microsoft-okta.gif" alt="You can connect your app with many different services" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anvil lets you collaborate with other developers and manage changes with &lt;a href="https://anvil.works/docs/version-control"&gt;git-backed version control&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dKhyfYtG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/version-control.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dKhyfYtG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/version-control.gif" alt='Collaborate with other developers"' width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/beta-docs/deployment-new-ide/environments"&gt;Create environments&lt;/a&gt; for production, staging and development and deploy each one separately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uj0Ak5oR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/environments.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uj0Ak5oR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://anvil-website-static.s3.eu-west-2.amazonaws.com/articles/anvil-in-80-seconds/environments.gif" alt="Create multiple environments" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can deploy the Anvil Editor on-site with an &lt;a href="https://anvil.works/docs/overview/enterprise"&gt;Enterprise plan&lt;/a&gt;. You can develop in the cloud and &lt;a href="https://anvil.works/docs/deployment"&gt;deploy Anvil apps online&lt;/a&gt;. You can also deploy apps on your own hardware with the open-source framework — &lt;a href="https://github.com/anvil-works/anvil-runtime"&gt;check it out on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wYJHQrQy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://newsignature.com/wp-content/uploads/2020/08/github-logo-tile-300x211.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wYJHQrQy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://newsignature.com/wp-content/uploads/2020/08/github-logo-tile-300x211.png" alt="Check out the open-source framework on GitHub" width="300" height="211"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;Why not have a play with the app builder? &lt;strong&gt;It’s free!&lt;/strong&gt; Click here to get started:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://anvil.works/build"&gt;Get building&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want more quality developer content?&lt;br&gt;
Follow me for more software development content!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JS5U2W8C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--t0GUPtjs--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/458094/b913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>programming</category>
      <category>startup</category>
    </item>
    <item>
      <title>Connect Your Pico W To The Internet And Control It From The Web</title>
      <dc:creator>Ryan</dc:creator>
      <pubDate>Mon, 25 Jul 2022 10:50:47 +0000</pubDate>
      <link>https://dev.to/anvil/connect-your-pico-w-to-the-internet-and-control-it-from-the-web-492l</link>
      <guid>https://dev.to/anvil/connect-your-pico-w-to-the-internet-and-control-it-from-the-web-492l</guid>
      <description>&lt;p&gt;I recently made a new video showing how to take your &lt;a href="https://www.raspberrypi.com/news/raspberry-pi-pico-w-your-6-iot-platform/" rel="noopener noreferrer"&gt;brand new Pico W&lt;/a&gt;, connect it securely to the internet, and control it from a web interface — all in Python with &lt;a href="https://anvil.works/" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check out the video or the text version of the video below.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Video
&lt;/h1&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/DDvzzMyYxCM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want more quality developer content?&lt;br&gt;
Follow me for more software development content!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Text Version
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00jdi4n214vx43gi60g3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00jdi4n214vx43gi60g3.png" alt="Article Thumbnail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next evolution of the hugely popular Raspberry Pi Pico microcontroller is here. The Raspberry Pi Pico W adds on-board wifi making it perfect for creating IoT devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In 3 steps, I’m going to teach you how to create and deploy a simple web app, so you can learn how to control your Pico W remotely.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The app will be a simple online app with a single button that makes the LED on the Pico flash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft74mtv2dadhryhz5u7vm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft74mtv2dadhryhz5u7vm.gif" alt="Using the finished app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Creating an Anvil app to control our Pico
&lt;/h2&gt;

&lt;p&gt;We’ll build the web app with Anvil, the platform for building web apps with nothing but Python.&lt;/p&gt;

&lt;p&gt;For the first step, we’ll start by creating the Anvil app that will wirelessly control our Pico. We’ll go to &lt;a href="https://anvil.works/build" rel="noopener noreferrer"&gt;anvil.works/build&lt;/a&gt; and create a new blank app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqf31sjd5ea00vnbq9hfb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqf31sjd5ea00vnbq9hfb.gif" alt="Creating a new blank app"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Click the name of the app at the top of the editor and change it to “Pico App”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fod82t7lwx0lc0ec3m8yt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fod82t7lwx0lc0ec3m8yt.gif" alt="Renaming the app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, let’s enable the &lt;a href="https://anvil.works/docs/uplink" rel="noopener noreferrer"&gt;Uplink&lt;/a&gt;. We’ll use the Uplink to connect to our Pico.&lt;/p&gt;

&lt;p&gt;Click the add features button in the editor’s side bar and select the Uplink.&lt;/p&gt;

&lt;p&gt;Next, we’ll click the ‘Enable server Uplink’ button.&lt;/p&gt;

&lt;p&gt;Copy the Uplink key, we’ll be using this in a Python Script on our Pico later to establish the connection between our App and the Pico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcz7u3h6y9b35vw4k0q8g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcz7u3h6y9b35vw4k0q8g.gif" alt="Enabling the Uplink and copying the Uplink key"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now the Uplink is enabled in our Anvil app let’s move on to step 2 and set up our Pico.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Setting up our Pico
&lt;/h2&gt;

&lt;p&gt;To setup our Pico we need to install the Anvil firmware.&lt;/p&gt;

&lt;p&gt;To start, we’ll hold down the BOOTSEL button on the Pico and plug it into our computer.&lt;/p&gt;

&lt;p&gt;Release BOOTSEL once the Pico’s drive appears on your computer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl71uzmpshihzst5fr73g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl71uzmpshihzst5fr73g.gif" alt="Connecting the Pico to our computer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we’ll download Anvil’s Pico firmware file (pico-w-anvil-v-complete.uf2) from the following link:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/anvil-works/anvil-pico/releases" rel="noopener noreferrer"&gt;https://github.com/anvil-works/anvil-pico/releases&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once it’s downloaded, copy the file onto the Pico’s drive. Our Pico will reboot once the files are copied over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fvramf9ysxomrztt4vr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fvramf9ysxomrztt4vr.gif" alt="Adding the  raw `pico-w-anvil-v0.1.2-complete.uf2` endraw  firmware file to our pico"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the Pico’s drive and edit the boot.py and the main.py file.&lt;/p&gt;

&lt;p&gt;In the boot.py file, edit the Wifi connection credentials to match your Wifi network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76qzkvk54y2sa6si60vy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76qzkvk54y2sa6si60vy.gif" alt="Editing boot.py and adding our wifi credentials"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, in the main.py file, underneath the import statements, add the Uplink key we copied earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rjzxb2csylkigcsyh5a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rjzxb2csylkigcsyh5a.gif" alt="Adding the Uplink kay to main.py"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main.py is where any functions you want to run on your Pico device are stored.&lt;/p&gt;

&lt;p&gt;As a default, Anvil’s main.py file for the Pico includes a &lt;code&gt;pico_fn&lt;/code&gt; function. It’s a simple function that makes the light on the Pico flash and demonstrates that you can pass Python objects from your Anvil app to your Pico.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@anvil.pico.callable decorator&lt;/code&gt; lets your Anvil app know that this function is available to call from the web. The &lt;code&gt;pico_fn&lt;/code&gt; function is the one we’ll be calling from our web app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@anvil.pico.callable(is_async=True)
async def pico_fn(n):
    # Output will go to the Pico W serial port
    print(f"Called local function with argument: {n}")

    # Blink the LED and then double the argument and return it.
    for i in range(10):
        led.toggle()
        await a.sleep_ms(50)
    return n * 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Save both boot.py and main.py.&lt;/p&gt;

&lt;p&gt;Reboot the Pico to save the updates by ejecting the disk and reconnecting the Pico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6o4b1dmjb2dxk693wp8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6o4b1dmjb2dxk693wp8.gif" alt="Rebooting the Pico W"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rebooting the Pico W&lt;br&gt;
The Pico will flash a few times to indicate it is connected to the internet.&lt;/p&gt;

&lt;p&gt;Let’s go back to the Anvil app we created earlier&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 3— Creating a UI and publishing to the web
&lt;/h2&gt;

&lt;p&gt;In the designer, we’ll drag and drop a button into our app’s form. We’ll change the text to ‘Flash the lights’ and style it by changing its role to &lt;code&gt;primary-color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we’ll add a text box and set its type to number. This will let the users of our app input a number and pass the data to our Pico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e90l8sws3zw87shde1d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e90l8sws3zw87shde1d.gif" alt="Adding a Button component and a TextBox component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Double click the button in the designer. This will add a function to our client-side code which will be called every time the button is clicked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5hn3f19j5yp8i7ermjr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5hn3f19j5yp8i7ermjr.gif" alt="Adding a Button component and a TextBox component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the function, let’s call the &lt;code&gt;pico_fn&lt;/code&gt; function which is inside our pico’s main.py file.&lt;/p&gt;

&lt;p&gt;We’ll pass our Pico function the number the user of our web app enters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdncatpqx5eryt16t5gur.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdncatpqx5eryt16t5gur.gif" alt="Calling the  raw `pico_fn` endraw  function in our click event function"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; def button_1_click(self, **event_args):
    """This method is called when the button is clicked"""
    anvil.server.call("pico_fn", self.text_box_1.text)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we’ve got the functionality sorted, we can deploy this app online by clicking the publish button in the top right of the editor. Let’s select the ‘Add public URL’ and change the URL to meaningful.&lt;/p&gt;

&lt;p&gt;If we navigate to the URL we chose and press our apps button, the LEDs on the Pico will now flash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7bl7u6589em7a6s2gbg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7bl7u6589em7a6s2gbg.gif" alt="Publishing our app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! We now have our Pico microcontroller connected to the internet with a deployed web app that controls it. Check out the link below to see the finished Anvil app:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://anvil.works/build#clone:UU2QIYDJCCUMPHIY=DLI6CTZ5CBL3US575ZVTOPWB" rel="noopener noreferrer"&gt;https://anvil.works/build#clone:UU2QIYDJCCUMPHIY=DLI6CTZ5CBL3US575ZVTOPWB&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I’ve just shown you how to control your Pico W from the web with nothing but Python and Anvil.&lt;/p&gt;

&lt;p&gt;Anvil is free to use — head on over to &lt;a href="https://anvil.works/pico" rel="noopener noreferrer"&gt;anvil.works/pico&lt;/a&gt; today to see more examples and the full documentation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Want more quality developer content?&lt;br&gt;
Follow me for more software development content!&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__458094"&gt;
    &lt;a href="/codingwithryan" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458094%2Fb913a90e-46cd-4803-9a09-4e679b2f0021.png" alt="codingwithryan image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/codingwithryan"&gt;Ryan&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/codingwithryan"&gt;Software developer. Tech enthusiast. Follow me for Python, Anvil and software development content.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;br&gt;
&lt;/blockquote&gt;

</description>
      <category>raspberrypi</category>
      <category>python</category>
      <category>iot</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
