htdocs/form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Form for Python</title>
<link rel="Stylesheet" type="text/css" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=0.875">
<style>
form fieldset {
border: 1px solid gray;
padding: 1rem;
margin-bottom: 1rem;
}
form fieldset[disabled] {
background: rgba(0, 0, 0, )
}
form legend {
background: var(--font-color);
color: var(--bg-color);
text-shadow: none;
font-size: 1em;
font-weight: bold;
font-family: 'Times New Roman', Times, serif;
text-transform: uppercase;
display: inline-block;
width: unset;
margin: 0 -1ch;
padding: 0 1ch;
}
form label {
display: block;
}
form input[type="text"] {
display: block;
}
</style>
</head>
<body>
<h1>Python CGI Form Example</h1>
<form method="POST" action="/cgi-bin/submit.py">
<fieldset>
<legend>Shipping information</legend>
<label>Name
<input name="shipping-name" type="text" autocomplete="name" required />
</label>
<label>Zip code
<input name="shipping-zip" type="text" autocomplete="postal-code" required>
</label>
</fieldset>
<fieldset id="billing-info">
<legend>Billing information</legend>
<label>Billing information is the same? <input name="billing-info-same" type="checkbox" checked /></label>
<label>Name
<input name="billing-name" type="text" autocomplete="name" required />
</label>
<label>Zip code
<input name="billing-zip" type="text" autocomplete="postal-code" required />
</label>
</fieldset>
<input type="submit" value="Calculate" />
</form>
<script>
{
const { "shipping-name": shippingNameEl, "shipping-zip": shippingZipEl, "billing-name": billingNameEl,
"billing-zip": billingZipEl,
"billing-info-same": billingInfoSameEl
} = document.querySelector("form").elements;
function updateBillingInfo() {
billingNameEl.placeholder = shippingNameEl.value;
billingZipEl.placeholder = shippingZipEl.value;
billingNameEl.disabled = billingInfoSameEl.checked;
billingZipEl.disabled = billingInfoSameEl.checked;
}
document.querySelector("form")
.addEventListener("input", updateBillingInfo);
document.querySelector("form")
.addEventListener("change", updateBillingInfo);
updateBillingInfo();
}
</script>
</body>
</html>
htdocs/cgi-bin/submit.py
import os
import cgi
import io
import cgitb
import random
cgitb.enable(True)
OUTFILE_NAME = "address.csv"
print ("Content-Type: text/html; charset=UTF-8")
print()
form = cgi.FieldStorage()
order_num = random.randrange(100000, 999999)
shipping_name = form.getfirst("shipping-name", None)
shipping_zip = form.getfirst("shipping-zip", None)
billing_name = form.getfirst("billing-name", shipping_name)
billing_zip = form.getfirst("billing-zip", shipping_zip)
if not shipping_name and billing_name:
print(f"<h1>Error: Invalid data</h1>")
print(f"<p>Your order could not be completed.</p>")
exit(1)
try:
with open(OUTFILE_NAME, "x") as outfile:
print("OrderNumber,ShippingName,ShippingZip,BillingName,BillingZip", file=outfile)
except (FileExistsError):
pass
with open(OUTFILE_NAME, "a+") as outfile:
print(order_num, shipping_name, shipping_zip, billing_name, billing_zip, sep=",", file=outfile)
print("")
print(f"<h1>Your order #{order_num} was confirmed!</h1>")
print("<h2>Shipping info</h2>")
print(f"<address>{shipping_name}<br>{shipping_zip}</address>")
print("<h2>Billing info</h2>")
print(f"<address>{billing_name}<br>{billing_zip}</address>")
htdocs/cgi-bin/dump_data.py
import cgi
import cgitb
cgitb.enable(True)
SUPER_SECRET_ADMIN_PASSWORD = "admin123"
OUTFILE_NAME = "address.csv"
print("Content-Type: text/plain; charset=UTF-8")
print()
form = cgi.FieldStorage()
if (form.getfirst("password") == SUPER_SECRET_ADMIN_PASSWORD):
with open(OUTFILE_NAME, "r") as address_file:
print(address_file.read())
else:
print("Invalid password.")