How the platform works, what powers it, and what teachers need to know when designing lessons and activities for browser-based Python.
code.pbaumgarten.com is a purpose-built web application. The server handles accounts, projects, exercises, and assessment. The browser handles all Python execution — no code is ever sent to the server to be run.
Python runs entirely in the browser via Pyodide, a port of CPython compiled to WebAssembly. Code is executed locally on the student's device — nothing is sent to the server at runtime.
The editor is built on CodeMirror 6, a professional-grade code editor used in major IDEs. It provides syntax highlighting, bracket matching, and a Python language mode.
The backend is a Python Flask application backed by PostgreSQL. It manages users, schools, projects, files, exercises, assignments, and test results.
Hosted on a dedicated VPS with Nginx as a reverse proxy and
Let's Encrypt TLS. The application runs under
Gunicorn managed by systemd.
Python execution runs in a dedicated Web Worker thread so the
browser UI stays responsive. Synchronous input() is handled via
SharedArrayBuffer and Atomics, which requires
cross-origin isolation headers.
No CSS or JavaScript frameworks are used. The frontend is plain HTML5, CSS3, and ES module JavaScript — keeping the codebase lean, fast, and auditable.
Understanding the execution model helps explain both the capabilities and constraints of the platform.
print) streams to the console panel in real time.input(), execution pauses and the console shows a prompt. The student types a response; execution resumes.matplotlib figures are captured as PNG images and displayed inline below the console output.The platform uses Pyodide 0.27, which bundles Python 3.12. The vast majority of standard Python works exactly as students would expect from a desktop installation. However, because Python runs inside a browser rather than a native operating system, a small number of modules and capabilities are unavailable or behave differently. The sections below detail what teachers need to know when designing lessons and activities.
The following features are completely absent from the browser Python environment. Lessons or activities that rely on them will need to be redesigned or delivered using a locally installed Python instead.
turtle is widely used in introductory
CS courses for teaching loops and coordinates. It is not available here because it
requires a desktop graphics window. For drawing activities, matplotlib
is a capable alternative that is fully supported.
| Module / Feature | Status | Reason |
|---|---|---|
| turtle, turtledemo | Not available | Requires a desktop graphics window |
| tkinter | Not available | Requires a desktop GUI toolkit |
| pygame | Not available | Requires OS-level graphics and audio |
| curses | Not available | Requires terminal control sequences |
| subprocess | Not available | No shell to call out to |
| venv, ensurepip, pip | Not available | Package management is handled by the platform |
These modules can be imported but will not work as expected, or have meaningful constraints that affect how they can be used in lessons.
| Module / Feature | Status | Notes for lesson design |
|---|---|---|
| socket | Limited | Can be imported but network connections fail. Browser security prevents raw TCP/UDP. |
| multiprocessing | Limited | Can be imported but processes cannot be created. Use sequential code. |
| threading | Limited | Present but unreliable in WebAssembly. Avoid thread-dependent activities. |
| File I/O (open, pathlib) | Virtual | Reads and writes work, but the filesystem is in-memory. Files written by Python appear in the file panel and persist when saved through the platform. |
| os.system, os.popen | Limited | No shell available. Other os functions (path, environment) work normally. |
| time.sleep | Works | Works correctly. Execution runs in a background thread so the browser UI stays responsive. |
The following standard library modules and third-party packages work correctly with no changes required from students or teachers.
| Category | Status | Modules / packages |
|---|---|---|
| Core language | Full support | All built-in types, control flow, functions, classes, decorators, generators, comprehensions, exceptions |
| Maths & numbers | Full support | math, random, statistics, decimal, fractions |
| Strings & text | Full support | string, re, textwrap, difflib |
| Data structures | Full support | collections, heapq, bisect, array |
| Functional tools | Full support | itertools, functools, operator |
| Date & time | Full support | datetime, calendar, time |
| Data formats | Full support | json, csv, xml, html, base64 |
| Type system & OOP | Full support | typing, abc, enum, dataclasses |
| Testing | Full support | unittest, unittest.mock, doctest |
| Databases | Full support | sqlite3 — full in-memory SQLite, excellent for database lessons — See it in action → |
| Numeric computing | Full support | numpy, scipy, sympy |
| Data analysis | Full support | pandas |
| Visualisation | Full support | matplotlib — charts render inline in the console panel — See it in action → |
| Machine learning | Full support | scikit-learn |
| Image processing | Full support | Pillow (PIL) — processing, manipulation, and programmatic drawing via ImageDraw; calling image.show() renders the image inline in the console panel, just like matplotlib — See it in action → |
Supported third-party packages are loaded automatically when the platform detects
an import statement on the first run — no installation step is
needed. Only packages that have been compiled specifically for WebAssembly are
available; packages that rely on native OS libraries or network sockets generally
cannot be made to work in the browser.
requests.get() and
requests.post() through the browser's built-in fetch(),
so standard syntax works as-is. Not every URL is reachable this way: only servers
that explicitly allow cross-origin requests will respond.
What is CORS, and which URLs will work? →
| Package | Status | Notes |
|---|---|---|
| numpy | Available | Arrays, linear algebra, random number generation |
| pandas | Available | DataFrames, CSV/JSON loading, data manipulation |
| matplotlib | Available | Charts render inline in the console panel — See it in action → |
| scipy | Available | Scientific computing, statistics, signal processing |
| scikit-learn | Available | Machine learning algorithms and model evaluation |
| sympy | Available | Symbolic mathematics — algebra, calculus, equation solving |
| Pillow (PIL) | Available | Image opening, resizing, filtering, format conversion, and programmatic drawing with ImageDraw. Calling image.show() renders the image inline in the console panel — no separate viewer needed. — See it in action → |
| beautifulsoup4 | Available | HTML and XML parsing. Useful for processing markup strings or API responses. Note that requests can only fetch pages from servers that allow cross-origin requests — most public websites don't. Details → |
| lxml | Available | Fast XML and HTML processing; works as a parser backend for BeautifulSoup |
| PyYAML | Available | YAML file reading and writing |
| cryptography | Available | Hashing, symmetric and asymmetric encryption |
| regex | Available | Enhanced regular expressions (superset of the standard re module) |
| networkx | Available | Graph and network algorithms — useful for CS theory topics |
| requests | CORS only | requests.get() and requests.post() work via the browser's fetch() API. Most public data APIs work; regular websites and private APIs generally do not. Check a URL → |
| httpx | Not available | Same constraint as requests — socket-based HTTP is not permitted. |
| flask, django | Not available | Server frameworks have no meaning in a browser context. They cannot bind ports or handle HTTP requests from outside. |
| paramiko | Not available | SSH connections require sockets |
| pygame | Not available | Although a browser-compatible build of Pygame exists, this platform does not provide the display canvas it requires. |
| sqlalchemy | Limited | The ORM layer can work with an in-memory SQLite backend, but is not pre-configured. For database lessons, the built-in sqlite3 module is recommended instead. |
Use the table below as a quick checklist when planning activities.
| Lesson type | Status |
|---|---|
Console I/O programs using input() and print() |
Fully supported |
| Loops, conditionals, functions, and recursion | Fully supported |
| Object-oriented programming (classes, inheritance) | Fully supported |
| File reading and writing (CSV, text, JSON) | Fully supported |
| Data analysis with NumPy and Pandas | Fully supported |
| Charting and visualisation with Matplotlib | Fully supported |
| Database activities with SQLite — See it in action → | Fully supported |
| Sorting, searching, and algorithms | Fully supported |
| Turtle graphics | Not available |
| GUI applications (tkinter, pygame) | Not available |
Fetching data from public web APIs (requests.get()) |
Partial CORS details → |
| Networking and raw sockets | Not available |
| Multi-threading and multiprocessing | Not available |
| Shell and OS commands | Not available |
ImageDraw module
is a capable in-platform alternative. Students can draw shapes, lines, polygons, and
text onto an image canvas and display the result inline with image.show().
matplotlib is also available for coordinate-based and geometric drawing tasks.
— See it in action →
Student code is executed locally in the browser using WebAssembly. It is never transmitted to the server at runtime. The server stores only saved file contents, exercise results, and account information.
Accounts are school-scoped. Students can only see their own work. Teachers can see the work of their own students. All data in transit is protected by TLS. Login is protected by CSRF tokens and automatic brute-force detection.
The platform is self-hosted on dedicated infrastructure and not subject to the data-sharing practices of third-party cloud education platforms.
Accounts are set up by teachers. If you're a teacher interested in trialling the platform, register your interest below.
Register your interest →
CORS stands for Cross-Origin Resource Sharing.
When Python code on this platform calls requests.get(), the request
is routed through the browser's built-in fetch() function rather than
Python's usual network stack. The browser then applies its normal security rules —
including CORS.
When a web page fetches data from a different server, the browser asks that server: "do you allow requests from this website?" The server answers by including special response headers. If the server says yes, the request succeeds. If it says nothing — or says no — the browser blocks the response, even if the server itself sent data back.
APIs that work with requests.get()
Most public data APIs are designed to be called from web pages and explicitly allow cross-origin requests:
restcountries.com/v3.1/alljsonplaceholder.typicode.com (test/dummy data)api.github.com (public repos, users, commits)api.nasa.gov (astronomy picture of the day, imagery)URLs that will not work
bbc.com, wikipedia.org, news sites, etc. are built to be visited in a browser tab, not fetched by scripts from other siteshttp:// endpoints from secure pages (mixed content)Check a URL
Enter any URL to find out whether requests.get() will be able to reach it from this platform.