Metadata-Version: 2.4
Name: stepik-python-grader
Version: 1.10.0
Summary: Automatic comparison and testing of Python solutions from Stepik courses
Author-email: Artem Markitanov <av.markitanov@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/ArtVsMark/Stepik-Python-Grader
Project-URL: Repository, https://github.com/ArtVsMark/Stepik-Python-Grader
Project-URL: Changelog, https://github.com/ArtVsMark/Stepik-Python-Grader/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/ArtVsMark/Stepik-Python-Grader/issues
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Education
Classifier: Natural Language :: English
Classifier: Natural Language :: Russian
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Education
Classifier: Topic :: Education :: Testing
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests<3.0,>=2.34.2
Requires-Dist: psutil<8.0,>=5.9
Requires-Dist: rich<16.0,>=13.0
Provides-Extra: dev
Requires-Dist: pytest>=8.2; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: pytest-timeout>=2.3; extra == "dev"
Requires-Dist: ruff>=0.15.19; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: hypothesis>=6.0; extra == "dev"
Provides-Extra: watch
Requires-Dist: watchfiles<2.0,>=0.21; extra == "watch"
Provides-Extra: e2e
Requires-Dist: playwright>=1.40; extra == "e2e"
Provides-Extra: lint
Requires-Dist: ruff<2.0,>=0.15; extra == "lint"
Dynamic: license-file

# Stepik Python Grader

[![CI](https://github.com/ArtVsMark/Stepik-Python-Grader/actions/workflows/ci.yml/badge.svg)](https://github.com/ArtVsMark/Stepik-Python-Grader/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/ArtVsMark/Stepik-Python-Grader)](https://github.com/ArtVsMark/Stepik-Python-Grader/releases)
[![Version](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ArtVsMark/Stepik-Python-Grader/main/.github/badges/version.json&cacheSeconds=300)](CHANGELOG.md)
[![Coverage (ubuntu)](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ArtVsMark/Stepik-Python-Grader/main/.github/badges/coverage.json&cacheSeconds=300)](https://github.com/ArtVsMark/Stepik-Python-Grader/actions/workflows/ci.yml)
[![Coverage (all OS combined)](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ArtVsMark/Stepik-Python-Grader/main/.github/badges/coverage-combined.json&cacheSeconds=300)](https://github.com/ArtVsMark/Stepik-Python-Grader/actions/workflows/ci.yml)
[![Glossary](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ArtVsMark/Stepik-Python-Grader/main/.github/badges/glossary.json&cacheSeconds=300)](docs/dev/glossary.md)
![Python](https://img.shields.io/badge/python-3.12%20%7C%203.13%20%7C%203.14%20%28exp%29-blue)

> **Status:** Stable &nbsp;·&nbsp; 🇬🇧 [English quick start & generic mode](README.en.md)

> Локальный грейдер для курсов «Поколение Python» на Stepik.
> Скачивает данные задачи с сайта и позволяет не только проверить решение локально, но и **сравнить несколько решений более честно**: сначала по корректности, потом по benchmark-метрикам.

![Веб-интерфейс --serve: грейдинг папки решений против тест-кейсов с вердиктом OK и таблицей результатов](docs/assets/hero-serve.gif)

> Форк / продолжение проекта: [Первоисточник грейдера](https://github.com/PavloOps/python_generation_grader)
>
> 💬 **Нашли баг или есть идея?** Пункт `9` в меню грейдера и кнопка 💬 в
> веб-интерфейсе открывают форму [issue](https://github.com/ArtVsMark/Stepik-Python-Grader/issues/new/choose)
> уже заполненной (версия, ОС, Python подставятся сами). Вопрос, а не баг — в
> [Discussions](https://github.com/ArtVsMark/Stepik-Python-Grader/discussions).

Курсы:
- [Поколение Python: Курс для начинающих](https://stepik.org/course/58852)
- [Поколение Python: Курс для продвинутых](https://stepik.org/course/68343)
- [Поколение Python: Курс для профессионалов](https://stepik.org/course/82541)
- [Поколение Python: ООП](https://stepik.org/course/98974)
- [Поколение Python: Курс для самураев](https://stepik.org/course/134318)

---

## Зачем это, если Stepik уже проверяет решения?

Встроенный чекер Stepik даёт «зачёт / не зачёт» — и только после сабмита. Грейдер закрывает то, чего у него нет:

- ⚡ **Мгновенный офлайн-цикл.** Правишь решение и проверяешь локально за секунды — без сабмита, без лимита попыток, без сети.
- 📊 **Честное сравнение нескольких решений.** Stepik не покажет, какое из ваших решений быстрее и экономнее по памяти — грейдер прогоняет их бок о бок (median-время, RSS, вердикты SIMILAR/SLOWER) в режимах 3/4.
- 🎓 **«Подучить», а не просто вердикт.** Частые ошибки из вашей истории прогонов с затуханием карточек — инструмент учит, а не только оценивает.
- 📚 **Офлайн-глоссарий Python** с deep-link прямо из ошибок исполнения.
- 🔒 **Свой код не покидает машину** (кроме явного скачивания задачи со Stepik и opt-in AI-подсказок с отдельным согласием).

Детальное сравнение с проектом-первоисточником — в [docs/use/versions.md](docs/use/versions.md#что-изменилось-по-сравнению-с-оригиналом).

---

## Основные возможности

- ✅ Запуск решений против наборов тест-кейсов (`tests/N` + `tests/N.clue`)
- 📋 **Автоматическое извлечение тест-кейсов** из HTML-таблицы в тексте задачи Stepik
- 📦 **Автоскачивание тестов из ZIP-архива** по ссылке в тексте задачи
- 🔗 Обнаружение ссылок на GitHub-тесты с подсказкой скачать вручную
- 📊 Сравнение нескольких решений одной задачи в таблице
- 🚀 Subprocess-бенчмарк с замером времени и памяти (режим 3)
- ⚡ Timeit-микробенчмарк через subprocess (режим 4)
- 🎨 Цветной вывод через `rich` — зелёный OK/AC, красный WA/TLE/RE, жёлтый SLOWER
- 🔍 Diff при WA — сравнение ожидаемого и фактического вывода при провале теста
- ⚖️ Вердикты AC / WA / TLE / RE по каждому тест-кейсу
- 🌐 Локальный веб-интерфейс (`--serve`, `http://127.0.0.1:8000`) и интеграция с VS Code / PyCharm
- 🖥 GUI-лаунчер веб-интерфейса без командной строки (`stepik-grader-gui`) —
  на Windows ярлык без консольного окна
- 🧩 pytest-плагин (`pytest --grader-mode`), кэш результатов и `--watch`
  (опционально: требует extra `[watch]` — `pip install -e ".[watch]"`, зависит
  от `watchfiles`)
- 🧪 Playwright e2e-смоук фронтенда + регрессия на XSS (опционально: extra
  `[e2e]` — см. [CONTRIBUTING.md § E2E-тесты](CONTRIBUTING.md#e2e-тесты-playwright-опционально))
- 📚 Локальный глоссарий-модуль (число готовых карточек — в бейдже Glossary выше, черновиков нет): функции/исключения/конструкции,
  детектор недостающих терминов, deep-link из error cards
- 🎓 Правила PEP 8 и раздел «Подучить» — частые ошибки из истории прогонов с
  затуханием (`--insights` / `--lint`)
- 📈 Локальная статистика прогонов (`--stats`) и SQLite-история (`--history`) — без сети
- 🔒 Опциональная OS-песочница исполнения решений (`--sandbox`)
- 🔍 Диагностика окружения и авторизация через Stepik API

> **Только в вебе — CLI-аналога нет.** Раздел «Песочница» (не путать с
> OS-изоляцией `--sandbox`) — запуск произвольного кода со своим stdin;
> пошаговый трейс исполнения (плеер шагов, кадры стека, memory-graph);
> редактор решения с сохранением; кнопка «Отправить в Stepik» в режиме 1
> интерактивные разделы «Глоссарий», «Правила (PEP)», «Подучить»
> и «Прогресс» — в терминале от них есть только сводки `--insights`/`--lint` и
> экспорт `--export-progress`. Обзор разделов — [docs/use/web-interface.md](docs/use/web-interface.md).

Разбор по модулям и слоям — в [docs/dev/architecture.md](docs/dev/architecture.md).

### Как это выглядит (`--serve`)

| Проверка папки решений (режим 2) | Офлайн-глоссарий Python |
|---|---|
| ![Таблица результатов веб-интерфейса: task.py — 5 из 5 тест-кейсов пройдено, вердикт OK, время и память](docs/assets/serve-results.png) | ![Раздел «Глоссарий»: список карточек и открытая карточка оператора % с синтаксисом и примерами кода](docs/assets/serve-glossary.png) |

---

## Быстрый старт

**Установить** (проще всего через [pipx](https://pipx.pypa.io)):

```bash
pipx install stepik-python-grader
```

**Запустить** интерактивное меню:

```bash
python -m stepik_grader       # надёжный способ (работает всегда)
stepik-grader                 # если команда в PATH
```

**Или веб-интерфейс** (только localhost) — те же режимы 1–4 в браузере плюс
разделы, которых в CLI нет (см. § Основные возможности):

```bash
stepik-grader --serve         # http://127.0.0.1:8000 (другой порт — --port)
```

**Совсем без командной строки** — окно-лаунчер веб-интерфейса:
выбор варианта запуска («Простой сервер» / «Сервер с изоляцией `--sandbox`»),
порта (с проверкой «занят») и рабочей папки, кнопки «Запустить»/«Остановить» и
авто-открытие браузера:

```bash
stepik-grader-gui                  # на Windows — ярлык без консольного окна
python -m stepik_grader.launcher   # то же окно из терминала
```

**Или проверить одно решение без интерактива:**

```bash
stepik-grader --mode 1 --file task.py
```

Полная установка (из исходников, venv, Windows-заметки, настройка OAuth) — в
[docs/use/installation.md](docs/use/installation.md). Пошаговый первый пример, режимы
1–4, CLI-флаги, скачивание задач и форматы тестов — в
[docs/use/grader-workflow.md](docs/use/grader-workflow.md).

---

## Документация

База знаний — в [`docs/`](docs/README.md), разложена по четырём направлениям:

| Направление | Для кого | Что внутри |
|---|---|---|
| [**docs/use/**](docs/use/README.md) | пользователь | установка и OAuth, режимы 1–4 и CLI-флаги, веб-интерфейс, конфигурация, форматы тест-кейсов, отличия от первоисточника |
| [**docs/dev/**](docs/dev/README.md) | контрибьютор | архитектура и дерево модулей, HTTP API, контракты данных, 11 ADR, дизайн незапущенного server mode |
| [**docs/agent/**](docs/agent/README.md) | Claude Code | шаблон ролей, очередь работ после крупного аудита |
| [**docs/archive/**](docs/archive/README.md) | по необходимости | история разработки, архив CHANGELOG, разовые аудиты |

Рядом с кодом: [CHANGELOG.md](CHANGELOG.md) — что изменилось в релизах,
[CONTRIBUTING.md](CONTRIBUTING.md) — как внести вклад,
[CLAUDE.md](CLAUDE.md) — инварианты ядра для агентов.

> Два правила этой документации: **одна тема — один файл** (остальные
> ссылаются, а не копируют) и **в активном документе нет журнала работ** (что
> сделано — в CHANGELOG, что предстоит — в Issues). Подробнее —
> [docs/README.md](docs/README.md).

---

## Безопасность (кратко)

**По умолчанию решения запускаются БЕЗ полноценного sandbox на уровне ОС.** Есть
таймаут выполнения (всегда) и best-effort лимит памяти на POSIX; изоляции ФС/сети
по умолчанию нет. Опциональная OS-изоляция включается флагом `--sandbox`
(`core/sandbox/`, три backend'а) — и в CLI (режимы 1–4), и в web
(`--serve --sandbox`; пошаговый трейс под ней недоступен). Без
`--sandbox` запускай только доверенные решения (свои или скачанные из Stepik
as-is).
Подробная threat model — в
[docs/configuration.md § Ограничения и безопасность](docs/use/configuration.md#ограничения-и-безопасность).
Как сообщить об уязвимости — [SECURITY.md](SECURITY.md).

---

## Прозрачность и доверие

- ✅ **Автотесты на каждый PR** (pytest), CI-матрица на 3 ОС × Python 3.12/3.13
  (+3.14 экспериментально) — живые бейджи покрытия single-OS и cross-OS в шапке.
- 🧠 **Строгий mypy** (`disallow_untyped_defs`, `warn_return_any`, …) + `ruff`
  (lint + format) в pre-commit и CI — типы и стиль проверяются на каждый PR.
- 🔐 **Приватный репорт уязвимостей** (GitHub Private Vulnerability Reporting) +
  документированная threat model — [SECURITY.md](SECURITY.md).
- 📦 **Публикация на PyPI через OIDC trusted publishing** — без хранимого токена
  в секретах; релизный dist собирается один раз в CI.
- 📜 **MIT**, открытая история изменений — [CHANGELOG.md](CHANGELOG.md).

---

## Первый вклад за 15 минут

Новичок? Возьмите issue с меткой
[`good first issue`](https://github.com/ArtVsMark/Stepik-Python-Grader/labels/good%20first%20issue)
— это задачи с понятным объёмом и ссылками на канон. Пошаговый онбординг (форк →
ветка от `main` → локальные гейты `pytest`/`ruff`/`mypy` → PR по Conventional
Commits) — в [CONTRIBUTING.md § Первый вклад за 15 минут](CONTRIBUTING.md#первый-вклад-за-15-минут).
Вопросы, идеи и «покажу своё» — в
[Discussions](https://github.com/ArtVsMark/Stepik-Python-Grader/discussions).

---

## Python версия

Python **3.12+** (3.14 — экспериментальная).

---

## Лицензия

[MIT](LICENSE) © Artem Markitanov (ArtVsMark).
