ofscli — OFS school portal CLI
Raw JSON access to the OFS "My OFS" portal resources: calendar, assessment, class resources, attendance, classes, timetable, MYP report, awards, homework.
Responses are saved verbatim (no formatting / further processing) under
data/<resource>/<timestamp>/ and echoed to stdout. JSON is preferred;
if a resource only exposes HTML/PDF, the raw bytes are saved as-is.
⚠️ Be a good neighbor. This tool talks to a real school portal. It is rate-limited, caches responses, and fetches on demand by default — please keep it that way and do not bulk-download the portal.
Install
pip install ofscli # from PyPI
# or from source:
# cd ofscli && uv sync
Setup
cp .env.example .env # fill in OFS_USERNAME / OFS_PASSWORD / OFS_STUDENT_ID / OFS_BASE_URL
OFS_BASE_URL is required: point it at your school's "My OFS" JSON-RPC
endpoint, e.g. https://<portal-host>/my-ofs/servlet/JSON-RPC. The tool
deliberately does not hard-code any school domain.
Usage
# one-time login (persists session to .ofscli/session.json)
ofscli login
# resources (each prints + saves raw JSON)
ofscli overview # user/student detail + classInfo (classes)
ofscli classes # class list (from overview payload)
ofscli grades # student grade history
ofscli homework list # homework list
ofscli homework detail --id 123 # one homework detail
ofscli homework download # details for homework due within 14 days
ofscli homework download --days 30 # wider window
ofscli homework download --all # every assignment (not recommended)
ofscli calendar # school calendar, current month
ofscli calendar --student # student calendar
ofscli calendar -m 6 -y 2026 # specific month/year
ofscli assessment # list semesters
ofscli assessment --semester-id 5 # assessment data for a semester
ofscli resources # all class resources
ofscli resources --class-id 42 # one class's resources
ofscli attendance # attendance record
ofscli timetable # timetable details
ofscli myp # MYP report result
ofscli awards # awards list
# exploration
ofscli discover # all discovered JSON-RPC methods
ofscli raw <method> '[params...]' # call any method with raw params
Being a good neighbor
The portal is a real school system — treat it gently. ofscli ships with
three layers of protection (all configurable):
| Feature | Default | Env var | CLI flag |
|---|---|---|---|
| Rate limit — min seconds between any two HTTP requests, with ±50% jitter so bursts don't stay in lockstep | 1.5 s | OFS_MIN_INTERVAL |
--min-interval |
| Prime caching — the referrer page is GET at most once per 10 min instead of before every RPC call (halves request count) | 600 s | OFS_PRIME_TTL |
— |
Response cache — read-only RPC results cached on disk under data/cache/, keyed by method+params |
900 s | OFS_CACHE_TTL |
--cache-ttl / --no-cache |
homework download is on-demand by default: it only fetches details for
assignments due within --days (default 14). Use --limit N to cap the
number of detail fetches, and --all only if you really need everything.
# examples
ofscli homework download --days 7 --limit 5 # small, polite
OFS_MIN_INTERVAL=3 ofscli homework list # slower, gentler
ofscli homework list --no-cache # force a fresh fetch
Discovered JSON-RPC methods
| Resource | Method | Params |
|---|---|---|
| overview | studentOverviewDelegate.getStudentOverview |
[studentId] |
| grades | studentOverviewDelegate.getStudentGrades |
[userId] |
| homework list | homeworkDelegate.getHomeworkListForParent |
[userId, classId, sort, page, []] |
| homework detail | homeworkDelegate.getHomeworkForParent |
[homeworkId, 2, studentId, false] |
| school calendar | academicCalendarDelegate.getCalendarEvents |
[month, year] |
| student calendar | academicCalendarDelegate.getCalendarEventsForStudent |
[studentId, month, year] |
| assessment semesters | assessmentDelegate.getStudentSemesterData |
[studentId] |
| assessment | assessmentDelegate.getStudentAssessmentDataBySemesterId |
[studentId, semesterId] |
| assessment detail | assessmentDelegate.getStudentAssessmentDataByDate |
[assessmentId, createdDate] |
| class resources | classResourceDelegate.getAllStudentClassResources |
[userId] |
| class resources (one) | classResourceDelegate.getClassResources |
[userId, classId] |
| attendance | attendanceDelegate.getStudentAttendance |
[userId] |
| timetable | userDelegate.getStudentTimetableDetails |
[userId] |
| MYP report | academicReportDelegate.getMYPResult |
[studentId] |
| awards | awardsDelegate.getStudentAwardsForOverview |
[userId] |
Methods were discovered by inspecting the portal's own JavaScript
(student-overview.min.js, school-calendar-plugin.min.js,
assessment-student.min.js, myp-report-tab.min.js,
student-awards-tab.min.js, dashboard.min.js).
Notes
userIdusually equalsstudentIdfor a single-child account; the CLI falls back tostudentIdwhen--user-idis not given.- Session cookies +
clientDeviceIdare persisted afterlogin; commands reuse the session until it expires (then re-runofscli login --force). ofscli rawis the exploration escape hatch for any method, including the extra ones listed byofscli discover(mail, library, reports, etc.).calendar --student(getCalendarEventsForStudent) is permission-gated: the portal returns code 490 "You do not have permission to view the calendar of this student" for a student account. The school calendar (calendarwithout--student) works for everyone.dashboardDelegate.getAsyncDatareturns{}for this account; the dashboard methods are listed underdiscoverfor staff/parent accounts that have dashboard widgets.
Security
.env(credentials) and.ofscli/(session cookies) are git-ignored — never commit them. Copy.env.exampleand fill in your own values.- The session file contains live portal cookies; treat it like a password.
- This is an unofficial tool, not affiliated with Overseas Family School (OFS). Personal use only. Use at your own risk and respect the portal's terms of service.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ofscli-0.2.1.tar.gz.
File metadata
- Download URL: ofscli-0.2.1.tar.gz
- Upload date:
- Size: 20.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7eb6240c1cfe935b08bdd5f103ae2ddeb606af5ec40c7cdb2e7338d89966aa60
|
|
| MD5 |
57f09f10034c202ff61e6f8da1bd3e0c
|
|
| BLAKE2b-256 |
54e4a7886c126027693810af6ab31ae3a6e0cc980204fbe17ce20c5dd6f14772
|
File details
Details for the file ofscli-0.2.1-py3-none-any.whl.
File metadata
- Download URL: ofscli-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90d4aa3ac1a4d4c9c66b45f45f5f2c674e3cedb64e41015326fcccc96123875c
|
|
| MD5 |
7f42ee622782cfb08c92b83fcd5349ab
|
|
| BLAKE2b-256 |
f4cdd464e02b06e99f27b4d29d19c5ff6e9d8d4aa9b88892607cc0490851ab99
|