aiograpi is the async Instagram private-API library (475★ on GitHub). A version bump of our vendored copy surfaced two real bugs. Both are fixed, tested, and PR'd upstream.
1. photo_upload extracts media from the wrong response
photo_upload retries photo_configure up to 10 times, then pulls the uploaded media out of self.last_json:
if await self.photo_configure(...):
media = await self._extract_configured_media_or_recent(
self.last_json, # shared mutable state
...
)
self.last_json is the client's shared "last response" field. In a single-upload flow it happens to equal the configure response. Run two uploads concurrently and another coroutine's response can land in self.last_json between the configure call and the read — you extract media from the wrong request, or fail outright.
photo_configure already returns the configured dict. The retry loop was discarding it:
if configure_result := await self.photo_configure(...):
media = await self._extract_configured_media_or_recent(
configure_result,
...
)
Race gone.
2. Instagram's token rotation gets silently dropped
Instagram rotates the bearer token mid-session and returns it in the ig-set-authorization response header. aiograpi parsed that header in exactly one place — the login flow. A rotation returned on any other private request was dropped, so authorization_data went stale and every later request rebuilt a stale Authorization header.
The fix moves the parse into the shared private-request handler, so any response carrying the header updates the client:
authorization = response.headers.get("ig-set-authorization")
if authorization:
self.authorization_data = self.parse_authorization(authorization)
Shipped with tests
Each fix has a regression test (mocked transport / mocked configure) and passes the project's ruff + pytest gates.
Top comments (0)