The official SDK for building Gambit Platform Adapters
Project description
Gambit Platform Integration SDK
Gambit SDK — это официальный инструментарий для разработки Адаптеров Платформ для системы автоматизации Gambit. Этот SDK предоставляет все необходимые контракты, схемы данных и утилиты, чтобы вы могли интегрировать любую образовательную платформу с ядром Gambit.
Философия
SDK спроектирован по принципу "Адаптер как Плагин". Это означает, что вы, как разработчик, фокусируетесь исключительно на бизнес-логике взаимодействия с конкретной платформой (реверс-инжиниринг её API, парсинг данных). Всю сложную инфраструктурную работу (взаимодействие с RabbitMQ, управление состоянием, логирование) берет на себя хост-система Gambit (AdapterRunner), которая будет запускать ваш код.
Ваша задача — реализовать простой и понятный интерфейс (BaseAdapter), который работает как "драйвер" для целевой платформы.
Установка
Для начала работы установите пакет с помощью pip:
pip install gambit-sdk
Быстрый старт
Вот минимальный пример рабочего адаптера. Ваша задача — унаследовать класс BaseAdapter и реализовать его абстрактные методы.
# my_platform_adapter.py
from datetime import datetime
from httpx import AsyncClient
from gambit_sdk import (
BaseAdapter,
ExerciseType,
UnifiedAssignmentPreview,
UnifiedAssignmentDetails,
UnifiedExercise,
UnifiedGrade,
UnifiedSolution,
ChoiceStructure,
StringAnswer,
)
class MyPlatformAdapter(BaseAdapter):
"""
Адаптер для вымышленной платформы "MyPlatform".
"""
def __init__(self, session: AsyncClient) -> None:
# SDK передает уже сконфигурированный HTTP-клиент
super().__init__(session)
self.base_url = "https://api.my-platform.com"
async def login(self, username: str, password: str) -> None:
"""Логинимся на платформе и сохраняем токен/cookie в сессию."""
response = await self.session.post(
f"{self.base_url}/auth/login",
json={"username": username, "password": password}
)
response.raise_for_status()
# httpx автоматически сохранит cookie из ответа в self.session
async def get_assignment_previews(self) -> list[UnifiedAssignmentPreview]:
"""Получаем легкий список заданий."""
response = await self.session.get(f"{self.base_url}/homeworks")
response.raise_for_status()
previews = []
for hw_data in response.json()["data"]:
preview = UnifiedAssignmentPreview(
platform_assignment_id=str(hw_data["id"]),
title=hw_data["title"],
assigned_date=datetime.fromisoformat(hw_data["assigned_to_day"]),
deadline=datetime.fromisoformat(hw_data["deadline_at"]),
context_data={"details_url": hw_data["_links"]["details"]}
)
previews.append(preview)
return previews
async def get_assignment_details(self, preview: UnifiedAssignmentPreview) -> UnifiedAssignmentDetails:
"""Получаем полную информацию о задании по его превью."""
details_url = preview.context_data["details_url"]
response = await self.session.get(details_url)
response.raise_for_status()
details_data = response.json()["data"]
exercises = [
UnifiedExercise(
platform_exercise_id=str(ex["id"]),
type=ExerciseType.INPUT_STRING, # Здесь должна быть логика маппинга
question=ex["question_text"],
max_score=float(ex["points"]),
structure=None # Для простых типов структура не нужна
) for ex in details_data["exercises"]
]
return UnifiedAssignmentDetails(
platform_assignment_id=preview.platform_assignment_id,
title=preview.title,
assigned_date=preview.assigned_date,
deadline=preview.deadline,
description=details_data.get("description"),
exercises=exercises
)
async def submit_solution(self, details: UnifiedAssignmentDetails, solution: UnifiedSolution) -> UnifiedGrade | None:
"""Отправляем решение и, если возможно, сразу получаем оценку."""
# 1. Конвертируем UnifiedSolution в формат, понятный платформе
platform_payload = {
"assignment_id": details.platform_assignment_id,
"answers": [
{"question_id": ans.platform_exercise_id, "value": ans.answer.value}
for ans in solution.answers if isinstance(ans.answer, StringAnswer)
]
}
# 2. Отправляем запрос
response = await self.session.post(
f"{self.base_url}/homeworks/{details.platform_assignment_id}/submit",
json=platform_payload
)
response.raise_for_status()
# 3. Если платформа сразу возвращает оценку, парсим и возвращаем ее
grade_data = response.json().get("grade")
if grade_data:
return UnifiedGrade(
platform_assignment_id=details.platform_assignment_id,
score=float(grade_data["score"]),
max_score=float(grade_data["max_score"]),
is_passed=grade_data["is_passed"]
)
return None
async def get_grade(self, details: UnifiedAssignmentDetails) -> UnifiedGrade | None:
"""Отдельно запрашиваем оценку для ранее сданного задания."""
response = await self.session.get(f"{self.base_url}/homeworks/{details.platform_assignment_id}/grade")
if response.status_code == 404:
return None # Оценка еще не выставлена
response.raise_for_status()
grade_data = response.json()["data"]
return UnifiedGrade(
platform_assignment_id=details.platform_assignment_id,
score=float(grade_data["score"]),
max_score=float(grade_data["max_score"]),
is_passed=grade_data["is_passed"]
)
Воркфлоу взаимодействия
Хост-система AdapterRunner будет взаимодействовать с вашим адаптером в следующем порядке:
login(username, password): Вызывается один раз для аутентификации и настройки сессии.get_assignment_previews(): Вызывается периодически для получения списка доступных заданий. Этот метод должен быть максимально быстрым и легким.get_assignment_details(preview): Вызывается для каждого нового задания из списка, полученного на шаге 2. Здесь можно делать более "тяжелые" запросы для получения полной информации.submit_solution(details, solution): Вызывается, когда ядро Gambit сгенерировало решение. Ваша задача — правильно отформатировать и отправить его на платформу.get_grade(details): Вызывается после отправки решения для получения итоговой оценки, еслиsubmit_solutionне вернул ее сразу.
Справочник по API
BaseAdapter
Абстрактный класс, определяющий контракт для всех адаптеров.
__init__(self, session: AsyncClient): Конструктор. Принимает готовыйhttpx.AsyncClient.login(self, username, password): Абстрактный метод для аутентификации.get_assignment_previews(self): Абстрактный метод. Должен вернутьlist[UnifiedAssignmentPreview].get_assignment_details(self, preview): Абстрактный метод. ПринимаетUnifiedAssignmentPreviewи должен вернутьUnifiedAssignmentDetails.submit_solution(self, details, solution): Абстрактный метод. ПринимаетUnifiedAssignmentDetailsиUnifiedSolution, может вернутьUnifiedGrade.get_grade(self, details): Абстрактный метод. ПринимаетUnifiedAssignmentDetails, должен вернутьUnifiedGrade.
AssignmentType (Enum)
Перечисление всех унифицированных типов упражнений.
CHOICE_SINGLE: Выбор одного варианта.CHOICE_MULTIPLE: Выбор нескольких вариантов.INPUT_STRING: Ввод короткой строки.INPUT_TEXT: Ввод длинного текста.TEXT_FILE: Загрузка файла с текстовым содержимым.MATCHING_PAIRS: Сопоставление пар.SEQUENCE_ORDERING: Установление последовательности.UNSUPPORTED: Неподдерживаемый тип.
Схемы данных
Все схемы данных являются Pydantic-моделями и обеспечивают строгую типизацию.
UnifiedAssignmentPreview: Легковесное представление задания. Ключевое поле —context_data, "черный ящик" для передачи данных междуget_previewsиget_details.UnifiedAssignmentDetails: Полное представление задания со списком упражнений (exercises: list[UnifiedExercise]).UnifiedExercise: Одно упражнение. Ключевое поле —structure, строго типизированная модель (ChoiceStructure,MatchingStructureи т.д.), описывающая варианты ответов или элементы для сопоставления.UnifiedSolution: Полное решение, состоящее из спискаUnifiedSolutionExercise.UnifiedSolutionExercise: Ответ на одно упражнение. Ключевое поле —answer, строго типизированная модель (ChoiceAnswer,StringAnswerи т.д.).UnifiedGrade: Итоговая оценка. Содержитscore,max_score,is_passedи опциональноcorrect_answers.
Содействие
На данный момент проект находится в стадии активной разработки. Если вы заинтересованы в создании адаптера для новой платформы или нашли ошибку в SDK, пожалуйста, создайте Issue в нашем репозитории.
Лицензия
Использование данного SDK регулируется проприетарной лицензией. Пожалуйста, ознакомьтесь с полным текстом в файле LICENSE перед использованием. Ключевое ограничение: SDK может быть использован исключительно для создания адаптеров для платформы Gambit.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gambit_sdk-0.3.1.tar.gz.
File metadata
- Download URL: gambit_sdk-0.3.1.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.13.5 Darwin/25.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9aecd4e9222027a38a74e9d388d3204308a73b5158a9d984eba27293d7c677d
|
|
| MD5 |
399f44b8e290c82526c079ec3d65f279
|
|
| BLAKE2b-256 |
d2b1dd7d8da3c90c166ea3c9381697fe4074b252443de7e92366eb802fcbbc9f
|
File details
Details for the file gambit_sdk-0.3.1-py3-none-any.whl.
File metadata
- Download URL: gambit_sdk-0.3.1-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.13.5 Darwin/25.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be6b10ef2913406332ac5c4ccdc7e50de20b73ad150e589cc95b5c71c872cb57
|
|
| MD5 |
b7ea2b0a2765ca8a0bf400ba2f4a446f
|
|
| BLAKE2b-256 |
65db7f56d834aca0bb0e999204090748bb06df884aa41f24148c5531ba9f44f4
|