Metadata-Version: 2.4
Name: socialift
Version: 1.2.1
Summary: Instagram, Facebook, LinkedIn, TikTok va Telegram uchun asinxron Python SDK — OAuth, kontent, chat, reklama targeting, Lead Ads va webhook'lar
Author: Fayoz Turaqulov
License: Socialift — tijorat litsenziyasi
        Copyright (c) 2026 Fayoz Turaqulov. Barcha huquqlar himoyalangan.
        
        1. RUXSAT
           Amaldagi obuna kaliti (`SOCIALIFT_LICENSE_KEY`) egasiga quyidagilar
           ruxsat etiladi:
           a) dasturiy ta'minotni o'z mahsuloti yoki ichki tizimlarida ishlatish;
           b) obuna rejasida ko'rsatilgan seat (muhit) sonidan oshmasdan o'rnatish;
           c) o'z ehtiyoji uchun kodni o'rganish va lokal o'zgartirish kiritish.
        
        2. TAQIQLAR
           Quyidagilar yozma ruxsatsiz taqiqlanadi:
           a) dasturiy ta'minotni yoki uning hosilasini qayta tarqatish, sotish,
              ijaraga berish, sublitsenziyalash;
           b) litsenziya tekshiruvini chetlab o'tish, o'chirish yoki buzish;
           c) obuna kalitini uchinchi shaxsga berish yoki oshkor qilish;
           d) dasturiy ta'minot asosida raqobatdosh mahsulot yaratish.
        
        3. OBUNA
           Ruxsat obuna amal qilgan davrda kuchda. Obuna tugagach yoki bekor
           qilingach 1-banddagi ruxsatlar to'xtaydi.
        
        4. KAFOLATLAR YO'QLIGI
           Dasturiy ta'minot "BOR HOLICHA" taqdim etiladi, hech qanday oshkora
           yoki nazarda tutilgan kafolatsiz. Mualliflar hech qanday zarar uchun
           javobgar emas.
        
        5. UCHINCHI TOMON XIZMATLARI
           Meta (Facebook, Instagram) va LinkedIn API'laridan foydalanish ularning
           o'z shartlariga bo'ysunadi. Ushbu litsenziya ularni qamrab olmaydi.
        
        Savollar: hello@socialift.uz
        
Project-URL: Homepage, https://github.com/1fayoz/socialift
Project-URL: Documentation, https://github.com/1fayoz/socialift/tree/main/docs
Project-URL: Repository, https://github.com/1fayoz/socialift
Project-URL: Issues, https://github.com/1fayoz/socialift/issues
Keywords: instagram,facebook,linkedin,tiktok,telegram,meta,graph-api,marketing-api,ads,targeting,telethon,bot-api,lead-ads,webhook,crm,async,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp>=3.9
Requires-Dist: cryptography>=42
Provides-Extra: server
Requires-Dist: aiofiles; extra == "server"
Requires-Dist: aiosmtplib; extra == "server"
Requires-Dist: alembic>=1.13; extra == "server"
Requires-Dist: argon2-cffi; extra == "server"
Requires-Dist: asyncpg; extra == "server"
Requires-Dist: bleach; extra == "server"
Requires-Dist: boto3; extra == "server"
Requires-Dist: certifi; extra == "server"
Requires-Dist: cryptography; extra == "server"
Requires-Dist: fastapi[standard]>=0.115; extra == "server"
Requires-Dist: fastapi-filter[sqlalchemy]; extra == "server"
Requires-Dist: fastapi-pagination; extra == "server"
Requires-Dist: gunicorn; extra == "server"
Requires-Dist: pydantic>=2; extra == "server"
Requires-Dist: pydantic-settings>=2; extra == "server"
Requires-Dist: pyjwt; extra == "server"
Requires-Dist: python-dotenv; extra == "server"
Requires-Dist: redis; extra == "server"
Requires-Dist: sqlalchemy[asyncio]>=2; extra == "server"
Requires-Dist: telethon>=1.36; extra == "server"
Requires-Dist: werkzeug; extra == "server"
Provides-Extra: telegram
Requires-Dist: telethon>=1.36; extra == "telegram"
Provides-Extra: crypto
Requires-Dist: cryptography; extra == "crypto"
Provides-Extra: all
Requires-Dist: telethon>=1.36; extra == "all"
Requires-Dist: cryptography>=42; extra == "all"
Dynamic: license-file

# Socialift

**Instagram, Facebook, LinkedIn, TikTok va Telegram uchun asinxron Python
SDK** — OAuth, kontent, chat, reklama targeting, Lead Ads va webhook'lar.
Bitta kutubxona, besh platforma, bitta xato modeli.

[![PyPI](https://img.shields.io/pypi/v/socialift)](https://pypi.org/project/socialift/)
[![Python](https://img.shields.io/pypi/pyversions/socialift)](https://pypi.org/project/socialift/)
[![License](https://img.shields.io/badge/license-Commercial-blue)](LICENSE)

```bash
pip install socialift
```

```python
import asyncio
from socialift import Facebook

async def main():
    async with Facebook(app_id="...", app_secret="...", config_id="...") as fb:
        token = await fb.exchange_code(code, redirect_uri="https://siz.uz/cb")

        for page in await fb.pages(token.access_token):
            print(page.name, "→ instagram:", page.instagram_username)

asyncio.run(main())
```

---

## Nega Socialift

Meta va LinkedIn API'lari bilan ishlash — hujjatlarda yozilmagan o'nlab
tafsilotni bilishni talab qiladi. Socialift ularni sizdan yashiradi:

| Muammo | Socialift'da |
|---|---|
| Business tipidagi app `scope` emas, `config_id` ishlatadi | `login_url(config_id=...)` — avtomatik |
| Instagram'ning ikki oqimi turli host va token talab qiladi | `Instagram(...)` va `Instagram.via_facebook(...)` |
| Page webhook obunasi app sozlamasidan alohida | `subscribe_page()` |
| Lead webhook'da lead mazmuni kelmaydi | `fb.lead(leadgen_id, token)` |
| Forma savollari o'zbekcha/ruscha nomlanadi | `normalize()` — kanonik kalitlar |
| Rate limit, 5xx, tarmoq uzilishi | avtomatik backoff + jitter |
| Har provayder xatoni o'zicha qaytaradi | bitta `ApiError` ierarxiyasi |
| LinkedIn `/rest/*` versiya sarlavhasini talab qiladi | avtomatik |
| Chat'da suhbatdosh haqida faqat `id` keladi | to'liq profil, parallel + keshli |

| TikTok xatoni HTTP 200 ichida qaytaradi | avtomatik aniqlanadi |
| Telegram guruh a'zolarini bot ko'rmaydi | akkaunt ulanadi — to'liq ro'yxat |
| Meta `targeting` obyekti chuqur va hujjatsiz | `Ads.build_targeting()` |

---

## Imkoniyatlar

| | Facebook | Instagram | LinkedIn | TikTok | Telegram |
|---|:---:|:---:|:---:|:---:|:---:|
| OAuth / ulanish | ✅ | ✅ | ✅ | ✅ | ✅¹ |
| Profil | ✅ | ✅ | ✅ | ✅ | ✅ |
| Page'lar va page token'lari | ✅ | — | — | — | — |
| Postlar (o'qish / e'lon / o'chirish) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Izohlar (javob, yashirish, o'chirish) | ✅ | ✅ | — | ✅² | — |
| Statistika va demografika | ✅ | ✅ | — | ✅² | ✅³ |
| Chat / xabarlar | — | ✅ | — | — | ✅ |
| Guruh va kanal boshqaruvi | — | — | — | — | ✅ |
| Reklama: kampaniya, ad set, kreativ | ✅ | ✅ | — | — | — |
| Reklama targeting (qidiruv, qamrov, auditoriya) | ✅ | ✅ | — | — | — |
| Lead Ads (formalar, lead'lar) | ✅ | ✅ | — | — | — |
| Webhook (imzo, hodisalar, dedupe) | ✅ | ✅ | — | ✅ | ✅ |

¹ Telegram'da ikki xil ulanish bor: **akkaunt** (telefon + kod, MTProto) va
**bot** (BotFather token'i, Bot API). Ikkalasi ham to'liq qo'llab-quvvatlanadi.
² TikTok'da izohlar va kunlik metrikalar faqat Business Account API'da.
³ Kanal statistikasi 500+ obunachidan boshlab (Telegram cheklovi).

---


---

## TikTok

```python
from socialift import TikTok

async with TikTok(client_key="...", client_secret="...") as tt:
    token = await tt.exchange_code(code, redirect_uri="https://siz.uz/cb")

    me = await tt.me(token.access_token)
    videos = await tt.iter_videos(token.access_token, max_items=50)

    # E'lon qilishdan OLDIN majburiy: ijodkorga nima ruxsat etilgan
    info = await tt.creator_info(token.access_token)

    await tt.publish_video(
        token.access_token,
        video_url="https://cdn.siz.uz/reel.mp4",   # domen tasdiqlangan bo'lsin
        title="Salom TikTok!",
        privacy_level=info["privacy_level_options"][0],
        wait=True,                                 # yakunlanguncha kutadi
    )
```

Domen tasdiqlanmagan bo'lsa faylni to'g'ridan-to'g'ri yuboring —
u bo'laklarga bo'lib yuklanadi:

```python
await tt.publish_video(token.access_token, video=open("reel.mp4", "rb").read())
```

---

## Telegram

Ikki xil ulanish bor va ular butunlay boshqacha ishlaydi.

**Bot** — BotFather token'i, oddiy HTTPS:

```python
from socialift import Telegram

async with Telegram(token="123456:AA...") as tg:
    await tg.send_message("@mening_kanalim", "Salom!")
    await tg.delete_message(chat_id, message_id)
    await tg.ban_member(chat_id, user_id)

    # O'ralmagan metod ham ishlaydi — nom to'g'ridan-to'g'ri uzatiladi
    await tg.set_chat_menu_button(chat_id=chat_id, menu_button={"type": "commands"})
```

**Akkaunt** — telefon + kod (MTProto). Bot ko'ra olmaydigan hamma narsa
shu yerda: tarix, a'zolar ro'yxati, guruh yaratish:

```bash
pip install "socialift[telegram]"
```

```python
from socialift import TelegramAccount

async with TelegramAccount(api_id=..., api_hash="...") as tg:
    sent = await tg.send_code("+998901234567")
    result = await tg.sign_in("+998901234567", code="12345",
                              phone_code_hash=sent["phone_code_hash"])
    session = result["session"]        # SHUNI shifrlab saqlang

async with TelegramAccount(api_id=..., api_hash="...", session=session) as tg:
    await tg.send_message("@mening_guruhim", "Salom!")
    await tg.delete_messages("@mening_guruhim", [123, 124])

    for user in await tg.participants("@mening_guruhim"):
        print(user.id, user.username)

    await tg.promote("@mening_guruhim", "@ali", title="Moderator")
    await tg.mute_member("@mening_guruhim", "@spamchi")
```

O'ralmagan imkoniyat uchun `raw()` — Telethon'ning istalgan TL so'rovi.

---

## Reklama va targeting (Meta Marketing API)

```python
from socialift import Ads

async with Ads(app_secret="...") as ads:
    account = (await ads.ad_accounts(token))[0]

    # 1) auditoriyani topish
    interests = await ads.search_interests(token, "fitness")
    cities = await ads.search_locations(token, "Tashkent")

    # 2) spetsifikatsiyani yig'ish
    targeting = Ads.build_targeting(
        countries=["UZ"],
        cities=[{"key": cities[0]["key"], "radius": 25, "distance_unit": "kilometer"}],
        age_min=25, age_max=45, genders=["female"],
        interests=[interests[0]["id"]],
        platforms=["facebook", "instagram"],
    )

    # 3) qamrovni PUL SARFLAMASDAN baholash
    estimate = await ads.delivery_estimate(
        token, ad_account_id=account.id, targeting=targeting
    )

    # 4) kampaniya -> ad set -> reklama (hammasi PAUSED)
    campaign = await ads.create_campaign(
        token, ad_account_id=account.id,
        name="Yozgi aksiya", objective="OUTCOME_TRAFFIC",
    )
    await ads.create_adset(
        token, ad_account_id=account.id, campaign_id=campaign["id"],
        name="UZ / 25-45 / ayollar", targeting=targeting,
        daily_budget_major=50_000,
    )
```

Mavjud Instagram postini ko'tarish uchun bitta chaqiruv yetadi:
`ads.boost_post(...)`.

Natijani kesimlar bo'yicha ko'rish (targetingni tuzatishning asosiy manbai):

```python
rows = await ads.insights_rows(
    token, campaign_id, level="adset", breakdowns=["age", "gender"]
)
```

## Litsenziya va narxlar

Socialift — **tijorat mahsuloti**. Ishlatish uchun amaldagi obuna kaliti
kerak:

```bash
export SOCIALIFT_LICENSE_KEY="slk_..."
```

```python
# yoki kodda
from socialift import Facebook
fb = Facebook(app_id="...", app_secret="...", license_key="slk_...")
```

| Reja | Imkoniyatlar | Seat |
|---|---|---|
| **Trial** (14 kun, bepul) | Profil, postlar, izohlar, webhook | 1 |
| **Starter** | + kontent e'lon qilish | 1 |
| **Pro** | + Instagram Direct, Telegram, statistika, reklama | 3 |
| **Enterprise** | + Lead Ads, CRM quvuri, prioritet qo'llab-quvvatlash | cheksiz |

Kalit olish: **https://socialift.uz/pricing**

Rejaga kirmagan imkoniyatni chaqirsangiz so'rov **Meta'ga yuborilishidan
oldin** to'xtatiladi:

```python
from socialift import FeatureNotInPlan

try:
    await fb.leads(form_id, page_token)
except FeatureNotInPlan as exc:
    print(exc)   # `lead_ads` imkoniyati `starter` rejasiga kirmaydi...
```

<details>
<summary><b>Litsenziya qanday ishlaydi (texnik tafsilot)</b></summary>

Kalit — Ed25519 bilan imzolangan JSON. Ikki bosqichda tekshiriladi:

1. **Offline** — imzo paketga joylangan ochiq kalit bilan tekshiriladi.
   Kalit mazmunini (reja, muddat, seat) o'zgartirish imzoni buzadi.
2. **Online** — SDK har 12 soatda `api.socialift.uz/api/v1/license/activate`
   ga murojaat qilib qisqa muddatli lease oladi. Bu obunani bekor qilish va
   seat nazoratini ta'minlaydi.

Litsenziya serveri javob bermasa **7 kunlik offline grace** ishlaydi —
tarmoq uzilishi prod'ingizni to'xtatmaydi.

Havosiz muhit (CI, izolyatsiyalangan tarmoq) uchun:

```bash
export SOCIALIFT_LICENSE_OFFLINE=1   # faqat imzo tekshiriladi
```

Aktivatsiya javobida litsenziya bilan birga **imzolangan qoidalar to'plami**
ham keladi: Graph API maydon kombinatsiyalari va lead moslashtirish
jadvali. Bu ma'lumot paketda yo'q — u serverda turadi va uzluksiz
to'ldirilib boriladi, ya'ni SDK'ni yangilamasdan ham yangi qoidalarni
olasiz.

**Ochiq aytamiz:** SDK mashina kodiga kompilyatsiya qilingan, lekin mijoz
mashinasida ishlaydigan hech qanday kodni butunlay yashirib bo'lmaydi.
Shuning uchun eng qimmatli ma'lumot umuman yuborilmaydi. Texnik tafsilot:
[docs/PACKAGING.md](docs/PACKAGING.md). Litsenziya shartlari
[LICENSE](LICENSE) faylida.

</details>

---

## Misollar

### Instagram Direct — to'liq suhbatdosh profili

`/me/conversations` javobida ishtirokchi haqida atigi `id` va `username`
keladi. SDK har bir suhbatdosh uchun User Profile API'ga **parallel** so'rov
yuboradi (`asyncio.gather`, 8 tadan) va natijani 6 soatga keshlaydi:

```python
from socialift import Instagram

ig = Instagram.via_facebook(app_secret=FB_APP_SECRET)
chats = await ig.conversations(page_token, page_id="1111", ig_user_id="2222")

for chat in chats["data"]:
    c = chat["contact"]
    print(c["name"], c["follower_count"], "bizni kuzatadi:", c["is_user_follow_business"])
```

### Lead Ads — webhook'dan CRM'gacha

```python
from socialift import Facebook, verify_request, parse_events

# 1. Imzoni tekshirish (XOM baytlar!)
if not verify_request(APP_SECRET, raw_body, request.headers):
    return 403

# 2. Hodisalarni ajratish
for event in parse_events(payload):
    if event.field != "leadgen":
        continue
    if await already_processed(event.key):     # takroriy yetkazish
        continue

    # 3. Meta lead MAZMUNINI yubormaydi — Graph API'dan o'qiymiz
    async with Facebook(app_id=APP_ID, app_secret=APP_SECRET) as fb:
        lead = await fb.lead(event.leadgen_id, page_token)

    print(lead.fields)          # {'full_name': ..., 'phone': '+998901234567'}
    print(lead.campaign_name)   # qaysi reklamadan kelgan
```

### Xatolarni ishlash

```python
from socialift import AuthError, PermissionError, RateLimitError

try:
    await ig.send_message(recipient_id, token, "Salom!")
except RateLimitError as exc:
    await asyncio.sleep(exc.retry_after or 60)
except PermissionError:
    ...   # 24 soatlik javob oynasi tugagan
except AuthError:
    ...   # token bekor qilingan → qayta login
```

---

## To'liq server

Tayyor backend kerak bo'lsa — webhook qabul qilish, PostgreSQL'ga yozish,
lead'larni CRM'ga imzolangan webhook bilan uzatish, Django admin:

```bash
pip install "socialift[server]"

socialift init      # .env namunasi + kalitlar generatsiyasi
socialift check     # sozlamalar to'g'rimi
socialift migrate   # alembic upgrade head
socialift serve     # http://localhost:8000/docs
```

62 endpoint · PostgreSQL + Redis talab qilinadi ·
[docs/BACKEND_SETUP.md](docs/BACKEND_SETUP.md)

---

## Hujjatlar

| Hujjat | Kimga |
|---|---|
| [docs/SDK.md](docs/SDK.md) | SDK API ma'lumotnomasi |
| [SECURITY.md](SECURITY.md) | Xavfsizlik modeli, token saqlash, zaiflik xabari |
| [docs/BACKEND_SETUP.md](docs/BACKEND_SETUP.md) | Meta / LinkedIn / CRM sozlash |
| [docs/FRONTEND.md](docs/FRONTEND.md) | Server API'si frontend uchun |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Arxitektura va qatlamlar |
| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | Server, nginx, CI/CD |
| [docs/PACKAGING.md](docs/PACKAGING.md) | Paket qanday yig'iladi, kod himoyasi, reliz |

---

## Xavfsizlik — qisqacha

- **Token'lar SDK'da saqlanmaydi.** Har chaqiruvga argument sifatida
  uzatiladi — bitta klient bilan ko'p foydalanuvchi nomidan parallel
  ishlash xavfsiz.
- **`appsecret_proof`** har Graph so'rovga avtomatik qo'shiladi: o'g'irlangan
  token boshqa muhitdan ishlamaydi.
- **Page token `repr()` da ko'rinmaydi** — log'ga tasodifan tushmaydi.
- **Webhook imzosi** `hmac.compare_digest` bilan — timing attack'dan himoya.
- **Server:** rate limiting, `TrustedHostMiddleware`, xavfsizlik sarlavhalari,
  prod'da yopiq `/docs`, bazadagi token'lar Fernet bilan shifrlangan.

Batafsil va zaiflik xabar berish: [SECURITY.md](SECURITY.md).

---

## Paket qanday tarqatiladi

`socialift` **kompilyatsiyalangan wheel** sifatida chiqadi: SDK modullari
Cython bilan mashina kodiga (`.so` / `.pyd`) aylantirilgan, `.py` manbasi
paketda yo'q. IDE avtoto'ldirish va `mypy` uchun `.pyi` tip stublari
qo'shilgan, ya'ni ishlab chiqish tajribasi o'zgarmaydi.

Graph API maydon to'plamlari va lead moslashtirish jadvali paketda emas —
ular litsenziya bilan birga serverdan **imzolangan holda** keladi va
uzluksiz yangilanib turadi (SDK'ni yangilash shart emas). Paket bo'lmasa
SDK minimal baseline bilan ishlashda davom etadi — qulflanib qolmaydi.

**Mijozingizning lead ma'lumoti bizning serverga hech qachon ketmaydi.**
Normalizatsiya sizning mashinangizda bajariladi; bizdan faqat qoidalar
keladi.

Qo'llab-quvvatlanadigan muhitlar: CPython 3.11–3.14 · Linux
(x86_64/aarch64, glibc va musl) · macOS (arm64/x86_64) · Windows AMD64.

Batafsil: [docs/PACKAGING.md](docs/PACKAGING.md).

---

## Platformalarning real cheklovlari

Bularni SDK yashira olmaydi:

- **Instagram xabar matni** faqat oxirgi 20 kun uchun keladi.
- **Javob oynasi** — mijozning oxirgi xabaridan 24 soat.
- **Suhbatdosh profili** faqat u biznesga yozgan bo'lsa ochiladi.
- **Demografika** obunachilar 100 tadan kam bo'lsa berilmaydi.
- **Development rejimidagi Meta app** haqiqiy foydalanuvchilardan webhook
  olmaydi — App Review kerak.
- **Page webhook obunasi** app sozlamasidan alohida: `subscribe_page()`.
- **TikTok access token 24 soat** yashaydi (refresh — 365 kun), ya'ni
  yangilash kunlik ish. Refresh token har yangilashda almashadi.
- **TikTok App Review'siz** faqat `SELF_ONLY` maxfiylikda post qila oladi.
- **TikTok `PULL_FROM_URL`** uchun domen dashboard'da tasdiqlangan bo'lishi
  shart; tasdiqlanmagan bo'lsa faylni yuklang.
- **TikTok izohlari** Open API'da umuman yo'q — faqat Business Account API.
- **Telegram bot** guruh a'zolarining to'liq ro'yxatini ololmaydi (faqat
  adminlarni) va tarixni ko'rmaydi. Ikkalasi uchun akkaunt ulanadi.
- **Telegram bot** 48 soatdan eski begona xabarni o'chira olmaydi.
- **Telegram akkaunt** cheklovlari: tez-tez yuborilgan xabar `FloodWait`
  beradi, agressiv xatti-harakat akkauntni bloklaydi.
- **Telegram webhook tanani imzolamaydi** — himoya faqat `secret_token`.
- **Reklama uchun `ads_management`** App Review va Business Verification
  talab qiladi; o'tguncha faqat app'da roli bor odamlar ishlata oladi.
- **Meta qamrov bahosini aniq bermaydi** — faqat oraliq (maxfiylik uchun).

---

## Talablar

**Python 3.11 – 3.14** · `aiohttp` · `cryptography` — boshqa bog'liqlik yo'q.

Telegram **akkaunti** (MTProto) uchun qo'shimcha: `pip install
"socialift[telegram]"` (telethon). Bot API uchun kerak emas.

Paket oldindan qurilgan wheel sifatida tarqatiladi (sdist yo'q). Tayyor
wheel mavjud platformalar:

| | glibc | musl | boshqa |
|---|---|---|---|
| **Linux** | `x86_64`, `aarch64` | `x86_64`, `aarch64` | — |
| **macOS** | — | — | `arm64` (11+), `x86_64` (10.13+) |
| **Windows** | — | — | `AMD64` |

PyPy va 32-bitli platformalar qo'llab-quvvatlanmaydi. Nega faqat wheel —
[docs/PACKAGING.md](docs/PACKAGING.md).

## Qo'llab-quvvatlash

- Hujjatlar: https://github.com/1fayoz/socialift/tree/main/docs
- Savol va xatolar: https://github.com/1fayoz/socialift/issues
- Tijorat: hello@socialift.uz

## Litsenziya

Tijorat litsenziyasi — [LICENSE](LICENSE). Obuna:
https://socialift.uz/pricing
