LinkedIn klienti: OAuth, profil va postlar
LinkedIn — Socialift Python SDK'dagi LinkedIn API klienti. U 3-legged OAuth va OpenID Connect (openid, profile, email) orqali a'zoni ulaydi, tokenni almashtiradi, tekshiradi va ruxsat bo'lsa yangilaydi, userinfo dan profil oladi hamda a'zo nomidan Posts API orqali matnli yoki havolali post yaratadi, o'qiydi va o'chiradi. LinkedIn shaxsiy xabarlari va Lead Gen Forms bu klientda yo'q.
from socialift import LinkedIn10 ta metodsocialift 1.3.0 bo'yichaYangilangan:
LinkedIn klientini qanday sozlash kerak?
Klient LinkedIn(client_id=..., client_secret=...) bilan yaratiladi. LinkedIn.from_env() qiymatlarni LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET va LINKEDIN_API_VERSION dan o'qiydi. Client ID va Client Secret LinkedIn Developer Portal'dagi app'ning Auth bo'limida turadi, redirect URL ham o'sha yerda qo'shiladi — batafsil «LinkedIn app sozlash» qo'llanmasida.
Scope'lar app'ga qo'shilgan mahsulotlarga bog'liq: «Sign In with LinkedIn using OpenID Connect» — openid, profile, email; «Share on LinkedIn» — w_member_social. SDK standart holda shu to'rttasini so'raydi. A'zo postlarini o'qish uchun r_member_social kerak — LinkedIn uni cheklangan ruxsat sifatida faqat tasdiqlangan foydalanuvchilarga beradi.
Posts API (/rest/*) har so'rovda LinkedIn-Version: YYYYMM sarlavhasini talab qiladi; SDK uni api_version dan oladi. LinkedIn har oylik versiyani kamida bir yil qo'llaydi, muddati o'tgan versiyaga HTTP 426 qaytaradi — shuning uchun api_version yoki LINKEDIN_API_VERSION ni faol versiyaga sozlab turing.
import asyncio
import os
from socialift import LinkedIn
async def main():
# 1) Aniq argumentlar bilan
li = LinkedIn(
client_id=os.environ["LINKEDIN_CLIENT_ID"],
client_secret=os.environ["LINKEDIN_CLIENT_SECRET"],
api_version="202609", # faol LinkedIn-Version (YYYYMM)
)
# 2) Yoki muhitdan: LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET,
# LINKEDIN_API_VERSION
# li = LinkedIn.from_env()
async with li:
me = await li.me(os.environ["LINKEDIN_TOKEN"]) # exchange_code() natijasi
print(me.id, me.full_name, li.person_urn(me.id))
asyncio.run(main())
Klient va login
Klientni yaratish, avtorizatsiya havolasi va code ni tokenga almashtirish.
exchange_codefrom_envlogin_url
exchange_code
asyncCallback'dagi code ni /oauth/v2/accessToken da (form-urlencoded) access tokenga almashtiradi va TokenBundle qaytaradi.
await li.exchange_code(code: str, *, redirect_uri: str) -> socialift.models.TokenBundle- LinkedIn qoidasi:
code30 daqiqa amal qiladi;redirect_uriavtorizatsiya so'rovidagi bilan bir xil bo'lishi kerak. - Access token 60 kun amal qiladi;
refresh_tokenfaqat app'da programmatik refresh yoqilgan bo'lsa keladi. - Javobda
access_tokenbo'lmasaApiError.
from_env
classmethodKlientni LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET va LINKEDIN_API_VERSION muhit o'zgaruvchilaridan yaratadi. Kalitlar kodda turmasligi uchun.
LinkedIn.from_env(**kwargs) -> LinkedIn- Bo'sh qiymatlar konstruktorda tekshirilmaydi:
client_idyo'qligilogin_urldaConfigurationErrorbo'lib chiqadi. LINKEDIN_API_VERSIONberilmasa SDK'dagi standart versiya ishlatiladi — u LinkedIn'da hali faol ekanini tekshiring.
A'zoni LinkedIn avtorizatsiya sahifasiga (/oauth/v2/authorization) yuborish uchun havola yasaydi; so'rov yubormaydi. Scope'lar probel bilan ajratiladi, standart: openid, profile, email, w_member_social.
li.login_url(
*,
redirect_uri: str,
state: Optional[str] = None,
scopes: Optional[list[str]] = None,
) -> strclient_idbo'lmasaConfigurationError.state— CSRF himoyasi: callback'dagi qiymat siz yuborganiga teng bo'lmasa so'rovni rad eting (LinkedIn tavsiyasi). SDK uni saqlamaydi.- LinkedIn qoidasi: a'zo so'ralgan scope'larni alohida tanlay olmaydi; ilgari berilganidan boshqa scope so'ralsa avvalgi barcha access tokenlar bekor bo'ladi.
redirect_uriapp'ning Auth bo'limidagi redirect URL'lardan biriga mos bo'lishi kerak.
url = li.login_url(redirect_uri="https://siz.uz/cb", state=state)Token boshqaruvi
Refresh token bilan yangilash va token holatini tekshirish.
introspect
asyncTokenni /oauth/v2/introspectToken da tekshiradi va LinkedIn javobini lug'at sifatida qaytaradi: active, status, expires_at, scope, auth_type va boshqalar. Token hali ishlayaptimi va qachon tugashini bilish uchun.
await li.introspect(token: str) -> dictstatus:active,expiredyokirevoked;scopefaqat 3-legged OAuth tokenlari uchun keladi.- LinkedIn qoidasi: kalitlar to'g'ri, lekin token boshqa app'niki bo'lsa javob 200 va
active: falsebo'ladi — xato ko'tarilmaydi.
info = await li.introspect(token)refresh
asyncRefresh token bilan yangi access token oladi (grant_type=refresh_token) va TokenBundle qaytaradi. Token tugashidan oldin a'zoni qayta login qildirmaslik uchun.
await li.refresh(refresh_token: str) -> socialift.models.TokenBundle- LinkedIn programmatik refresh tokenlarni faqat tasdiqlangan Marketing Developer Platform hamkorlariga beradi; bo'lmasa a'zo avtorizatsiyadan qayta o'tadi.
- Refresh token 365 kun amal qiladi va yangilash uning muddatini uzaytirmaydi; yangi access token 60 kunlik.
- Javobda
access_tokenbo'lmasaApiError.
bundle = await li.refresh(refresh_token)Profil
OpenID Connect profili va muallif URN'i.
me
asyncOpenID Connect userinfo (/v2/userinfo) dan a'zo profilini Profile sifatida qaytaradi: id (= sub), ism, rasm va email. sub post muallifi URN'ini yasash uchun kerak.
await li.me(token: str) -> socialift.models.Profileopenidvaprofilescope'lari kerak, email uchunemail; LinkedIn hujjatiga ko'raemailmaydoni ixtiyoriy va javobda bo'lmasligi mumkin.Profile.username— email, u bo'lmasasub;Profile.rawda locale'dan olingan qo'shimchalanguagebor.
Kerakli ruxsatlar:openidprofileemail
me = await li.me(token)person_urn
staticmethodsub ni urn:li:person:{sub} ko'rinishiga keltiradi — posts va create_post dagi author uchun. Statik metod, so'rov yubormaydi.
LinkedIn.person_urn(sub: str) -> strcreate_postvapostsurn:bilan boshlanmagan qiymatni o'zi shunday o'raydi.
Kerakli ruxsatlar:r_member_socialw_member_social
posts = await li.posts(token, author=li.person_urn(sub), count=10)post = await li.create_post(token, author=li.person_urn(sub), text="Yangiliklar!",
article_url="https://siz.uz/blog")Postlar
Posts API: a'zo postlarini o'qish, yaratish va o'chirish.
create_post
asyncA'zo nomidan matnli post (ixtiyoriy havola bilan) Posts API'da yaratadi va {id, body} qaytaradi; id — x-restli-id sarlavhasidagi post URN'i. visibility: PUBLIC yoki CONNECTIONS.
await li.create_post(
token: str,
*,
author: str,
text: str,
visibility: str = 'PUBLIC',
article_url: Optional[str] = None,
article_title: Optional[str] = None,
) -> dictw_member_socialkerak (Share on LinkedIn mahsuloti).- Havola uchun SDK
content.articlegasourcevatitle(berilmasa URL) yozadi. LinkedIn Posts API URL'ni skanerlamaydi, shuning uchun thumbnail va tavsif avtomatik chiqmaydi. - Boshqa
visibilityqiymatiConfigurationErrorberadi. - Rasm, video va hujjat yuklash bu metodda yo'q.
Kerakli ruxsatlar:w_member_social
post = await li.create_post(token, author=li.person_urn(sub), text="Yangiliklar!",
article_url="https://siz.uz/blog")delete_post
asyncPostni URN bo'yicha (urn:li:share:... yoki urn:li:ugcPost:...) o'chiradi va {deleted: True, urn} qaytaradi. URN yo'l qismida to'liq kodlanadi.
await li.delete_post(token: str, post_urn: str) -> dict- LinkedIn qoidasi: o'chirish idempotent — avval o'chirilgan post uchun ham 204 qaytadi; ommaviy o'chirish yo'q.
w_member_socialkerak; amalni qaytarib bo'lmaydi.
Kerakli ruxsatlar:w_member_social
await li.delete_post(token, post_urn)posts
asyncMuallif postlarini Posts API'ning q=author so'rovi bilan o'qiydi va LinkedIn javobini (elements, paging) qaytaradi. start va count bilan sahifalanadi.
await li.posts(token: str, *, author: str, start: int = 0, count: int = 10) -> dict- A'zo postlari uchun
r_member_socialkerak — LinkedIn uni cheklangan ruxsat sifatida faqat tasdiqlangan foydalanuvchilarga beradi; 403 da SDK tushuntiruvchiPermissionErrorko'taradi. - LinkedIn qoidasi:
countstandart 10, maksimal 100; natijalar oxirgi o'zgartirilgan vaqt bo'yicha yangidan eskiga tartiblanadi. - Keyingi postlar bo'lsa ham sahifada
countdan kam element kelishi mumkin — keyingi sahifanipaging.linksdan aniqlang.
Kerakli ruxsatlar:r_member_social
posts = await li.posts(token, author=li.person_urn(sub), count=10)Barcha klientlarda umumiy metodlar
Har bir HTTP klient (Telegram, Facebook, Instagram, LinkedIn, TikTok, Ads) shu past darajadagi metodlarga ega: SDK'da hali o'rab olinmagan endpoint'ni chaqirish yoki sahifalab o'qish uchun. async with bloki tugaganda ulanish o'zi yopiladi.
request
asyncIstalgan HTTP so'rovni yuboradi va JSON javobni qaytaradi — SDK'da hali alohida metodi yo'q endpoint uchun. Token va imzo parametrlarini (access_token, Meta uchun appsecret_proof — socialift.crypto.appsecret_proof) o'zingiz params yoki headers ga qo'shasiz.
await li.request(
method: str,
url: str,
*,
params: Optional[Mapping[str, Any]] = None,
data: Optional[Any] = None,
json: Optional[Any] = None,
headers: Optional[Mapping[str, str]] = None,
) -> AnyparamsdagiNoneqiymatlar yuborilmaydi.- Limit (
RateLimitError) va vaqtinchalik server xatolarida (HTTP 429, 500, 502, 503, 504)RetryPolicybo'yicha qayta uriniladi;Retry-Aftersarlavhasi bo'lsa, shuncha kutiladi. Tarmoq uzilishiTransportErrorbo'lib chiqadi.
get
asyncrequest("GET", ...) ning qisqa shakli.
await li.get(url: str, **kw) -> Anypost
asyncrequest("POST", ...) ning qisqa shakli.
await li.post(url: str, **kw) -> Anydelete
asyncrequest("DELETE", ...) ning qisqa shakli.
await li.delete(url: str, **kw) -> Anypaginate
asyncMeta'ning kursorli sahifalashi (paging.next) bo'yicha yurib, barcha data elementlarini bitta ro'yxatga yig'ib qaytaradi.
await li.paginate(
url: str,
*,
params: Optional[Mapping[str, Any]] = None,
max_items: int = 500,
page_size: int = 100,
) -> list[dict]max_items(standart 500) — himoya chegarasi: yirik akkauntda ro'yxat o'n minglab yozuv bo'lishi mumkin.page_size— bitta so'rovdagilimit.
close
asyncSDK o'zi yaratgan HTTP sessiyasini yopadi (tashqaridan berilgan sessiyaga tegmaydi). async with Client(...) ishlatilsa, o'zi chaqiriladi.
await li.close() -> NoneKo'p so'raladigan savollar
LinkedIn access token qancha amal qiladi?
LinkedIn hujjatiga ko'ra hozir barcha access tokenlar 60 kunlik muddat bilan beriladi (expires_in). Programmatik refresh token faqat tasdiqlangan Marketing Developer Platform hamkorlariga beriladi va 365 kun amal qiladi; uni ishlatish refresh tokenning muddatini uzaytirmaydi. Refresh token bo'lmasa a'zo avtorizatsiyadan qayta o'tishi kerak.
Nega LinkedIn postlarini o'qishda 403 xatosi chiqadi?
posts() muallif postlarini q=author bilan o'qiydi va a'zo postlari uchun r_member_social ruxsati kerak. LinkedIn bu ruxsatni cheklangan deb belgilagan va faqat tasdiqlangan foydalanuvchilarga beradi. Ruxsat bo'lmasa SDK tushuntiruvchi matnli PermissionError ko'taradi.
LinkedIn API'dagi 426 xatosi nimani bildiradi?
/rest/* so'rovidagi LinkedIn-Version sarlavhasi endi faol bo'lmagan versiyani ko'rsatmoqda. LinkedIn har versiyani kamida bir yil qo'llaydi, keyin NONEXISTENT_VERSION kodi bilan 426 qaytaradi. SDK'da api_version yoki LINKEDIN_API_VERSION ni faol YYYYMM qiymatiga yangilang.
LinkedIn postida muallif qanday ko'rsatiladi?
Shaxsiy post muallifi urn:li:person:{sub} ko'rinishida bo'ladi, bu yerda sub — me() qaytargan Profile.id. person_urn(sub) shu satrni yasaydi; create_post va posts esa urn: bilan boshlanmagan qiymatni o'zi o'raydi.
Socialift LinkedIn xabarlari yoki Lead Gen Forms bilan ishlaydimi?
Yo'q. LinkedIn klienti faqat login, tokenlar, profil va postlarni qamraydi. Shaxsiy xabarlar va Lead Gen Forms uchun SDK'da metod yo'q.