PyShala
A self-hosted interactive Python training platform for delivering custom lessons with live code execution and automated feedback.
Features
- Interactive Lessons: Write and run Python code directly in the browser
- Automated Testing: Instant feedback with pass/fail results for each test case
- Custom Content: Create your own lessons using simple YAML files
- Data File Support: Lessons can include CSV, JSON, and other data files
- Self-Hosted: Deploy on your own infrastructure
- No External Dependencies: Code execution runs locally (no Docker required)
Quick Start
Installation
pip install pyshala
Command Line
# Run with default lessons directory (./lessons)
pyshala
# Run with custom lessons path
pyshala ./my_lessons
# Run with custom port
pyshala ./my_lessons --port 8080
# See all options
pyshala --help
CLI Options:
| Option | Default | Description |
|---|---|---|
lessons_path |
./lessons |
Path to lessons directory |
--host |
0.0.0.0 |
Host address to bind |
--port, -p |
3000 |
Frontend port |
--backend-port |
8000 |
Backend API port |
--max-execution-time |
10.0 |
Max code execution time (seconds) |
--python-path |
Current interpreter | Python interpreter for execution |
--loglevel |
info |
Logging level (debug/info/warning/error) |
--app-name |
Learn Python |
Application name displayed in the UI |
--app-description |
(see below) | Description displayed on home page |
--version, -v |
Show version and exit |
Python API
from pyshala import PyShala
# Create and run the app with your lessons
app = PyShala(lessons_path="./my_lessons")
app.run()
Open your browser at http://localhost:3000
Configuration Options:
from pyshala import PyShala
app = PyShala(
lessons_path="./lessons", # Path to lesson YAML files
host="0.0.0.0", # Host address
port=3000, # Frontend port
backend_port=8000, # Backend API port
max_execution_time=10.0, # Max code execution time (seconds)
python_path="/usr/bin/python3", # Python interpreter for execution
loglevel="info", # Logging level
)
app.run()
Alternative: Using create_app
from pyshala import create_app
app = create_app(lessons_path="./my_lessons", port=8080)
app.run()
Creating Lessons
Lessons are defined using YAML files organized into modules. For more information about writing lessons, see LESSONS.md.
Directory Structure
lessons/
├── python_basics/ # Module directory
│ ├── module.yaml # Module metadata
│ ├── 01_hello_world.yaml # Lesson file
│ ├── 02_variables.yaml
│ └── sales_data.csv # Data file for lessons
└── control_flow/
├── module.yaml
└── 01_if_statements.yaml
Module Configuration (module.yaml)
name: "Python Basics"
description: "Learn the fundamentals of Python programming"
order: 1
lessons:
- 01_hello_world.yaml
- 02_variables.yaml
Lesson Configuration
title: "Hello, World!"
description: "Write your first Python program"
order: 0
instructions: |
# Hello, World!
Use the `print()` function to display text.
## Your Task
Print "Hello, World!"
starter_code: |
# Write your code here
test_cases:
- description: "Prints greeting"
stdin: ""
expected_output: "Hello, World!"
# Optional: include data files
data_files:
- name: data.csv
path: data.csv
Test Case Options
| Field | Description |
|---|---|
stdin |
Input provided to the program |
expected_output |
Expected stdout output |
description |
Test description shown to learner |
hidden |
If true, test details hidden from learner |
Development
Setup
git clone https://github.com/dkedar7/pyshala.git
cd pyshala
pip install -e ".[dev]"
Running Directly with Reflex
reflex run
Running Tests
pytest tests/ -v
Building the Package
python -m build
Tech Stack
- Frontend/Backend: Reflex (Python)
- Code Editor: Monaco Editor via reflex-monaco
- Code Execution: Local Python subprocess (sandboxed)
License
MIT License
Metadata
Release files for pyshala 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pyshala-0.1.1.tar.gz | 35.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyshala-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.3 kB
Release files / pyshala-0.1.1.tar.gz
| Download URL | pyshala-0.1.1.tar.gz |
|---|---|
| Size | 35.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8f11e0666a95d32799dbb226da5baafe98d375d4206efee721696671adfa04aa
|
|
BLAKE2b-256 checksum How to use checksums |
dbda5402ee5f5c45301df15319fea5c21cfac59b8a2bfabefa6a3d814eb64c1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|
Release files / pyshala-0.1.1-py3-none-any.whl
| Download URL | pyshala-0.1.1-py3-none-any.whl |
|---|---|
| Size | 42.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d720799d75d21911be7afa08267f6edc39cd2f944046d60c9e751a1913051b42
|
|
BLAKE2b-256 checksum How to use checksums |
133ec3c3c77d2e155b21c6ff48844706e4c93e855949d9ce465c29f3189fbb55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|
Security for pyshala 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.