Skip to content

Управление пользователями

Управление разметчиками в Potato: списки доступа в user_config, вход по ссылке с URL-параметром, роли и права RBAC, квоты на разметчика и обучение перед задачей.

Potato решает о каждом человеке три отдельных вопроса: может ли он зарегистрироваться, что ему разрешено делать после входа и сколько работы он получит. За каждый вопрос отвечает свой блок конфигурации, и когда их путают, обычно получается разметчик, который может войти, но так и не получает ни одного объекта.

Режимы доступа

Открытый доступ

По умолчанию Potato разрешает самостоятельную регистрацию, так что новый разметчик сам создаёт себе учётную запись на странице входа:

yaml
user_config:
  allow_all_users: true

Ограниченный доступ

Задайте allow_all_users: false и перечислите адреса, которым разрешено регистрироваться. Больше никто создать учётную запись не сможет:

yaml
user_config:
  allow_all_users: false
  users:
    - alice@example.com
    - bob@example.com
    - researcher@university.edu

Оба ключа находятся внутри user_config. Если написать их на верхнем уровне, они молча игнорируются, и список доступа выглядит настроенным, но ничего не делает.

Аутентификация

Вход по паролю

Режим по умолчанию. Разметчики регистрируются с адресом электронной почты и паролем, который Potato хранит как хеш PBKDF2 с отдельной солью для каждого пользователя.

yaml
login:
  type: password

Прямой вход по параметру URL

url_direct берёт имя пользователя прямо из параметра URL и не спрашивает пароль. Так обрабатываются участники, приходящие с краудсорсинговых платформ:

yaml
login:
  type: url_direct
  url_argument: PROLIFIC_PID

Тогда разметчики приходят по адресу http://your-server:8000/?PROLIFIC_PID=abc123 и входят как abc123.

url_argument принимает и список. В этом случае папка с результатами разметчика получает имя, склеенное из всех значений:

yaml
login:
  type: url_direct
  url_argument:
    - PROLIFIC_PID
    - STUDY_ID
    - SESSION_ID

Типов входа три: password, url_direct и prolific. Последний добавляет к входу по URL интеграцию с API Prolific. Настройка на стороне платформы описана в разделе Интеграция с краудсорсингом.

Отключение пароля или формы входа

Каждый разметчик входит под именем пользователя, потому что Potato хранит метки каждого разметчика в папке с его именем внутри output_annotation_dir. Ни одна настройка не убирает этот шаг. Две настройки убирают из него пароль, а вторая убирает и форму.

Если на верхнем уровне конфигурации указать require_password: false, форма входа спрашивает только имя пользователя. Незнакомое имя Potato сразу регистрирует, а знакомое возвращает к работе этого разметчика:

yaml
require_password: false

Поэтому любой, кто введёт существующее имя пользователя, продолжит сессию этого разметчика, и отключать пароль стоит только там, где разметчики доверяют друг другу или URL задачи закрыт от посторонних. Список пользователей в этом режиме по-прежнему действует, и при user_config.allow_all_users: false имя, которого нет в users, отклоняется. Чтобы убрать и форму, используйте вход url_direct и отправьте каждому разметчику ссылку с его именем пользователя. На странице Вход без пароля перечислены бэкенды аутентификации, которые работают без пароля.

Роли и права

Общий ключ администратора

admin_api_key задаёт один общий ключ, который передаётся в заголовке X-API-Key и обходит все проверки прав. Если он не задан, Potato создаёт ключ сам и записывает его в {task_dir}/admin_api_key.txt.

yaml
admin_api_key: "your-shared-key"

Управление доступом на основе ролей

С блоком rbac названные по имени люди попадают в админ-панель, просто войдя в систему как обычно, без общего ключа:

yaml
rbac:
  enabled: true
 
  # Custom roles, merged over the built-in ones
  roles:
    lead: [view_admin_dashboard, export_data, annotate]
 
  # Assign roles to specific users
  user_role_assignments:
    carol@example.com: admin
    dave@example.com: lead
 
  # Map an SSO claim to a role
  sso_role_mapping:
    "org:my-github-org": adjudicator

Права такие: view_admin_dashboard, manage_assignment, adjudicate, export_data и annotate. Встроенная роль admin имеет все пять, adjudicator имеет adjudicate, export_data и annotate, а annotator только annotate.

Права пользователя складываются из прав всех его ролей. Если блока rbac нет вообще, повышенный доступ дают только общий ключ и список adjudication.adjudicator_users. Благодаря этому проекты, написанные до появления RBAC, продолжают работать.

Нагрузка

Лимиты на разметчика

max_annotations_per_user задаёт одно число для всех:

yaml
max_annotations_per_user: 100

per_annotator_quota задаёт разным людям разные числа. Он принимает default, by_user и by_user_role, а любой другой вложенный ключ отклоняет при загрузке, а не игнорирует:

yaml
per_annotator_quota:
  default: 50
  by_user:
    alice@example.com: 200
  by_user_role:
    expert: 150
    novice: 40

Лимит определяется так: сначала смотрится by_user, затем by_user_role, затем default. Метки ролей берутся из user_roles:

yaml
user_roles:
  alice@example.com: expert
  bob@example.com: novice

Такая метка относится только к нагрузке. Права она даёт лишь тогда, когда заодно называет роль из rbac.roles, поэтому expert и novice остаются метками квот и ничем больше.

Разметчиков на объект

num_annotators_per_item задаёт, сколько человек увидит каждый объект, и именно от этого зависит, сможете ли вы в конце сообщить согласованность:

yaml
num_annotators_per_item: 3
min_annotators_per_instance: 2

max_annotations_per_item служит устаревшим псевдонимом того же лимита. Если задать оба с разными значениями, конфигурация будет отклонена при загрузке, а не согласована молча.

Стратегия назначения

yaml
assignment_strategy: random
random_seed: 1234

Стратегии такие: random, fixed_order, least_annotated, max_diversity, diversity_clustering, category_based, batch, priority, model_review, llm_confidence, psychometric и active_learning. По умолчанию random_seed равен 1234, поэтому фиксируйте его, когда запуск должен быть воспроизводимым. Что делает каждая стратегия, описано в разделе Назначение задач.

Допуск разметчиков

Этап обучения показывает разметчикам перед настоящей задачей тренировочные объекты с известными ответами, а passing_criteria решает, кто пойдёт дальше:

yaml
training:
  enabled: true
  data_file: data/training.json
  passing_criteria:
    min_correct: 8
    max_mistakes: 2
    max_mistakes_per_question: 1
  allow_retry: true
  failure_action: block

Формат объектов и варианты обратной связи описаны в разделе Этап обучения.

Проверка внимательности во время задачи

Обучение отсеивает людей в начале. Проверки внимательности продолжают измерять и тогда, когда настоящая работа уже идёт:

yaml
attention_checks:
  enabled: true
  items_file: data/attention_checks.json
  frequency: 10
  min_response_time: 3.0
  failure_handling:
    warn_threshold: 2
    warn_message: "Please read items carefully before answering."
    block_threshold: 5
    block_message: "You have been blocked due to too many incorrect responses."

Эталонные примеры и отчёты о согласованности описаны в разделе Контроль качества.

Сессии

yaml
secret_key: "a-long-random-string"
session_timeout_minutes: 60
persist_sessions: true
session_lifetime_days: 7

secret_key подписывает cookie сессии. Его можно задать и через переменную окружения POTATO_SECRET_KEY. Без него Potato при каждом запуске создаёт новый ключ, и каждый перезапуск разлогинивает всех.

session_timeout_minutes сбрасывает сессию, которая простаивала столько минут, и отсчёт начинается заново с каждым запросом. Potato 2.11 первым из релизов применяет этот параметр, со значением по умолчанию 480 минут. При 60, как в этом примере, разметчику, который отошёл на час, придётся по возвращении войти заново.

Пример: исследовательская группа

yaml
annotation_task_name: "Sentiment Annotation"
task_dir: .
 
user_config:
  allow_all_users: false
  users:
    - researcher1@university.edu
    - researcher2@university.edu
    - student1@university.edu
    - student2@university.edu
 
rbac:
  enabled: true
  user_role_assignments:
    researcher1@university.edu: admin
 
user_roles:
  researcher1@university.edu: expert
  student1@university.edu: novice
 
per_annotator_quota:
  default: 200
  by_user_role:
    expert: 300
    novice: 120
 
num_annotators_per_item: 2
assignment_strategy: least_annotated
 
data_files:
  - data/main.json
 
item_properties:
  id_key: id
  text_key: text
 
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the sentiment of this text?"
    labels:
      - Positive
      - Negative
      - Neutral
    sequential_key_binding: true
 
output_annotation_dir: annotation_output/

Пример: краудсорсинг

yaml
annotation_task_name: "Sentiment Annotation Study"
task_dir: .
 
login:
  type: url_direct
  url_argument: PROLIFIC_PID
 
completion_code: "POTATO2024"
 
user_config:
  allow_all_users: true
 
max_annotations_per_user: 50
num_annotators_per_item: 3
assignment_strategy: random
 
hide_navbar: true
jumping_to_id_disabled: true
 
attention_checks:
  enabled: true
  items_file: data/attention_checks.json
  frequency: 10
  failure_handling:
    warn_threshold: 2
    block_threshold: 5
 
data_files:
  - data/main.json
 
item_properties:
  id_key: id
  text_key: text
 
output_annotation_dir: annotation_output/

Дополнительные материалы

Подробности реализации см. в исходной документации и в справочнике по ролям и правам.