A typed, retrying, rate-limited unofficial client for RateMyProfessors.
Looking for TypeScript? Check out the TypeScript version.
- Python 3.10 or later
- Works with type checkers (Pydantic models, fully typed API)
pip install ratemyprofessors-clientCreate a client and call any of these methods. See the full docs for parameters, return types, and examples.
from rmp_client import RMPClient
with RMPClient() as client:
...Schools
search_schools(query)— Search schools by name. Returns paginated results.get_school(school_id)— Get a single school by its numeric ID.get_compare_schools(school_id_1, school_id_2)— Fetch two schools side by side.get_school_ratings_page(school_id)— Get one page of school ratings.iter_school_ratings(school_id)— Iterator over all ratings for a school.
Professors
search_professors(query)— Search professors by name. Returns paginated results.list_professors_for_school(school_id)— List professors at a given school.iter_professors_for_school(school_id)— Iterator over all professors at a school.get_professor(professor_id)— Get a single professor by their numeric ID.get_professor_ratings_page(professor_id)— Get one page of professor ratings.iter_professor_ratings(professor_id)— Iterator over all ratings for a professor.
Low-level
raw_query(payload)— Send a raw GraphQL payload to the RMP endpoint.
Lifecycle
close()— Close the client. Safe to call multiple times.
All errors extend RMPError. Catch and narrow with isinstance:
HttpError— The server returned a non-2xx status code (e.g. 404, 500).ParsingError— The response couldn't be parsed (e.g. professor/school not found).RetryError— The request failed after all retry attempts. Contains the last underlying error.RMPAPIError— The GraphQL API returned anerrorsarray in the response.ConfigurationError— Invalid client configuration.
from rmp_client import RMPClient, HttpError, ParsingError
with RMPClient() as client:
try:
prof = client.get_professor("2823076")
except ParsingError:
print("Professor not found")
except HttpError as e:
print(f"HTTP error: {e.status_code}")All methods return Pydantic models. Import any of these:
from rmp_client.models import (
School,
Professor,
Rating,
SchoolRating,
ProfessorSearchResult,
SchoolSearchResult,
ProfessorRatingsPage,
SchoolRatingsPage,
CompareSchoolsResult,
)School— ID, name, location, overall quality, category ratings (reputation, safety, etc.)Professor— ID, name, department, school, overall rating, difficulty, percent take againRating— Date, comment, quality, difficulty, tags, course, thumbs up/downSchoolRating— Date, comment, overall score, category ratings, thumbs up/downProfessorSearchResult/SchoolSearchResult— Paginated list withhas_next_pageandnext_cursorProfessorRatingsPage/SchoolRatingsPage— One page of ratings with cursor paginationCompareSchoolsResult— A pair of schools
Optional helpers for data pipelines:
from rmp_client import (
analyze_sentiment,
normalize_comment,
is_valid_comment,
build_course_mapping,
clean_course_label,
)normalize_comment(text, *, strip_html=True, strip_punctuation=False)— Normalize text for deduplication (trim, strip HTML, lowercase, collapse whitespace; optionally strip punctuation)is_valid_comment(text, *, min_len=10)— Validate a comment and return aValidationResultwith diagnostics (empty, too short, all caps, excessive repeats, no alpha)clean_course_label(raw)— Clean scraped course labels (remove counts, normalize whitespace)build_course_mapping(scraped, valid)— Map scraped labels to known course codesanalyze_sentiment(text)— Compute sentiment label from text (uses TextBlob)