Skip to content

Commit a4c395c

Browse files
committed
Client: add session_callback for when a new session is created
...via createSession or refreshSession
1 parent d56e96f commit a4c395c

3 files changed

Lines changed: 22 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ Here's how to package, test, and ship a new release.
234234
* `Base`:
235235
* Expose lexicons in `defs` attribute.
236236
* `Client`:
237-
* Add minimal auth support with `access_token` constructor kwarg and attribute. To send authenticated requests, call `createSession` or `refreshSession` to get an access token, then set it on a `Client`.
237+
* Add minimal auth support with `access_token` and `refresh_token` constructor kwargs and `session` attribute. If you use a `Client` to call `com.atproto.server.createSession` or `com.atproto.server.refreshSession`, the returned tokens will be automatically stored and used in future requests.
238238
* Bug fix: handle trailing slash on server address, eg `http://ser.ver/` vs `http://ser.ver`.
239239
* Default server address to official `https://bsky.social` PDS.
240240
* Add default `User-Agent: lexrpc (https://lexrpc.readthedocs.io/)` request header.

lexrpc/client.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,20 @@ class Client(Base):
6868
"""
6969

7070
def __init__(self, address=DEFAULT_PDS, access_token=None,
71-
refresh_token=None, headers=None, **kwargs):
71+
refresh_token=None, headers=None, session_callback=None,
72+
**kwargs):
7273
"""Constructor.
7374
7475
Args:
7576
address (str): base URL of XRPC server, eg ``https://bsky.social/``
7677
access_token (str): optional, will be sent in ``Authorization`` header
7778
refresh_token (str): optional; used to refresh access token
7879
headers (dict): optional, HTTP headers to include in every request
80+
session_callback (callable, dict => None): called when a new session
81+
is created with new access and refresh tokens. This callable is
82+
passed one positional argument, the dict JSON output from
83+
``com.atproto.server.createSession`` or
84+
``com.atproto.server.refreshSession``.
7985
kwargs: passed through to :class:`Base`
8086
8187
Raises:
@@ -93,6 +99,7 @@ def __init__(self, address=DEFAULT_PDS, access_token=None,
9399
'accessJwt': access_token,
94100
'refreshJwt': refresh_token,
95101
}
102+
self.session_callback = session_callback
96103

97104
def __getattr__(self, attr):
98105
if NSID_SEGMENT_RE.match(attr):
@@ -109,7 +116,9 @@ def call(self, nsid, input=None, **params):
109116
params: optional method parameters
110117
111118
Returns:
112-
dict or generator iterator: for queries and procedures, decoded JSON object, or None if the method has no output. For subscriptions, generator of messages from server.
119+
dict or generator iterator: for queries and procedures, decoded JSON
120+
object, or None if the method has no output. For subscriptions,
121+
generator of messages from server.
113122
114123
Raises:
115124
NotImplementedError: if the given NSID is not found in any of the
@@ -174,6 +183,8 @@ def call(self, nsid, input=None, **params):
174183
if output and nsid in (LOGIN_NSID, REFRESH_NSID):
175184
logger.info(f'Logged in as {output.get("did")}, storing session')
176185
self.session = output
186+
if self.session_callback:
187+
self.session_callback(output)
177188

178189
self._maybe_validate(nsid, 'output', output)
179190
return output

lexrpc/tests/test_client.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,17 @@ def test_refresh_token(self, mock_post, mock_get):
274274
]
275275
mock_post.return_value = response(session)
276276

277-
client = Client(access_token='towkin', refresh_token='reephrush')
277+
callback_got = []
278+
def callback(session):
279+
nonlocal callback_got
280+
callback_got.append(session)
281+
282+
client = Client(access_token='towkin', refresh_token='reephrush',
283+
session_callback=callback)
278284
got = client.com.atproto.server.describeServer(x='y')
279285
self.assertEqual(output, got)
280286
self.assertEqual(session, client.session)
287+
self.assertEqual([session], callback_got)
281288

282289
mock_get.assert_any_call(
283290
'https://bsky.social/xrpc/com.atproto.server.describeServer?x=y',

0 commit comments

Comments
 (0)