LinkedIn API Python Client
Official Python client for LinkedIn's Rest.li APIs, wrapping OAuth2, versioned endpoints, and query tunneling into typed request/response calls.
Repository Health
Technical Analysis
LinkedIn API Python Client is LinkedIn’s own thin wrapper around the requests library for calling LinkedIn’s Rest.li-based APIs. Rest.li is a robust but idiosyncratic RPC-over-HTTP protocol, and this client exists to remove the busywork of getting it right: correct headers, protocol-version-2.0.0 query encoding, automatic query tunneling for oversized GET requests, and consistent handling of versioned vs. non-versioned base URLs.
The package ships two classes. RestliClient exposes one method per Rest.li verb (get, batch_get, get_all, finder, batch_finder, create, batch_create, update, batch_update, partial_update, batch_partial_update, delete, batch_delete, action) and returns typed response objects rather than raw JSON. AuthClient covers the 2-legged and 3-legged OAuth2 flows LinkedIn’s APIs require: generating the member authorization URL, exchanging an authorization code or refresh token for an access token, retrieving client-credential tokens, and introspecting tokens for status and expiry.
What You Get
- A
RestliClientcovering every Rest.li method (GET, BATCH_GET, GET_ALL, FINDER, BATCH_FINDER, CREATE, BATCH_CREATE, UPDATE, BATCH_UPDATE, PARTIAL_UPDATE, BATCH_PARTIAL_UPDATE, DELETE, BATCH_DELETE, ACTION) with keyword-only arguments and typed response objects - An
AuthClientimplementing 2-legged and 3-legged OAuth2, refresh-token exchange, and access-token introspection - Automatic query tunneling: oversized GET requests are silently rewritten into POST-based tunneled requests per LinkedIn’s protocol, so callers never hit URL-length limits
- Built-in URN and query-parameter encoding utilities matching Rest.li protocol version 2.0.0
- Support for LinkedIn’s versioned APIs via a
version_stringargument on every call - A custom exception hierarchy (
InvalidArgumentError,MissingArgumentError,ResponseFormattingError,InvalidSerializedRestliError) for explicit failure modes instead of generic HTTP errors
Common Use Cases
- Fetching a signed-in member’s profile via Sign In With LinkedIn (OpenID Connect) using a 3-legged access token
- Creating and managing LinkedIn ad accounts and campaign groups through the Advertising APIs
- Publishing organic posts to LinkedIn via the Share API
- Building the OAuth2 authorization-code redirect flow for a web app that needs member-scoped LinkedIn access
- Batch-fetching or batch-updating multiple Rest.li entities (e.g. campaign conversions) in a single call
Under The Hood
Architecture
RestliClient composes a layered request pipeline: each of its 13 public methods (get, batch_get, finder, create, update, delete, action, and their batch/partial variants) builds query parameters via the encoder utilities, constructs the target URL through utils/api.py::build_rest_url, routes the prepared request through utils/query_tunneling.py (which automatically rewrites oversized requests into LinkedIn’s query-tunneling format), sends it over a shared requests.Session, and hands the raw response to a per-method formatter class in response_formatter.py that decodes it into a typed object from response.py. AuthClient is a separate, parallel class for the five OAuth2 flows, sharing only the common/constants.py and common/errors.py modules with the Rest.li client. The encode-build-tunnel-send-format pipeline is identical across every Rest.li verb, so protocol-level changes touch only the shared utils layer, not thirteen separate method bodies.
Tech Stack
Python 3.7+, managed with Poetry. The sole runtime dependency is requests (unpinned in pyproject.toml). Dev dependencies are pytest plus the responses library for mocking HTTP calls in tests, curlify and flask for local example/debugging tooling, python-dotenv for example configuration, pre-commit with black and Conventional Commits enforcement, and twine for PyPI publishing. There is no async client, no ORM, and no web framework dependency — the library is deliberately scoped to being a thin, synchronous outbound HTTP client.
Code Quality
The test suite (nearly 900 lines in the main client test file, plus dedicated encoder/decoder unit tests) uses pytest with the responses library to mock HTTP responses and parametrizes every Rest.li method against representative request/response fixtures, rather than hitting live LinkedIn endpoints. CI runs this suite across Python 3.7 through 3.10 via GitHub Actions and Poetry. Pre-commit hooks enforce black formatting and Conventional Commit messages on every commit. Public methods use keyword-only arguments and type hints (Optional, Union, generic TypeVar bounds) throughout, though there is no strict static type-checking (mypy) configured. A custom exception hierarchy keeps failure modes explicit instead of leaking raw requests exceptions.
API Design
Every public method carries an exhaustive docstring with a runnable usage example, covering all 13 Rest.li verbs and all 5 auth flows — reference-quality documentation embedded directly in the source. The library’s real value is hiding the awkward parts of LinkedIn’s Rest.li protocol: automatic query tunneling for oversized GET requests, consistent handling of versioned vs. non-versioned base URLs, and protocol-version-2.0.0-compliant parameter encoding — details a hand-rolled requests wrapper would likely get wrong. It isn’t a novel general-purpose pattern, but it is a well-scoped, purpose-built encoding of a genuinely uncommon protocol.