Python CGI Scripts

Python CGI scripts: headers, cgi.FieldStorage, and common patterns

How do you write a basic CGI script in Python?

A Python CGI script starts with #!/usr/bin/python3 (or the correct interpreter path for your host), imports cgi and sys, optionally calls cgi.enable_traceback() for debugging, then prints the Content-Type header and a blank line before any body output. Form data is read with cgi.FieldStorage(). The script needs execute permission (chmod 755) and must live in a CGI-enabled directory.

Request custom development Getting started

Python 2 vs Python 3 on shared hosting

Many older shared hosts default to Python 2 in the CGI path even if Python 3 is installed. If your shebang is #!/usr/bin/python3 and only Python 2 is at that path, the script fails with a 500. Run 'python --version' and 'python3 --version' in a shell session on your host to see what is available. Some hosts require #!/usr/bin/env python3 to find the version-3 binary in the PATH.

Python 2 reached end of life in 2020 and receives no security updates. If your host only offers Python 2 in the CGI path and you cannot install Python 3, that is a signal to find a different host or switch to a hosted form endpoint. Writing new CGI code in Python 2 in 2026 means inheriting known, unfixed vulnerabilities in the interpreter itself.

Reading form data with cgi.FieldStorage

import cgi; form = cgi.FieldStorage() parses both GET and POST requests, including multipart/form-data for file uploads. Access a field with form.getvalue('fieldname'), which returns the string value or None if the field is absent. For file upload fields, form['fieldname'] is a FieldStorage instance with a .file attribute you read from and a .filename attribute with the original filename.

The cgi module was deprecated in Python 3.11 and is scheduled for removal in a future version. For new projects, prefer a lightweight WSGI framework like Flask or Bottle that can run on a WSGI-capable host, which gives you proper request parsing without the CGI overhead. For existing CGI scripts that work and need maintenance, cgi.FieldStorage is fine to continue using for now.

Printing headers in Python

Python CGI scripts print headers to sys.stdout the same way as Perl: the Content-Type header, a blank line, then the body. The most common mistake is printing a blank line or any other output before the Content-Type, which garbles the response. sys.stdout.flush() after the headers ensures they are sent before the body, though Python typically flushes on newline in CGI mode.

For binary output (serving an image or PDF), set sys.stdout = sys.stdout.buffer (Python 3) before printing binary content, because Python 3's sys.stdout is a text stream by default. Alternatively, write to sys.stdout.buffer directly for the binary body while keeping sys.stdout for the headers.

What to know

Key points

Get help

Listings and a local agent, when you are ready

Need a CGI script built, debugged, or a hosting environment configured? Forms use a clearly-marked placeholder endpoint until wired to a real system.

Hosting partner CGI-compatible hosting for Python hosting

Reserved for an affiliate link to a vetted shared or VPS hosting provider that supports CGI and Perl/Python execution. Operator wires affiliate link here.

Development Need a custom CGI script built?

Self-hosted lead form for custom CGI development inquiries. Placeholder endpoint until wired to the operator's CRM or email handler.

Open inquiry form →

Custom CGI development

No spam. Your inquiry is answered within 1 business day.

Hosting setup help

No spam. Your inquiry is answered within 1 business day.

Questions

Frequently asked questions

Is the Python cgi module still available?
Yes, but it was deprecated in Python 3.11 and is scheduled for removal in a future Python version. For new projects, a lightweight WSGI framework like Flask or Bottle running on a WSGI-capable host is a cleaner approach. For existing CGI scripts, cgi.FieldStorage continues to work on current Python 3 versions; just plan for eventual migration.
My Python CGI script returns a 500 error. What should I check?
Check the interpreter path in the shebang (python3 vs python vs a version-specific path), execute permissions (chmod 755), and whether any output appears before the Content-Type header. Add import cgitb; cgitb.enable() at the top to redirect tracebacks to the browser during debugging. Test the script directly with python myscript.py to see errors outside the web server context.

CustomCGI publishes reference information on CGI programming and server-side web scripting for educational and informational purposes. Code examples are provided as-is for learning; always audit and test scripts in a staging environment before deploying to production. Security vulnerabilities in CGI scripts are a real risk; follow current best practices and review the security guide before deploying any user-facing code.