Skip to main content

releasetrain-sentiment

Scores sentiment per comment in a Reddit discussion thread, flagging author replies vs. community responses, to measure sentiment divergence over time.

Install

pip install releasetrain-sentiment

Two optional extras:

pip install releasetrain-sentiment[classify]   # TPS/GDS classifier (scikit-learn)
pip install releasetrain-sentiment[fetch]      # live ReleaseTrain API wrapper (requests)

Quickstart: scoring a thread

from releasetrain_sentiment import score_post, trajectory_summary

post = {
    "title": "Update broke my build",
    "description": "Nothing compiles since 3.2.0",
    "comments": [
        {"text": "Known issue, fix coming soon", "author": "dev1", "is_author": True},
        {"text": "Same here, very annoying", "author": "user2", "is_author": False},
        {"text": "Thanks for the heads up", "author": "dev1", "is_author": True},
    ],
}

results = score_post(post)
# results[0] is the post itself (source="post", index=-1)
# results[1:] is one entry per comment, same order as the input,
# each with compound/pos/neu/neg/label and is_author

summary = trajectory_summary(results)
# {"author_avg": ..., "community_avg": ..., "author_shift": ..., "community_shift": ...}

score_posts(list_of_posts) runs the same thing over a batch, returning one results array per input post, same order.

Modules

  • score.py: the scorer above. Pure function, no network calls, no ReleaseTrain coupling. Standard VADER thresholds (compound >= 0.05 positive, <= -0.05 negative).
  • baseline_vader.py: a reconstruction of the paper's "technical_first" VADER baseline described in Reviewer #7's feedback (a keyword exemption plus a narrower +/- 0.15 neutral band). This is a reconstruction from the reviewer's written description, not the original experiment code, which was not available when this package was built. See the module docstring before citing it as a faithful reproduction.
  • classify.py: a trainable TF-IDF + Multinomial Naive Bayes pipeline (Reviewer #9: "Multinomial Naive Bayes achieves the best balance in identifying the minority TPS class"). No pretrained model ships with this package; train it on your own labeled data.
  • corpus.py: the corpus and labeling documentation reviewers #4, #7, and #9 each independently asked for (which subreddits/timeframes, what API, how labeled). ENHANCED_AUTOMATED_CORPUS is filled in from real, verified data; TPSGDS542_CORPUS has placeholder fields that need the actual gold-dataset values filled in before citing it in the paper.
  • evaluate.py: sample_high_divergence() implements Reviewer #4's suggested audit (30 high-divergence TPS threads vs. 30 high-divergence GDS threads); evaluate_predictions() is a small precision/recall/F1 harness for testing the "helps developers find useful reports" claim against a labeled ground truth, however small.
  • fetch.py: an optional thin wrapper around ReleaseTrain's /api/reddit endpoint, isolated from every other module so none of them need network access to run or be tested.

Example: the keyword-contamination check

from releasetrain_sentiment import flags_technical_keyword

flags_technical_keyword("That redesign was a massive error")  # True
flags_technical_keyword("I am so tired of this company")       # False

The first example is the exact contamination Reviewer #7 describes: the keyword fires regardless of whether the comment is actually a bug report.

Example: training a classifier

from releasetrain_sentiment import train_classifier, classify, save_classifier

texts = ["crash on launch every time", "app freezes after the update",
         "I'm so tired of this company", "another pointless update, ugh"]
labels = ["TPS", "TPS", "GDS", "GDS"]

pipe = train_classifier(texts, labels)
classify(pipe, ["the app crashed again"])  # ["TPS"]
save_classifier(pipe, "tps_gds_model.joblib")

Known limitations

  • No pretrained TPS/GDS classifier ships with this package. The original 542-post gold-labeled dataset was not available when it was built.
  • baseline_vader.py is a best-effort reconstruction of a described flaw, not a verified reproduction of the original experiment code.
  • TPSGDS542_CORPUS in corpus.py has unfilled fields (subreddit list, date range, labeling process) that need the real dataset to complete.

Releasing to PyPI

Publishing uses PyPI's Trusted Publishing: no API token is stored in this repo or anywhere else. One-time setup, done once by whoever owns the sberhe-se4cps PyPI account:

  1. Go to https://pypi.org/manage/account/publishing/
  2. Add a new pending publisher with:
    • PyPI project name: releasetrain-sentiment
    • Owner: SE4CPS
    • Repository name: releasetrain-sentiment
    • Workflow name: publish.yml
    • Environment name: pypi
  3. Save it. This registers the project on PyPI without uploading anything yet.

After that, every GitHub Release published from this repo (tag it v0.1.0, draft a release from that tag) automatically builds and publishes to PyPI via .github/workflows/publish.yml. No further manual steps or secrets needed.

License

MIT

Metadata

Release files for releasetrain-sentiment 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for releasetrain-sentiment 0.1.0
File Size Uploaded
releasetrain_sentiment-0.1.0.tar.gz 15.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for releasetrain-sentiment 0.1.0
File Interpreter ABI Platform
releasetrain_sentiment-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.8 kB

Release files / releasetrain_sentiment-0.1.0.tar.gz

Download URL releasetrain_sentiment-0.1.0.tar.gz
Size 15.4 kB
Tags Source
SHA-256 checksum
How to use checksums
d29a395369ed10d5ab3e33556be7f435f1b076a826370893d75f34ac8e465182
BLAKE2b-256 checksum
How to use checksums
535aaefa3795bb42a121dc6b52c0c35040e9ed4517899216c7ce60f1f88d345d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / releasetrain_sentiment-0.1.0-py3-none-any.whl

Download URL releasetrain_sentiment-0.1.0-py3-none-any.whl
Size 17.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6a9339edf9294cd1dc2baebdbef5b6601b385df5c39aeea549df74bd62c245cf
BLAKE2b-256 checksum
How to use checksums
b91c9a8b52873b1a2b1eab047e594c49fa20adb38d93462032900288481fb9a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page