Creating Structural Engineering Web Application with Flask: A Beginner’s Guide

Murat Melek
6 min readJan 3, 2023

This tutorial aims to guide you through the process of building a structural engineering web application using Flask, a Python web framework. By the end of this tutorial, you will have learned how to deploy a simple structural calculation — specifically, calculating the axial capacity of a structural steel column — as a Flask application.

Before we dive into the implementation using Flask, let’s briefly review the structural calculations that will be used in the example.

Determining the Capacity of a Structural Steel Column in Compression

For the purposes of this application, we will only consider flexural buckling (for compression members without slender elements, as defined in Section B4 of The American Institute of Steel Construction’s (AISC) Specification for Structural Steel Buildings). It is expected that these compression members will undergo flexural buckling before experiencing torsional or local buckling.

Buckling Modes

To determine the flexural buckling strength of a column, we will first calculate the critical stress (Fcr). The value of Fcr depends on several parameters, including the radius of gyration (r), lateral unbraced length of the member (L), effective length factor (K), specified minimum yield stress (Fy), and steel modulus of elasticity (E).

The relationship between critical stress and these parameters can be represented as follows:

As depicted in the plot above, the boundary between inelastic and elastic buckling occurs at slenderness term of 1.5. Once critical buckling stress is calculated using this relationship, nominal compressive strength (based on the limit state of flexural buckling) is equal to:

This relationship can be expressed as a Python function as follows. It is worth noting that the Python function uses KL/r, rather than the slenderness ratio, as the threshold between inelastic and elastic buckling.

import math

def calculate_phi_pn(moment_of_inertia, section_area, kl, steel_modulus_of_elasticity=29000, f_y=50):
'''
This function calculates structural steel column capacity based on moment of inertia, section area,
unbraced column length (kl), steel_modulus_of_elasticty and steel yield stress (f_y)
'''
phi = 0.9

radius_of_gyration = math.sqrt(moment_of_inertia/section_area)

if kl == 0:
kl += 0.00001
else:
kl = kl * 12

# elastic critical stress
f_e = (math.pi)**2 * steel_modulus_of_elasticity / ((kl / radius_of_gyration)**2)

if kl/radius_of_gyration <= (4.71 * (steel_modulus_of_elasticity/f_y)**0.5):
f_cr = (0.658**(f_y/f_e)) * f_y
elif kl/radius_of_gyration >= 200:
f_cr = 0
else:
f_cr = 0.8777 * f_e

# multiply phi factor with section area and f_cr
phi_pn = int(phi*section_area*f_cr)

return phi_pn

Now that we have a Python function that calculates the axial capacity of a steel column, we can use Flask to create a web application from this function. Let’s get started with the Flask integration.

Flask

Flask is a popular lightweight Python web framework that provides useful tools and features for creating web applications. It is designed to be lightweight, modular, easily scalable, and can be used for creating web applications of any size, from small to large. It is also easy to learn and implement, making it a popular choice for developers who are new to web development, with Django and FastAPI being other examples.

For more detailed information on Flask, you can check out this article on Medium.

In it’s simplest form, a flask application consists:

  • A Python of file called application.py or app.py at the top level directory.
  • A templates folder that contains HTML templates, which are used to render the web pages of the application. For our example, we are using a very simple index.html.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Steel Column Axial Capacity</title>
</head>
<body>
<h4>Flask Example - Column Axial Capacity</h4>
<form method="POST" action="" enctype="multipart/form-data">
<label for="moment_of_inertia">Section Moment of Inertia (in4):</label><br>
<input type="number" id="moment_of_inertia" name="moment_of_inertia"><br>
<label for="section_area">Section Area (in2):</label><br>
<input type="float" id="section_area" name="section_area"><br>
<label for="k_l">Unbraced Length (ft):</label><br>
<input type="number" id="k_l" name="k_l"><br>
<label for="steel_modulus_of_elasticity">Steel Modulus of Elasticity (ksi):</label><br>
<input type="number" id="steel_modulus_of_elasticity" name="steel_modulus_of_elasticity"><br>
<label for="steel_yield_stress">Steel Yield Stress (ksi):</label><br>
<input type="number" id="steel_yield_stress" name="steel_yield_stress"><br>
<br>
<button type="submit">Submit</button>
<br>
<b>
{% for message in get_flashed_messages() %}
<p style="color:blue">{{ message }}</p>
{% endfor %}
</form>
</body>
</html>
  • For this example, we are not using CSS, JavaScript or images. If this was the case, we would also need a static folder to store these files.
  • column_capacity_simple.py contains the function that calculates the ultimate strength of the column.
  • If we were deploying this application to the web, we would also have needed a requirements.txt file. This file contains the libraries needed for the code to run.

To begin, we will import the Flask class and its methods. We will also import the calculate_phi_pn function from the column_capacity_simple.py file.

We will use the os module to generate a secret key in the next step.

from flask import render_template, request, redirect, flash
from flask import Flask

from column_capacity_simple import calculate_phi_pn

import os

In the next step, we generate an instance of Flask class. We set the secret key using app.secret_key = os.urandom(24) generating a random string of 24 bytes. This ensures that the secret key is unique and randomly generated.

app = Flask(__name__)
app.secret_key = os.urandom(24)

We bind home() function to the root url (/), using a decorator. When a request is sent to the root URL, home() function is called.

@app.route("/")
def home():
return render_template("index.html")

The enter_information() function is called whenever a POST request is made. This function collects the input parameters for the calculate_phi_pn() function and checks to ensure that all required inputs have been entered. If all inputs are present, the function calculates the axial capacity of the column using the calculate_phi_pn() function.

The Flask framework allows us to display messages using Jinja code blocks and the get_flashed_messages() function in the index.html file.

@application.route("/", methods=['POST'])
def enter_information():
if request.method == 'POST':
moment_of_inertia = request.form.get('moment_of_inertia')
section_area = request.form.get('section_area')
k_l = request.form.get('k_l')
steel_modulus_of_elasticity = request.form.get('steel_modulus_of_elasticity')
f_y = request.form.get('steel_yield_stress')

# check whether all inputs are entered
check_inputs = all([moment_of_inertia, section_area, k_l, steel_modulus_of_elasticity, f_y])

# check_inputs is true, call for the calculate_phi_pn function
if check_inputs:

phi_pn = calculate_phi_pn(float(moment_of_inertia), float(section_area), float(k_l), float(steel_modulus_of_elasticity), float(f_y))

output = "Design Axial Capacity of the Column is: " + str(phi_pn) + " kips"

# we can use flash to show the output on the same page
flash(output)
return redirect(request.url)

# if input(s) are missing
else:
flash('Please fill all of the boxes.')
return redirect(request.url)

Application.py ends with the following code which executes the application script when invoked directly.

By setting debug = True, we enable the application to automatically restart when we make changes to the code. This can be helpful during development, as it allows us to see the changes in real-time. In addition, debug mode provides helpful error messages if the application encounters any issues. This can help identify and troubleshoot problems.

if __name__ == "__main__":
application.run(debug=True)

We are ready to run “application.py”.

python application.py

Flask runs on port 5000 as default in development mode. If we follow the URL address given above, we can test our simple web app that runs on the local host.

To sum up, this tutorial demonstrated how to use Flask to create a web application that calculates the axial capacity of a structural column. It’s worth noting that this example uses a basic user interface and has not been deployed to the cloud. There are many additional considerations and steps that would need to be taken to make the application fully functional and available for use by a wider audience.

The code for this example is available, in it’s entirety, on GitHub.

References

--

--