Skip to main content

Easy-to-use Python client for the Ed Stem API

Project description

pyedstem

Typed Python client for the Ed Stem API.

pyedstem provides a small, sync-first interface for common Ed Stem tasks such as listing active courses, retrieving discussion threads, reading lessons, and posting answers back to Ed using the XML document format the API expects.

Installation

Install with pip

pip install pyedstem

Add to a uv project

uv add pyedstem

Configuration

You can create a client directly with an API token:

from pyedstem import EdStemClient

client = EdStemClient(api_token="your-edstem-token")

Or load configuration from environment variables:

  • EDSTEM_API_TOKEN — required
  • EDSTEM_BASE_URL — optional, defaults to https://edstem.org/api
  • EDSTEM_TIMEOUT_SECONDS — optional, defaults to 30.0
from pyedstem import EdStemClient

with EdStemClient.from_env() as client:
    current_user = client.user.get_current_user()

Quick start

List active courses

from pyedstem import EdStemClient

with EdStemClient.from_env() as client:
    active_courses = client.courses.list_active()

for course in active_courses:
    print(course.id, course.code, course.name)

Fetch unanswered discussion threads

from pyedstem import EdStemClient

course_id = 12345

with EdStemClient.from_env() as client:
    threads = client.workflows.list_course_unanswered_threads(course_id)

for thread in threads:
    print(f"#{thread.number}: {thread.title}")

Post an answer

from pyedstem import EdStemClient

with EdStemClient.from_env() as client:
    client.threads.post_answer(
        thread_id=67890,
        markdown="Hi there,\n\nThanks for the question...",
    )

Features

  • typed models for common Ed Stem responses
  • sync-first client API with resource groups
  • workflow helpers for active-course and unanswered-thread automation
  • markdown-to-Ed document conversion for answer posting
  • opt-in live contract tests for undocumented API drift detection

Development

Clone the repository, then install development dependencies with uv:

uv sync --group dev

Run the test suite:

uv run pytest tests

Live contract tests

The repository includes an opt-in live suite under tests/live/ that probes documented Ed endpoints so API changes can be detected early.

Safe read-only live tests:

EDSTEM_RUN_LIVE_TESTS=1 uv run pytest tests/live/test_endpoint_contracts.py tests/live/test_restricted_endpoint_contracts.py

Opt-in write test for posting answers:

EDSTEM_RUN_WRITE_TESTS=1 \
EDSTEM_WRITE_TEST_THREAD_ID=12345 \
uv run pytest tests/live/test_write_endpoint_contracts.py

Only enable the write suite when it is safe to mutate real Ed data.

Publishing

Build distribution artifacts with:

uv build

Recommended: GitHub Actions trusted publishing

This repository now includes .github/workflows/publish.yml, which:

  • runs tests
  • builds the wheel and source distribution
  • checks package metadata with twine check
  • publishes to PyPI using GitHub Actions OIDC trusted publishing

To enable it for this repository:

  1. In PyPI, open the pyedstem project and add a Trusted Publisher under Manage → Publishing.
  2. Use these values for the publisher configuration:
    • Owner: AlexDrBanana
    • Repository name: pyedstem
    • Workflow name: publish.yml
    • Environment name: leave this blank
  3. Publish by creating a GitHub release, or run the workflow manually from the Actions tab.

No PyPI token needs to be stored in GitHub secrets for this flow.

If you later want an approval gate in GitHub before publishing, you can add a GitHub environment such as pypi and then update the trusted publisher config to match it.

Documentation

This repository can also publish an automatic docs site from code docstrings using MkDocs and mkdocstrings.

  • local preview: uv sync --group dev --group docs && uv run mkdocs serve
  • production docs: .github/workflows/docs.yml
  • published site URL: https://alexdrbanana.github.io/pyedstem/

To enable GitHub Pages deployment:

  1. In GitHub, open Settings → Pages.
  2. Set Source to GitHub Actions.
  3. Push to main or run the docs workflow manually.

Because the docs workflow also runs on published releases, the package release and docs deployment stay in sync automatically.

Manual fallback

If you ever want to publish locally instead, you can still use the named uv index and provide credentials through environment variables:

UV_INDEX_PYPI_RELEASE_USERNAME=__token__ \
UV_INDEX_PYPI_RELEASE_PASSWORD=your-pypi-token \
uv publish --index pypi-release

The pypi-release index is configured in pyproject.toml with the correct PyPI download and upload URLs. Keep credentials out of the file and provide them only at publish time.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyedstem-0.2.1.tar.gz (45.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyedstem-0.2.1-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file pyedstem-0.2.1.tar.gz.

File metadata

  • Download URL: pyedstem-0.2.1.tar.gz
  • Upload date:
  • Size: 45.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyedstem-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ca560db4b2d4b2b18ce557af5648457a31d3f8b4501ff8f0cdad20e890aa4e71
MD5 ed93a79c40464ca29f2cdd739061d919
BLAKE2b-256 48d81beca9076f9dc3a38ede7017791498d971e915e4a4a05b5945457a51deb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyedstem-0.2.1.tar.gz:

Publisher: publish.yml on AlexDrBanana/pyedstem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyedstem-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: pyedstem-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyedstem-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a1e2499b56ffd69b860c2883195405e7ee78fae15c955bf9b0a05308eb6c3d3a
MD5 4de2546e87d2c070dd11a2e64c42f2c2
BLAKE2b-256 744bb3f04fe97eae6ce013a6ce0421afe9a58bc0aea9aa42f4a8ffea994c4f4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyedstem-0.2.1-py3-none-any.whl:

Publisher: publish.yml on AlexDrBanana/pyedstem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page