socialkit (s-socialkit)
Общий слой домена соцсетей — то, что одинаково у Telegram, VK, Instagram, TikTok, Threads, YouTube, Rutube, Дзена, vc.ru, ok.ru, Boosty, Reddit, Pinterest и MAX. Аналог
aichatkitдля ИИ-чатов.
Зачем
Соцсети работают так же, как ИИ-чаты: навык объявляет способности видами, а оркестратор зовёт вид, а не сервис. Тогда веер («найти конкурентов во всех соцсетях») получается сам собой — спросили всех, кто объявил вид, — а новая соцсеть подключается установкой пакета, без правки ядра.
До этого единицей подключения была ВСЯ СЕТЬ: маршрут веера лежал таблицей
CROSSPOST_ROUTES, перечень сетей — закрытым NetworkId на шестнадцать
значений, а способность выяснялась двумя десятками булевых флагов уже ПОСЛЕ
загрузки адаптера.
Состав 0.0.1
| Модуль | Что даёт |
|---|---|
capabilities |
контракт видов: перечень, таблица вид→метод, правило имени точки входа <сервис>_<вид>, поля ответа, машинная проверка однородности вызова |
entities |
сущности домена: материал, комментарий, показатели, цель публикации, автор, файл, страницы выборок. Приехали из ядра bublictr |
liveness |
живость входа — ТОНКИЙ реэкспорт corekit.diagnosis.access (три исхода, правило живёт в основании) |
content_types |
кто каким ВИДОМ какие ТИПЫ материала умеет: язык объявления, чтение из метаданных (без импорта навыков), вопрос «кто умеет карусель» |
trail |
СЛЕД вызова вида: четыре ступени ВОКРУГ вызова одной строкой @traced (механизм — corekit.trail), общий идентификатор прохода, рекурсивная вычистка секретов, приёмник в локальный *.jsonl |
Типы материала
video (горизонтальное long-form) · reel (короткое вертикальное) · post ·
story · carousel · article · poll.
Порог тот же, что у видов: тип заводится, когда его умеют трое и больше
(пересчитано по тринадцати навыкам соцсетей). Поэтому здесь нет трансляции — её
умеет один Rutube; нет и «аудио» — звук приезжает вложением в пост, а это
MediaKind.
Навык объявляет соответствие вид→типы ТОЧКАМИ ВХОДА группы
socialkit.content_types, где значение — сам перечень строкой:
[project.entry-points."socialkit.content_types"]
instagram_publish = "post:image, carousel:image+video, reel:video, story:image+video"
Так перечень читается из метаданных, не импортировав ни одного навыка. После двоеточия — чем тип бывает наполнен: карусель у Instagram и альбома Telegram принимает внутрь ролик, у VK — только фотографии, и эта разница объявлена словами, а не подразумевается.
Виды
Ядро (веерится): publish · content · media · comments · feed ·
metrics · search · profile · session · export.
Второй эшелон (объявлен, волну не блокирует): engagement · schedule ·
members · messages · collection · events.
Порог объявления — повторяемость намерения (умеют трое и больше), а не похожесть
кода. Уникальное (market ВКонтакте, star revenue Телеграма, протокол MAX)
остаётся своей командой навыка: вид с одним носителем — это переименованный
сервис.
Правила контракта
- вид и метод зовутся ОДНИМ словом — помнить соответствие не приходится;
- имя сервиса живёт ТОЛЬКО в координате точки входа
<сервис>_<вид>; - вызов однороден:
ctxесть у любого вида и везде со значением по умолчанию. У чатов это разъехалось, и наивный вызов падалTypeErrorна первом же сервисе. Проверяется машиной:socialkit.uniformity_problems(навык); - сырой ответ сервиса всегда лежит в
raw; - «не знаю» говорится прямо:
None, а не ноль и не выдуманный вердикт.
Чего в ките нет и не будет
Транспорта (netkit), браузера, минта и хранилища сессий (librarykit), пула
аккаунтов (accountpoolkit), троттлинга и реестра адресов (adapterkit), веера
(это оркестратор). Кит про ЗНАНИЕ домена, а не второй фреймворк.
Установка
pip install s-socialkit
Использование
from socialkit import CAPABILITY_METHOD, CORE_KINDS, capability_id, uniformity_problems
from socialkit import ContentItem, ContentType, Visibility
# навык объявляет точку входа
capability_id("vk", "publish") # → "vk_publish"
# оркестратор зовёт вид, не зная имени сервиса
метод = getattr(навык, CAPABILITY_METHOD["publish"])
метод(ContentItem(service="vk", type=ContentType.POST, visibility=Visibility.PUBLIC))
# навык проверяет себя сам: объявленное обязано быть позываемым
assert uniformity_problems(навык) == []
Спросить по ТИПУ материала — ничего не загружая и не зная имён сетей:
from socialkit import ContentType, MediaKind, who_can
who_can(ContentType.CAROUSEL) # → ('instagram_publish', ...)
who_can(ContentType.CAROUSEL, media=MediaKind.VIDEO_FILE) # карусель с роликом внутри
who_can(ContentType.REEL, kind="content") # кто ПЕРЕЧИСЛЯЕТ вертикальные
Оставить след вызова — одной строкой, не зная про основание:
from socialkit import SESSION, set_sink, to_jsonl, traced
set_sink(to_jsonl("~/.sessions/trail.jsonl")) # локально; наружу — тот же файл
class VkSession:
service, kind = "vk", SESSION
@traced # четыре ступени вокруг вызова, а не в теле
async def session(self, ctx=None, **_):
...
Одна запись прохода (intent → access → exchange → outcome) выглядит так:
{"stage": "outcome", "trace_id": "e2f1…", "service": "vk", "kind": "session",
"verdict": "refused", "why": "вход отвергнут", "evidence": "форма входа в ответе"}
trace_id приезжает из ExecutionContext, поэтому сценарий из десяти видов в
разных сетях читается одним grep по идентификатору. Секреты в записи не
попадают никогда — ни доводом, ни вложенным заголовком.
Разработка
python -m pytest -q # 90 тестов
python -m ruff check .
CI/CD
.gitlab-ci.yml — три стадии: gates (тесты + ruff + lint-imports, на каждый
push и на тег) → release-guard (тег == версия во всех местах) → publish-pypi
(Trusted Publishing/OIDC, только после двух первых; версия, уже лежащая на
PyPI, повторно не публикуется).
Trusted Publisher для этого репозитория на pypi.org (Manage → Publishing →
GitLab, namespace S-kits, project socialkit, file .gitlab-ci.yml) ещё не
настроен владельцем — до этого шага publish-pypi ожидаемо падает на обмене
OIDC-токена (mint-token). Это не баг пайплайна, а недостающая ручная настройка
на стороне PyPI.
Metadata
Release files for s-socialkit 0.0.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| s_socialkit-0.0.10.tar.gz | 170.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| s_socialkit-0.0.10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 262.7 kB