Advanced Usage#

Session Object#

The pysjtu.session.Session object contains iSJTU session state, handles login operation, and persists certain parameters and some inner states across requests. And it has an HTTP request interface to help you send requests as a logged user.

In QuickStart, we used pysjtu.client.create_client() function to acquire a pysjtu.client.Client. Under the hood, create_client creates a pysjtu.session.Session for you. But if you need features like session persistence, proxies and tuned timeout, you need to create the session manually.

Login#

There’s several ways to acquire a login session.

First, let’s login with username and password:

sess = pysjtu.Session(username="...", password="...")

A pysjtu.session.Session.login() method is provided, in case you want to provide username and password later:

sess = pysjtu.Session()
sess.login("username", "password")

And, if you have cookie contains session info, you may login with this cookie:

sess = pysjtu.Session(cookies=...)

The cookies parameter accepts any cookie type that HTTPX accepts (currently HTTPX.Cookies, CookieJar, and dict). Also, cookies can be set later:

sess = pysjtu.Session()
sess.cookies = ...

Warning

A session validation is performed when setting cookies. If your cookie doesn’t contain valid user information, a pysjtu.exceptions.SessionException will be raised. To skip this validation, set _cookies.

sess = pysjtu.Session()
sess.cookies = some_invalid_cookies  # This will fail.
sess._cookies = some_invalid_cookies  # This won't.

Session Persistence#

You may want to dump your login session to use it later.

To persist your session, you simply call the pysjtu.session.Session.dump() function, which returns a dict containing session info. And the pysjtu.session.Session.dumps() function will save session info to your specified file.

logged_sess.dump()
# {'username': '...', 'password': '...', 'cookies': {...}}
logged_sess.dumps("session.file")  # session saved to ./session.file
logged_sess.dumps(f)  # session saved to 'f' file-like object

Similarly, to load your saved session, you call the pysjtu.session.Session.load() and pysjtu.session.Session.loads() function.

sess.load({...})
sess.loads("session.file")
sess.loads(f)

Besides, saved session files can be loaded when initializing the object:

sess = pysjtu.Session(session_file="session.file")

Sessions can also be used as context managers. This will make sure the session file is updated when exiting the with block, even if unhandled exceptions occurred.

with pysjtu.Session(session_file="session.file") as sess:
    sess.get(...)

Note

The given file must exist, or a FileNotFound exception will be raised. But passing in an empty file is allowed, emptying username, password and cookies.

Configuration#

Sessions can be used to provide configs to requests. Just like Sessions in requests and Clients in HTTPX, this is done by passing parameters to the pysjtu.client.Client constructor.

s = pysjtu.Session(cookies=..., proxies="http://127.0.0.1:8888", timeout=1.0)

HTTP Requests#

You can use a pysjtu.session.Session to send HTTP requests as a logged user:

s.request("GET", "https://i.sjtu.edu.cn/...")
s.get("https://i.sjtu.edu.cn/...")
s.post("https://i.sjtu.edu.cn/...")
s.put("https://i.sjtu.edu.cn/...")
s.delete("https://i.sjtu.edu.cn/...")
s.head("https://i.sjtu.edu.cn/...")
s.options("https://i.sjtu.edu.cn/...")

They share the same interface with HTTPX.

By default, a session validation will be performed, and the session will be automatically renewed if it’s expired.

Note

Auto session renewal works by automatically login again with the given username and password.

If the session is expired, and username and password hasn’t been provided (you login by providing cookies only), pysjtu.exceptions.SessionException will be raised. If the provided username and password is invalid, pysjtu.exceptions.LoginException will be raised.

They can be opt-out by calling request methods with validate_session, auto_renew, or both set to False.

s.get("https://i.sjtu.edu.cn/...", validate_session=False)
s.get("https://i.sjtu.edu.cn/...", auto_renew=False)

Note

If validate_session is True, auto_renew is False, and your session is expired, pysjtu.exceptions.SessionException will be raised.

Client Object#

The pysjtu.client.Client object provides a developer-friendly interface to iSJTU APIs. It uses an authenticated pysjtu.session.Session object to send HTTP requests.

Initialization#

To initialize a pysjtu.client.Client object, you pass in a pysjtu.session.Session object described in the previous section.

client = pysjtu.Client(session=sess)

Note

The new client object is bounded with the session passed in, which means API calls may alter the session’s internal states (cookies, etc). You may change session’s settings at any time, and these changes will reflect on client behaviours immediately.

If you haven’t initialized any pysjtu.session.Session yet and you want to login with a pair of username & password, pysjtu.client.create_client() function will help you get one and initialize a pysjtu.client.Client.

client = pysjtu.create_client("username", "password")

Usages#

There are two types of API: properties and methods. For detailed usage, see iSJTU Interface.

HTTP Proxying#

PySJTU supports HTTP proxies.

To forward all traffic to http://127.0.0.1:8888, you may set the proxy information at pysjtu.session.Session initialization.

s = pysjtu.Session(proxies="http://127.0.0.1:8888")

For detailed usage, refer to HTTPX: HTTP Proxying.

Timeout Configuration#

Like HTTPX, PySJTU has strict timeouts.

Timeouts can be enforced request-wise and session-wise.

Warning

A common pitfall is that the default timeout is too short for GPA related requests. To avoid this, you may set the timeout separately for these requests.

s = pysjtu.Session(timeout=10)
s.get("https://i.sjtu.edu.cn", timeout=10)

For detailed usage, refer to HTTPX: Fine tunning the configuration.

OCR#

During login, captcha is solved automatically using built-in OCR engines. There are three OCR engines you may choose from: pysjtu.ocr.LegacyRecognizer, pysjtu.ocr.NNRecognizer and pysjtu.ocr.JCSSRecognizer.

The first two are offline OCR engines, and the last one is an online one. To use an offline engine, you need to install PySJTU with ocr extra dependencies. For detailed comparison, see Recognizers.

The default engine is pysjtu.ocr.JCSSRecognizer. You may pick another one by passing it to the pysjtu.session.Session constructor.

s = pysjtu.Session(ocr=pysjtu.NNRecognizer())
# or to use the client directly,
c = pysjtu.create_client(ocr=pysjtu.NNRecognizer())