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.

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.0.tar.gz (26.1 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.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pyedstem-0.2.0.tar.gz
  • Upload date:
  • Size: 26.1 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.0.tar.gz
Algorithm Hash digest
SHA256 fa8c33da10257eeecd602e331d2f1090b46253ae0be62b4790dd68275ea080ca
MD5 938c7cb8e31970896f7807fbb7af55ea
BLAKE2b-256 5d963a4a6f60ce1fb707c1b69d85c98abed1ebcd3f5b8477e7c9aea9fe9fb550

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyedstem-0.2.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: pyedstem-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.0 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 599347f51487041c36666996764d08afc1d8976d851c1131781d425fa210666a
MD5 89d0191c3575b876c59fdcb1c17876ba
BLAKE2b-256 e39efa1b2a482dc6d02042ef672aae865efb98ecf540b4bdff3efdbbaeb8ca6c

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyedstem-0.2.0-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