Metadata-Version: 2.4
Name: okcdn
Version: 4.1.0
Summary: High-performance Python client for OK.ru CDN video & media streaming engine
Author: SangoAlgo
License: MIT
Project-URL: Homepage, https://github.com/SangoAlgo/okcdn
Project-URL: Documentation, https://github.com/SangoAlgo/okcdn#readme
Project-URL: Repository, https://github.com/SangoAlgo/okcdn.git
Project-URL: Bug Tracker, https://github.com/SangoAlgo/okcdn/issues
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: AsyncIO
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: aiohttp>=3.8.0
Dynamic: requires-python

# OkCdn — High-Performance Python Client for OK.ru CDN Streaming Engine

[![PyPI Version](https://img.shields.io/pypi/v/okcdn.svg)](https://pypi.org/project/okcdn/)
[![Python Versions](https://img.shields.io/pypi/pyversions/okcdn.svg)](https://pypi.org/project/okcdn/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Asyncio](https://img.shields.io/badge/asyncio-native-brightgreen.svg)](https://docs.python.org/3/library/asyncio.html)
[![FastAPI & Docker Ready](https://img.shields.io/badge/FastAPI-Server%20Backend-teal.svg)](https://github.com/SangoAlgo/okcdn)

**`okcdn`** — это ультра-легковесный, высокопроизводительный асинхронный Python SDK для взаимодействия с сервером **OKCdn**. Позволяет мгновенно перекачивать видеопотоки (MPEG-DASH, HLS, MP4) в облачный CDN OK.ru на максимальной скорости без сохранения на диск (**Zero-Disk RAM Streaming**), обновлять протухшие ссылки менее чем за 0.5 секунды и отправлять медиафайлы.

---

## ⚡ Ключевые возможности

* 🚀 **Zero-Disk RAM Streaming**: Скачивание, склейка и отправка MPEG-DASH (`.mpd`), HLS (`.m3u8`) и Direct MP4 целиком в оперативной памяти сервера без износа SSD/диска.
* 🔄 **Мгновенное обновление ссылок (<0.5с)**: Автоматическая генерация свежих прямых CDN-ссылок (`.mp4`, `.m3u8`, `.mpd`) на ранее загруженные видео.
* 📦 **Пакетная загрузка (`send_videos`)**: Параллельная асинхронная отправка списков видео с настраиваемым лимитом одновременных потоков (`concurrency`).
* 📤 **Прямая загрузка файлов (`upload_file`)**: Загрузка локальных файлов любого размера напрямую в OK CDN.
* 🛡 **Строгая изоляция и безопасность**: Сервер не хранит жестко заданные токены. Каждый клиент передает свой `auth_token` и `chat_id`.
* ⚡ **30-минутный умный пул сессий**: Сервер кэширует авторизацию и автоматически отключает сокеты при неактивности более 30 минут, снижая нагрузку на RAM и CPU.
* 🔁 **Автоматический Retry**: Встроенные повторные попытки с экспоненциальной задержкой при временных сбоях сети.

---

## 📦 Установка

```bash
pip install --upgrade okcdn
```

---

## 🚀 Быстрый старт

```python
import asyncio
from okcdn import OkCdn

SERVER_URL = "https://okcdn-1.onrender.com"  # или ваш собственный сервер
AUTH_TOKEN = "ВАШ_OK_AUTHCODE"
CHAT_ID = -93804481741046

async def main():
    # Инициализация асинхронного клиента
    async with OkCdn(
        server_url=SERVER_URL,
        auth_token=AUTH_TOKEN,
        default_chat_id=CHAT_ID
    ) as cdn:

        # 1. Проверка доступности сервера
        health = await cdn.health()
        print("Статус сервера:", health)

        # 2. Отправка видео по ссылке (HLS / DASH / MP4)
        video = await cdn.send_video(
            link="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4",
            caption="Мой стрим",
            title="BigBuckBunny_720p.mp4"
        )
        print("✅ Видео успешно опубликовано!")
        print("📹 Video ID:  ", video["video_id"])
        print("🔗 Direct MP4:", video["mp4"])
        print("📺 HLS Stream:", video["hls"])
        print("🖼 Poster:    ", video["poster"])
        print("⏱ Duration:  ", video["duration"])

        # 3. Мгновенное обновление ссылок (<0.5с)
        fresh = await cdn.refresh_links(
            video_id=video["video_id"],
            message_id=video.get("message_id")
        )
        print("🔄 Свежая ссылка MP4:", fresh["mp4"])
        print("⌛ Истекает через:   ", fresh["expires_in_sec"], "сек")

if __name__ == "__main__":
    asyncio.run(main())
```

---

## 📖 Полное руководство по API

### 1. Инициализация клиента `OkCdn`

```python
cdn = OkCdn(
    server_url="https://api.yourdomain.com",  # Базовый URL сервера OKCdn
    auth_token="AUTHCODE_HERE",               # Токен авторизации OK.ru (AUTHCODE)
    default_chat_id=None,                     # Целевой ID чата по умолчанию
    timeout=120.0,                            # Таймаут запросов в секундах
    max_retries=3,                            # Количество попыток при сбоях
    headers=None                              # Дополнительные HTTP заголовки
)
```

> **Совет:** Клиент поддерживает контекстный менеджер `async with OkCdn(...) as cdn:`, который автоматически закрывает HTTP-соединения при выходе.

---

### 2. Отправка видео (`send_video`)

Загружает видеопоток (DASH `.mpd`, HLS `.m3u8`, прямой `.mp4`) в оперативную память сервера, переупаковывает через FFmpeg и публикует в чат OK.ru.

```python
video_data = await cdn.send_video(
    link="https://site.com/video.m3u8",
    chat_id=123456789,             # Необязательно, если задан default_chat_id
    title="movie_720p.mp4",        # Имя файла видео
    caption="Описание к ролику"     # Текст сообщения
)
```

**Формат ответа:**
```json
{
  "success": true,
  "video_id": "16539363710239",
  "message_id": "117188933073769661",
  "mp4": "https://vd252.okcdn.ru/?expires=1788247610477&...",
  "hls": "https://vd252.okcdn.ru/?expires=1788247610477&...&cmd=videoPlayer_hls",
  "dash": "https://vd252.okcdn.ru/?expires=1788247610477&...&cmd=videoPlayer_dash",
  "direct": "https://vd252.okcdn.ru/?expires=1788247610477&...",
  "poster": "https://iv.okcdn.ru/videoPreview?id=...",
  "duration": "0:10",
  "title": "movie_720p.mp4",
  "caption": "Описание к ролику",
  "metrics": {
    "download": { "download_size_mb": 15.4, "download_speed_mb_s": 25.1 },
    "upload": { "upload_speed_mbps": 40.2, "upload_time_sec": 3.1 },
    "total_time_sec": 4.8
  }
}
```

---

### 3. Мгновенное обновление ссылок (`refresh_links`)

Прямые CDN-ссылки OK.ru имеют срок жизни (обычно от 24 часов до нескольких месяцев). Метод `refresh_links` обновляет ссылки **менее чем за 0.5 секунды** без повторной загрузки видео:

```python
fresh = await cdn.refresh_links(
    video_id="16539363710239",
    message_id="117188933073769661", # Рекомендуется передавать message_id
    chat_id=123456789
)

print(fresh["mp4"])             # Свежая ссылка на MP4
print(fresh["hls"])             # Свежий HLS плейлист
print(fresh["expires_at"])      # ISO дата истечения ссылки
print(fresh["expires_in_sec"])  # Оставшееся время жизни в секундах
```

---

### 4. Пакетная параллельная отправка (`send_videos`)

Отправка списка видеофайлов с контролем числа параллельных потоков:

```python
urls = [
    "https://example.com/part1.mp4",
    "https://example.com/part2.m3u8",
    "https://example.com/part3.mpd"
]

results = await cdn.send_videos(
    links=urls,
    chat_id=123456789,
    concurrency=3  # Число параллельных загрузок
)

for url, data in results.items():
    if data.get("success"):
        print(f"✅ {url} -> {data.get('mp4')}")
    else:
        print(f"❌ {url} -> Ошибка: {data.get('error')}")
```

---

### 5. Загрузка локальных файлов (`upload_file`)

Метод автоматически запрашивает прямую ссылку загрузки в OK CDN и передает бинарные данные:

```python
uploaded = await cdn.upload_file(
    file_path="my_video.mp4",
    caption="Прямая загрузка файла",
    chat_id=123456789
)
print("Video ID:", uploaded["video_id"])
print("MP4 URL: ", uploaded["mp4"])
```

---

### 6. Отправка фото и аудио

```python
# Отправка фото
photo = await cdn.send_photo(
    photo_path="banner.jpg", # Локальный путь или URL
    caption="Превью к видео"
)

# Отправка аудио
audio = await cdn.send_audio(
    audio_path="soundtrack.mp3",
    title="Track Name",
    performer="Artist"
)
```

---

### 7. Мониторинг и статистика (`get_stats` & `health`)

```python
# Проверка здоровья сервера
status = await cdn.health()
print(status)
# {'status': 'healthy', 'version': '4.0.0', 'active_sessions': 1}

# Детальная статистика аккаунта и сессий
stats = await cdn.get_stats()
print(stats)
```

---

## 🤖 Примеры интеграции

### 1. Telegram Бот (Aiogram 3.x)

```python
import asyncio
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from okcdn import OkCdn

bot = Bot(token="TELEGRAM_BOT_TOKEN")
dp = Dispatcher()

cdn = OkCdn(
    server_url="https://okcdn-1.onrender.com",
    auth_token="OK_AUTHCODE_HERE",
    default_chat_id=-93804481741046
)

@dp.message(Command("stream"))
async def cmd_stream(message: types.Message):
    await message.answer("⏳ Скачиваю и перекачиваю видео в OK CDN...")
    
    url = message.text.split(maxsplit=1)[1]
    res = await cdn.send_video(link=url, caption=f"Запросил @{message.from_user.username}")
    
    if res.get("success"):
        await message.answer(
            f"🎬 <b>Видео готово!</b>\n\n"
            f"🔗 <b>Прямой MP4:</b> {res['mp4']}\n"
            f"📺 <b>HLS Стрим:</b> {res.get('hls')}\n"
            f"⏱ <b>Длительность:</b> {res.get('duration')}",
            parse_mode="HTML"
        )
    else:
        await message.answer(f"❌ Ошибка: {res.get('error')}")

async def main():
    try:
        await dp.start_polling(bot)
    finally:
        await cdn.close()

if __name__ == "__main__":
    asyncio.run(main())
```

---

### 2. FastAPI Прокси-Сервис / Video Resolver

```python
from fastapi import FastAPI, HTTPException
from okcdn import OkCdn, OkCdnError

app = FastAPI(title="Video Stream Resolver")
cdn = OkCdn(
    server_url="https://okcdn-1.onrender.com",
    auth_token="OK_AUTHCODE_HERE",
    default_chat_id=-93804481741046
)

@app.on_event("shutdown")
async def shutdown():
    await cdn.close()

@app.get("/api/resolve")
async def resolve_stream(video_id: str, message_id: str = None):
    try:
        data = await cdn.refresh_links(video_id=video_id, message_id=message_id)
        if not data.get("success"):
            raise HTTPException(status_code=404, detail=data.get("error"))
        return {
            "mp4": data["mp4"],
            "hls": data["hls"],
            "expires_in_sec": data["expires_in_sec"]
        }
    except OkCdnError as e:
        raise HTTPException(status_code=500, detail=str(e))
```

---

## 🛠 Обработка ошибок

Библиотека предоставляет типизированные исключения:

```python
from okcdn.exceptions import (
    OkCdnError,             # Базовое исключение библиотеки
    OkCdnAuthError,         # Ошибка авторизации (401 / неверный токен)
    OkCdnBadRequestError,   # Некорректные параметры (400 / не указан chat_id)
    OkCdnServerError,       # Внутренняя ошибка сервера (500)
    OkCdnTimeoutError       # Таймаут при скачивании или ответе
)

try:
    video = await cdn.send_video("https://site.com/video.mp4")
except OkCdnAuthError:
    print("❌ Неверный или просроченный токен OK.ru!")
except OkCdnBadRequestError as e:
    print(f"❌ Ошибка в параметрах: {e}")
except OkCdnServerError as e:
    print(f"❌ Ошибка на стороне сервера: {e}")
except OkCdnError as e:
    print(f"❌ Прочая ошибка: {e}")
```

---

## ⚙️ Переменные окружения

Вы можете инициализировать клиент без параметров в коде — `OkCdn()` автоматически подхватит переменные окружения:

| Переменная | Описание | Пример |
| :--- | :--- | :--- |
| `OKCDN_SERVER_URL` | Адрес сервера OKCdn | `https://okcdn-1.onrender.com` |
| `OKCDN_AUTH_TOKEN` / `ACCOUNT_TOKEN` | Сессионный токен OK.ru (`AUTHCODE`) | `QMYlNXVS01...` |
| `OKCDN_CHAT_ID` / `CHAT_ID` | Целевой ID диалога / чата OK.ru | `-93804481741046` |
| `OKCDN_TIMEOUT` | Таймаут запросов в секундах | `120.0` |

---

## 📄 Лицензия

Распространяется под лицензией **MIT**. Подробности в файле [LICENSE](https://github.com/SangoAlgo/okcdn/blob/main/LICENSE).
