One place for hosting & domains

      Web

      How To Install the Etherpad Collaborative Web Editor on Ubuntu 20.04


      Introduction

      Etherpad is a web application that enables real-time collaborative text editing in the browser. It is written in Node.js and can be self-hosted on a variety of platforms and operating systems.

      In this tutorial we will install Etherpad on an Ubuntu 20.04 server, using the SQLite database engine to store our data. We’ll also install and configure Nginx to act as a reverse proxy for the application, and we’ll fetch and install SSL certificates from the Let’s Encrypt certificate authority to enable secure HTTPS connections to our Etherpad instance.

      Prerequisites

      Before starting this tutorial, you will need the following:

      • An Ubuntu 20.04 server, with a non-root, sudo-enabled user, and with the UFW firewall enabled. Please read our Initial Server Setup with Ubuntu 20.04 to learn more about setting up these requirements.
      • Node.js installed, version 14 or higher. See option 2 of How To Install Node.js on Ubuntu 20.04 to learn how to install an up-to-date version of Node.js using NodeSource packages.
      • A domain name pointed at your server’s public IP address. This should be something like example.com or etherpad.example.com, for instance.

      Note: If you’re using DigitalOcean, our DNS Documentation can help you get your domain name set up in the control panel.

      When you have the prerequisites in place, continue to Step 1, where we’ll download and configure the Etherpad application.

      Step 1 — Downloading and Configuring Etherpad

      To install Etherpad, you’ll need to download the source code, install dependencies, and configure systemd to run the server.

      The Etherpad maintainers recommend running the software as its own user, so your first step will be to create a new etherpad user using the adduser command:

      • sudo adduser --system --group --home /opt/etherpad etherpad

      This creates a --system user, meaning that it can’t log in directly and has no password or shell assigned. We give it a home directory of /opt/etherpad, which is where we’ll download and configure the Etherpad software. We also create an etherpad group using the --group flag.

      You now need to run a few commands as the etherpad user. To do so, you’ll use the sudo command to open a bash shell as the etherpad user. Then you’ll change directories (cd) to /opt/etherpad:

      • sudo -u etherpad bash
      • cd /opt/etherpad

      Your shell prompt will update to show that you’re the etherpad user. It should look similar to etherpad@host:~$.

      Now clone the Etherpad repository into /opt/etherpad using Git:

      • git clone --branch master https://github.com/ether/etherpad-lite.git .

      This will pull the master branch of the Etherpad source code into the current directory (.). When that’s done, run Etherpad’s installDeps.sh script to install the dependencies:

      This can take a minute. When it’s done, you’ll need to manually install one last dependency. We need to cd into the Etherpad src folder and install the sqlite3 package in order to use SQLite as our database.

      First, change into the src directory:

      Then install the sqlite3 package using npm:

      Your final task as the etherpad user is to update the Etherpad settings.json file to use SQLite for its database, and to work well with Nginx. Move back up to the /opt/etherpad directory:

      Then open the settings file using your favorite text editor:

      The file is formatted as JSON, but with extensive comments throughout explaining each setting. There’s a lot you can configure, but for now we’re interested in two values that update the database configuration:

      settings.json

        "dbType": "dirty",
        "dbSettings": {
          "filename": "var/dirty.db"
        },
      

      Scroll down and look for the dbType and dbSettings section, shown here. Update the settings to sqlite and a filename of your choice, like the following:

      settings.json

        "dbType": "sqlite",
        "dbSettings": {
          "filename": "var/sqlite.db"
        },
      

      Finally, scroll down some more, find the trustProxy setting, and update it to true:

      settings.json

      "trustProxy": true,
      

      Save and close the settings file. In nano you can save and close by typing CTRL+O then ENTER to save, and CTRL+X to exit.

      When that’s done, be sure to exit the etherpad user’s shell:

      You’ll be returned to your normal user’s shell.

      Etherpad is installed and configured. Next we’ll create a systemd service to start and manage the Etherpad process.

      Step 2 — Creating a Systemd Service for Etherpad

      In order to start Etherpad on boot and to manage the process using systemctl, we need to create a systemd service file. Open up the new file in your favorite text editor:

      • sudo nano /etc/systemd/system/etherpad.service

      We’re going to create a service definition based on information in Etherpad’s documentation wiki. The How to deploy Etherpad Lite as a service page gives an example configuration that needs just a few changes to make it work for us.

      Add the following content into your text editor, then save and close the file:

      /etc/systemd/system/etherpad.service

      [Unit]
      Description=Etherpad, a collaborative web editor.
      After=syslog.target network.target
      
      [Service]
      Type=simple
      User=etherpad
      Group=etherpad
      WorkingDirectory=/opt/etherpad
      Environment=NODE_ENV=production
      ExecStart=/usr/bin/node --experimental-worker /opt/etherpad/node_modules/ep_etherpad-lite/node/server.js
      Restart=always
      
      [Install]
      WantedBy=multi-user.target
      

      This file gives systemd the information it needs to run Etherpad, including the user and group to run it as, and the command used to start the process (ExecStart=...).

      After closing the file, reload the systemd daemon to pull in the new configuration:

      • sudo systemctl daemon-reload

      Next, enable the etherpad service. This means the service will start up whenever your server reboots:

      • sudo systemctl enable etherpad

      And finally, we can start the service:

      • sudo systemctl start etherpad

      Check that the service started properly using systemctl status:

      • sudo systemctl status etherpad

      Output

      ● etherpad.service - Etherpad, a collaborative web editor. Loaded: loaded (/etc/systemd/system/etherpad.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2021-09-09 14:12:43 UTC; 18min ago Main PID: 698 (node) Tasks: 13 (limit: 1136) Memory: 152.0M CGroup: /system.slice/etherpad.service └─698 /usr/bin/node --experimental-worker /opt/etherpad/node_modules/ep_etherpad-lite/node/server.js

      The output should indicate that the service is active (running).

      Etherpad is now running, but it is unavailable to the public because port 9001 is blocked by your firewall. In the next step we’ll make Etherpad public by setting up Nginx as a reverse proxy in front of the Etherpad process.

      Step 3 — Installing and Configuring Nginx

      Putting a web server such as Nginx in front of your Node.js server can improve performance by offloading caching, compression, and static file serving to a more efficient process. We’re going to install Nginx and configure it to proxy requests to Etherpad, meaning it will take care of handing requests from your users to Etherpad and back again.

      First, refresh your package list, then install Nginx using apt:

      • sudo apt update
      • sudo apt install nginx

      Allow traffic to ports 80 and 443 (HTTP and HTTPS) using the “Nginx Full” UFW application profile:

      • sudo ufw allow "Nginx Full"

      Output

      Rule added Rule added (v6)

      Next, open up a new Nginx configuration file in the /etc/nginx/sites-available directory. We’ll call ours etherpad.conf but you could use a different name:

      • sudo nano /etc/nginx/sites-available/etherpad.conf

      Paste the following into the new configuration file, being sure to replace your_domain_here with the domain that is pointing to your Etherpad server. This will be something like etherpad.example.com, for instance.

      /etc/nginx/sites-available/etherpad.conf

      server {
          listen       80;
          listen       [::]:80;
          server_name  your_domain_here;
      
          access_log  /var/log/nginx/etherpad.access.log;
          error_log   /var/log/nginx/etherpad.error.log;
      
          location / {
              proxy_pass         http://127.0.0.1:9001;
              proxy_buffering    off;
              proxy_set_header   Host $host;
              proxy_pass_header  Server;
      
              # proxy headers
              proxy_set_header    X-Real-IP $remote_addr;
              proxy_set_header    X-Forwarded-For $remote_addr;
              proxy_set_header    X-Forwarded-Proto $scheme;
              proxy_http_version  1.1;
      
              # websocket proxying
              proxy_set_header  Upgrade $http_upgrade;
              proxy_set_header  Connection "upgrade";
          }
      }
      

      This configuration is loosely based on a configuration provided on the Etherpad wiki. It is HTTP-only for now, as we’ll let Certbot take care of configuring SSL in the next step. The rest of the config sets up logging locations and then passes all traffic along to http://127.0.0.1:9001, the Etherpad instance we started up in the previous step. We also set various headers that are required for well-behaved proxying and for websockets (persistent HTTP connections that enable real-time two-way communication) to work through a proxy.

      Save and close the file, then enable the configuration by linking it into /etc/nginx/sites-enabled/:

      • sudo ln -s /etc/nginx/sites-available/etherpad.conf /etc/nginx/sites-enabled/

      Use nginx -t to verify that the configuration file syntax is correct:

      [secondary_lable Output]
      nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
      nginx: configuration file /etc/nginx/nginx.conf test is successful
      

      And finally, reload the nginx service to pick up the new configuration:

      • sudo systemctl reload nginx

      Your Etherpad site should now be available on plain HTTP, and it will look something like this:

      The default homepage of an Etherpad instance, with a button for

      Now that we have our site up and running over HTTP, it’s time to secure the connection with Certbot and Let’s Encrypt certificates.

      Step 4 — Installing Certbot and Setting Up SSL Certificates

      Thanks to Certbot and the Let’s Encrypt free certificate authority, adding SSL encryption to our Etherpad app will take only two commands.

      First, install Certbot and its Nginx plugin:

      • sudo apt install certbot python3-certbot-nginx

      Next, run certbot in --nginx mode, and specify the same domain you used in the Nginx server_name config:

      • sudo certbot --nginx -d your_domain_here

      You’ll be prompted to agree to the Let’s Encrypt terms of service, and to enter an email address.

      Afterwards, you’ll be asked if you want to redirect all HTTP traffic to HTTPS. It’s up to you, but this is generally recommended and safe to do.

      After that, Let’s Encrypt will confirm your request and Certbot will download your certificate:

      Output

      Congratulations! You have successfully enabled https://etherpad.example.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=etherpad.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/etherpad.example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/etherpad.example.com/privkey.pem Your cert will expire on 2021-12-06. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Certbot will automatically reload Nginx to pick up the new configuration and certificates. Reload your site and it should switch you over to HTTPS automatically if you chose the redirect option.

      The default Etherpad editor, with a textbox and placeholder text

      You’re done! Try out your new Etherpad editor and invite some collaborators.

      Conclusion

      In this tutorial we set up Etherpad, with Nginx and Let’s Encrypt SSL certificates. Your Etherpad is now ready to use, but there’s more configuration you may want to do, including adding authenticated users, adding plugins, and customizing the user interface through skins.

      Your SQLite-backed Etherpad instance will be able to handle a moderate number of active users, but if you anticipate very high traffic, you may want to look into configuring a MySQL or PostgreSQL database instead.

      All of these configuration options are documented on the official Etherpad wiki.



      Source link

      Core Web Vitals Do’s and Don’ts


      How to Join

      This Tech Talk is free and open to everyone. Register below to get a link to join the live stream or receive the video recording after it airs.

      Date Time RSVP
      September 14, 2021 11 a.m.–12 p.m. ET / 3–4 p.m. GMT

      About the Talk

      User experience is now a critical Google ranking factor. While blazing fast web pages have a higher chance of appearing at the top in search results, speed alone doesn’t boost SEO.

      Explore how modern eCommerce design and infrastructure optimization work together to help you get more (and happier!) customers.

      What You’ll Learn

      • Secret optimization recipes that satisfy both search crawlers and real users
      • Best practices to optimize loading (LCP), interactivity (FID), and visual stability (CLS)
      • Passing the Core Web Vitals assessment with Progressive Web Apps (PWA)
      • Selecting the right server infrastructure and content delivery network (CDN) for healthy Core Web Vitals

      This Talk is Designed For

      • Magento developers
      • E-commerce store owners
      • Anyone building or managing an eCommerce website

      Prerequisites

      • Familiarity with Magento and cloud infrastructure setup
      • Familiar with basic web optimization principles

      Resources

      Core Web Vitals: Largest Contentful Paint (LCP), First Input Delay (FID), and Cumulative Layout Shift (CLS)
      Core Web Vitals: Your Store Better Run Fast in May 2021
      The latest page experience update, Google Search Central
      How to Scale Your E-Commerce Business With GoMage and DigitalOcean [Tech Talk]

      Exploring headless solutions or implementing one? Meet industry experts and fellow Magento developers, online business leaders, and PWA practitioners for live sessions and networking. Take a deeper dive into PWA and eCommerce, get your free ticket here.

      About the Presenters

      Yuriy Protsiuk, Product Owner, GoMage PWA Storefront
      Yuriy drives product success through defining business vision of the product, anticipating business needs, and managing the day-to-day routine of the GoMage PWA development team.

      Austin Black, Solutions Engineer, DigitalOcean
      Austin is a technical expert in software development, information security, and disaster recovery. He loves finding creative solutions to complex problems.

      To join the live Tech Talk, register here.



      Source link

      How To Create Your First Web Application Using Flask and Python 3


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Flask is a lightweight Python web framework that provides useful tools and features for creating web applications in the Python Language. It gives developers flexibility and is an accessible framework for new developers because you can build a web application quickly using only a single Python file. Flask is also extensible and doesn’t force a particular directory structure or require complicated boilerplate code before getting started.

      Learning Flask will allow you to quickly create web applications in Python. You can take advantage of Python libraries to add advanced features to your web application, like storing your data in a database, or validating web forms.

      In this tutorial, you’ll build a small web application that renders HTML text on the browser. You’ll install Flask, write and run a Flask application, and run the application in development mode. You’ll use routing to display various web pages that serve different purposes in your web application. You’ll also use view functions to allow users to interact with the application through dynamic routes. Finally, you’ll use the debugger to troubleshoot errors.

      Prerequisites

      Step 1 — Installing Flask

      In this step, you’ll activate your Python environment and install Flask using the pip package installer.

      First, activate your programming environment if you haven’t already:

      Once you have activated your programming environment, install Flask using the pip install command:

      Once the installation is complete, you will see a list of installed packages in the last parts of the output, similar to the following:

      Output

      ... Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, click, flask Successfully installed Jinja2-3.0.1 MarkupSafe-2.0.1 Werkzeug-2.0.1 click-8.0.1 flask-2.0.1 itsdangerous-2.0.1

      This means that installing Flask also installed several other packages. These packages are dependencies Flask needs to perform different functions.

      You’ve created the project folder, a virtual environment, and installed Flask. You can now move on to setting up a simple application.

      Step 2 — Creating a Simple Application

      Now that you have your programming environment set up, you’ll start using Flask. In this step, you’ll make a small Flask web application inside a Python file, in which you’ll write HTML code to display on the browser.

      In your flask_app directory, open a file named app.py for editing, use nano or your favorite text editor:

      Write the following code inside the app.py file:

      flask_app/app.py

      
      from flask import Flask
      
      app = Flask(__name__)
      
      
      @app.route('/')
      def hello():
          return '<h1>Hello, World!</h1>'
      

      Save and close the file.

      In the above code block, you first import the Flask object from the flask package. You then use it to create your Flask application instance, giving it the name app. You pass the special variable __name__, which holds the name of the current Python module. This name tells the instance where it’s located; you need this because Flask sets up some paths behind the scenes.

      Once you create the app instance, you can use it to handle incoming web requests and send responses to the user. @app.route is a decorator that turns a regular Python function into a Flask view function, which converts the function’s return value into an HTTP response to be displayed by an HTTP client, such as a web browser. You pass the value '/' to @app.route() to signify that this function will respond to web requests for the URL /, which is the main URL.

      The hello() view function returns the string '<h1>Hello, World!</h1>' as an HTTP response.

      You now have a simple Flask application in a Python file called app.py, in the next step, you will run the application to see the result of the hello() view function rendered in a web browser.

      Step 3 — Running the Application

      After creating the file that contains the Flask application, you’ll run it using the Flask command line interface to start the development server and render on the browser the HTML code you wrote as a return value for the hello() view function in the previous step.

      First, while in your flask_app directory with your virtual environment activated, tell Flask where to find the application (app.py in your case) using the FLASK_APP environment variable with the following command (on Windows, use set instead of export):

      Then specify that you want to run the application in development mode (so you can use the debugger to catch errors) with the FLASK_ENV environment variable:

      • export FLASK_ENV=development

      Lastly, run the application using the flask run command:

      Once the application is running, the output will be something like this:

      Output

      * Serving Flask app "app" (lazy loading) * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 296-353-699

      The preceding output has several pieces of information, such as:

      • The name of the application you’re running ("app").
      • The environment in which the application is being run (development).
      • Debug mode: on signifies that the Flask debugger is running. This is useful when developing because it provides detailed error messages when things go wrong, which makes troubleshooting easier.
      • The application is running locally on the URL http://127.0.0.1:5000/. 127.0.0.1 is the IP that represents your machine’s localhost and :5000 is the port number.

      Open a browser and type in the URL http://127.0.0.1:5000/. You will see the text Hello, World! in an <h1> heading as a response. This confirms that your application is successfully running.

      If you want to stop the development server, press CTRL+C.

      Warning: Flask uses a simple web server to serve your application in a development environment, which also means that the Flask debugger is running to make catching errors easier. You should not use this development server in a production deployment. See the Deployment Options page on the Flask documentation for more information. You can also check out this Flask deployment tutorial with Gunicorn or this one with uWSGI or you can use DigitalOcean App Platform to deploy your Flask application by following the How To Deploy a Flask App Using Gunicorn to App Platform tutorial.

      To continue developing the app.py application, leave the development server running and open another terminal window. Move into the flask_app directory, activate the virtual environment, set the environment variables FLASK_ENV and FLASK_APP, and continue to the next steps. (These commands are listed earlier in this step.)

      Note: When opening a new terminal, or when you close the one you are running the development server on and want to rerun it, it is important to remember activating the virtual environment and setting the environment variables FLASK_ENV and FLASK_APP for the flask run command to work properly.

      You only need to run the server once in one terminal window.

      While a Flask application’s development server is already running, it is not possible to run another Flask application with the same flask run command. This is because flask run uses the port number 5000 by default, and once it is taken, it becomes unavailable to run another application on so you would receive an error similar to the following:

      Output

      OSError: [Errno 98] Address already in use

      To solve this problem, either stop the server that’s currently running via CTRL+C, then run flask run again, or if you want to run both applications at the same time, you can pass a different port number to the -p argument, for example, to run another application on port 5001 use the following command:

      With this you can have one application running on http://127.0.0.1:5000/ and another one on http://127.0.0.1:5001/ if you want to.

      You now have a small Flask web application. You’ve run your application and displayed information on the web browser. Next, you’ll learn about routes and how to use them to serve multiple web pages.

      Step 4 — Routes and View Functions

      In this step, you’ll add a few routes to your application to display different pages depending on the requested URL. You’ll also learn about view functions and how to use them.

      A route is a URL you can use to determine what the user receives when they visit your web application on their browser. For example, http://127.0.0.1:5000/ is the main route that might be used to display an index page. The URL http://127.0.0.1:5000/about may be another route used for an about page that gives the visitor some information about your web application. Similarly, you can create a route that allows users to sign in to your application at http://127.0.0.1:5000/login.

      Your Flask application currently has one route that serves users who request the main URL (http://127.0.0.1:5000/). To demonstrate how to add a new web page to your application, you will edit your application file to add another route that provides information on your web application at http://127.0.0.1:5000/about.

      First, open your app.py file for editing:

      Edit the file by adding the following highlighted code at the end of the file:

      flask_app/app.py

      from flask import Flask
      
      app = Flask(__name__)
      
      
      @app.route('/')
      def hello():
          return '<h1>Hello, World!</h1>'
      
      
      @app.route('/about/')
      def about():
          return '<h3>This is a Flask web application.</h3>'
      

      Save and close the file.

      You added a new function called about(). This function is decorated with the @app.route() decorator that transforms it into a view function that handles requests for the http://127.0.0.1:5000/about endpoint.

      With the development server running, visit the following URL using your browser:

      http://127.0.0.1:5000/about
      

      You will see the text This is a Flask web application. rendered in an <h3> HTML heading.

      You can also use multiple routes for one view function. For example, you can serve the index page at both / and /index/. To do this, open your app.py file for editing:

      Edit the file by adding another decorator to the hello() view function:

      flask_app/app.py

      from flask import Flask
      
      app = Flask(__name__)
      
      @app.route('/')
      @app.route('/index/')
      def hello():
          return '<h1>Hello, World!</h1>'
      
      @app.route('/about/')
      def about():
          return '<h3>This is a Flask web application.</h3>'
      

      Save and close the file.

      After adding this new decorator, you can access the index page at both http://127.0.0.1:5000/ and http://127.0.0.1:5000/index.

      You now understand what routes are, how to use them to make view functions, and how to add new routes to your application. Next, you’ll use dynamic routes to allow users to control the application’s response.

      Step 5 — Dynamic Routes

      In this step, you’ll use dynamic routes to allow users to interact with the application. You’ll make a route that capitalizes words passed through the URL, and a route that adds two numbers together and displays the result.

      Normally, users don’t interact with a web application by manually editing the URL. Rather, the user interacts with elements on the page that lead to different URLs depending on the user’s input and action, but for the purposes of this tutorial, you will edit the URL to demonstrate how to make the application respond differently with different URLs.

      First, open your app.py file for editing:

      If you allow the user to submit something to your web application, such as a value in the URL as you are going to do in the following edit, you should always keep in mind that your app should not directly display untrusted data (data the user submits). To display user data safely, use the escape() function that comes with the markupsafe package, which was installed along with Flask.

      Edit app.py and add the following line to the top of the file, above the Flask import:

      flask_app/app.py

      from markupsafe import escape
      from flask import Flask
      
      # ...
      

      Then, add the following route to the end of the file:

      flask_app/app.py

      # ...
      
      @app.route('/capitalize/<word>/')
      def capitalize(word):
          return '<h1>{}</h1>'.format(escape(word.capitalize()))
      

      Save and close the file.

      This new route has a variable section <word>. This tells Flask to take the value from the URL and pass it to the view function. The URL variable <word> passes a keyword argument to the capitalize() view function. The argument has the same name as the URL variable (word in this case). With this you can access the word passed through the URL and respond with a capitalized version of it using the capitalize() method in Python.

      You use the escape() function you imported earlier to render the word string as text. This is important to avoid Cross Site Scripting (XSS) attacks. If the user submits malicious JavaScript instead of a word, escape() will it render as text and the browser will not run it, keeping your web application safe.

      To display the capitalized word inside an <h1> HTML heading, you use the format() Python method, for more on this method, see How To Use String Formatters in Python 3

      With the development server running, open your browser and visit the following URLs. You can replace the highlighted words with any word of your choice.

      http://127.0.0.1:5000/capitalize/hello
      http://127.0.0.1:5000/capitalize/flask
      http://127.0.0.1:5000/capitalize/python
      

      You can see the word in the URL capitalized in an <h1> tag on the page.

      You can also use multiple variables in a route. To demonstrate this, you will add a route that adds two positive integer numbers together and displays the result.

      Open your app.py file for editing:

      Add the following route to the end of the file:

      flask_app/app.py

      # ...
      
      @app.route('/add/<int:n1>/<int:n2>/')
      def add(n1, n2):
          return '<h1>{}</h1>'.format(n1 + n2)
      

      Save and close the file.

      In this route, you use a special converter int with the URL variable (/add/<int:n1>/<int:n2>/) which only accepts positive integers. By default, URL variables are assumed to be strings and are treated as such.

      With the development server running, open your browser and visit the following URL:

      http://127.0.0.1:5000/add/5/5/
      

      The result will be the sum of the two numbers (10 in this case).

      You now have an understanding of how to use dynamic routes to display different responses in a single route depending on the requested URL. Next, you’ll learn how to troubleshoot and debug your Flask application in case of an error.

      Step 6 — Debugging A Flask Application

      When developing a web application, you will frequently run into situations where the application displays an error instead of the behavior you expect. You may misspell a variable or forget to define or import a function. To make fixing these problems easier, Flask provides a debugger when running the application in development mode. In this step, you will learn how to fix errors in your application using the Flask debugger.

      To demonstrate how to handle errors, you will create a route that greets a user from a list of usernames.

      Open your app.py file for editing:

      Add the following route to the end of the file:

      flask_app/app.py

      # ...
      
      @app.route('/users/<int:user_id>/')
      def greet_user(user_id):
          users = ['Bob', 'Jane', 'Adam']
          return '<h2>Hi {}</h2>'.format(users[user_id])
      

      Save and close the file.

      In the route above, the greet_user() view function receives a user_id argument from the user_id URL variable. You use the int converter to accept positive integers. Inside the function, you have a Python list called users, which contains three strings representing usernames. The view function returns a string that is constructed depending on the provided user_id. If the user_id is 0, the response will be Hi Bob in an <h2> tag because Bob is the first item in the list (the value of users[0]).

      With the development server running, open your browser and visit the following URLs:

      http://127.0.0.1:5000/users/0
      http://127.0.0.1:5000/users/1
      http://127.0.0.1:5000/users/2
      

      You will receive the following responses:

      Output

      Hi Bob Hi Jane Hi Adam

      This works well so far, but it can go wrong when you request a greeting for a user who doesn’t exist. To demonstrate how the Flask debugger works, visit the following URL:

      http://127.0.0.1:5000/users/3
      

      You’ll see a page that looks like this:

      Flask Debugger

      At the top, the page gives you the name of the Python exception, which is IndexError, indicating that the list index (3 in this case) is out of the list’s range (which is only from 0 to 2 because the list has only three items). In the debugger, you can see the traceback that tells you the lines of code that raised this exception.

      The last two lines of the traceback usually give the source of the error. In your case the lines may be something like the following:

      File "/home/USER/flask_app/app.py", line 28, in greet_user
          return '<h2>Hi {}</h2>'.format(users[user_id])
      

      This tells you that the error originates from the greet_user() function inside the app.py file, specifically in the return line.

      Knowing the original line that raises the exception will help you determine what went wrong in your code, and decide what to do to fix it.

      In this case you can use a simple try...except clause to fix this error. If the requested URL has an index outside the list’s range, the user will receive a 404 Not Found error, which is an HTTP error that tells the user the page they are looking for does not exist.

      Open your app.py file for editing:

      To respond with an HTTP 404 error, you will need Flask’s abort() function, which can be used to make HTTP error responses. Change the second line in the file to also import this function:

      flask_app/app.py

      from markupsafe import escape
      from flask import Flask, abort
      

      Then edit the greet_user() view function to look as follows:

      flask_app/app.py

      # ...
      
      @app.route('/users/<int:user_id>/')
      def greet_user(user_id):
          users = ['Bob', 'Jane', 'Adam']
          try:
              return '<h2>Hi {}</h2>'.format(users[user_id])
          except IndexError:
              abort(404)
      

      You use try above to test the return expression for errors. If there was no error, meaning that user_id has a value that matches an index in the users list, the application will respond with the appropriate greeting. If the value of user_id is outside the list’s range, an IndexError exception will be raised, and you use except to catch the error and respond with an HTTP 404 error using the abort() Flask helper function.

      Now, with the development server running, visit the URL again:

      http://127.0.0.1:5000/users/3
      

      This time you’ll see a standard 404 error page informing the user that the page does not exist.

      By the end of this tutorial, your app.py file will look like this:

      flask_app/app.py

      from markupsafe import escape
      from flask import Flask, abort
      
      app = Flask(__name__)
      
      
      @app.route('/')
      @app.route('/index/')
      def hello():
          return '<h1>Hello, World!</h1>'
      
      
      @app.route('/about/')
      def about():
          return '<h3>This is a Flask web application.</h3>'
      
      @app.route('/capitalize/<word>/')
      def capitalize(word):
          return '<h1>{}</h1>'.format(escape(word.capitalize()))
      
      @app.route('/add/<int:n1>/<int:n2>/')
      def add(n1, n2):
          return '<h1>{}</h1>'.format(n1 + n2)
      
      @app.route('/users/<int:user_id>/')
      def greet_user(user_id):
          users = ['Bob', 'Jane', 'Adam']
          try:
              return '<h2>Hi {}</h2>'.format(users[user_id])
          except IndexError:
              abort(404)
      

      You now have a general idea of how to use the Flask debugger to troubleshoot your errors and help you determine the appropriate course of action to fix them.

      Conclusion

      You now have a general understanding of what Flask is, how to install it, and how to use it to write a web application, how to run the development server, and how to use routes and view functions to display different web pages that serve specific purposes. You’ve also learned how to use dynamic routes to allow users to interact with your web application via the URL, and how to use the debugger to troubleshoot errors.

      If you would like to read more about Flask, check out the Flask topic page.



      Source link