Skip to content

Repository files navigation

Annotator

POC de ferramenta de anotação e treino estilo Roboflow para detecção de objetos com YOLO11. Backend FastAPI + auth (fastapi-users + SQLite), painel admin e frontend Vue 3 SPA.


Stack

  • Backend: FastAPI (Python 3.12) + uvicorn
  • ML: Ultralytics YOLO11 / YOLO26 (PyTorch CUDA 12.8)
  • Auth: fastapi-users 13+ (cookie JWT annauth, 7 dias)
  • DB: SQLite via SQLAlchemy async + aiosqlite
  • Pacotes Python: uv (lockfile em uv.lock)
  • Frontend: Vue 3 + Vite + Vue Router + Pinia + Tailwind (JavaScript)

Como rodar

1. Instalar dependências

# uv (gerencia Python e libs)
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env

# Dependências Python
uv sync

# Dependências do frontend
cd frontend && npm install && cd ..

2. Configurar .env

cat > .env <<EOF
AUTH_SECRET=$(openssl rand -hex 32)
COOKIE_SECURE=false
IMAGES_DIR=motores
CLASSES=objeto
EXPECTED_BOXES_PER_IMAGE=1
DEFAULT_CONF=0.30
DEFAULT_EPOCHS=100
IMG_SIZE=640
VAL_SPLIT=0.2
EOF

3. Criar o primeiro admin

uv run python seed_admin.py admin@local.dev senha123

4. Build do frontend e subir o backend

cd frontend && npm run build && cd ..
uv run python app.py
# ou: uv run uvicorn app:app --reload --port 8888

Abra http://localhost:8888/.

Dev com hot reload

# Terminal 1: backend (API e auth)
uv run python app.py

# Terminal 2: Vite (UI em :5173 com proxy para :8888)
cd frontend && npm run dev

Organização do repositório

Annotator/
├── app.py                  # FastAPI: API, middleware auth, SPA mount em /
├── config.py               # Lê .env
├── db.py                   # SQLAlchemy async + tabelas User / AppClass + seed
├── users.py                # fastapi-users (cookie JWT, hooks de signup/reset)
├── schemas.py              # UserRead / UserCreate / UserUpdate
├── trainer.py              # Pipeline YOLO (treino, predição, export, merge)
├── seed_admin.py           # Cria o primeiro superuser
│
├── frontend/               # Vue 3 SPA
│   ├── package.json, vite.config.js, tailwind.config.js
│   ├── index.html
│   ├── dist/               #   (gerado por `npm run build`, gitignored)
│   └── src/
│       ├── main.js, App.vue, router.js, api.js, style.css
│       ├── stores/         #   auth.js, theme.js (Pinia)
│       ├── composables/    #   useToast.js
│       ├── components/     #   Brand, ThemeToggle, Modal, ToastHost
│       ├── pages/          #   Login, Signup, Forgot, Reset, Admin, Annotator
│       └── annotator/      #   componentes do anotador
│           ├── ImageList.vue, Toolbar.vue
│           ├── Canvas.vue          # desenhar/mover/resize de bboxes
│           ├── AnnotationList.vue
│           ├── TrainingPanel.vue   # polling de /api/train/status
│           ├── ShortcutsPanel.vue
│           └── modals/             # Settings / Export / Results / Models / Merge
│
├── motores/                # IMAGES_DIR padrão (gitignored)
├── dataset/                # dataset YOLO gerado (gitignored)
├── runs/                   # saídas de treino (gitignored)
├── exports/                # modelos campeões exportados (gitignored)
├── annotations.json        # estado das anotações (gitignored)
├── app.db                  # SQLite — usuários + classes (gitignored)
├── pyproject.toml, uv.lock
└── README.md

Variáveis de ambiente

Variável Padrão Descrição
AUTH_SECRET CHANGE-ME-IN-ENV Segredo HS256 do JWT do cookie. Troque em produção. Rotacionar invalida todas as sessões.
COOKIE_SECURE false Em produção (HTTPS) defina true.
DATA_DIR raiz do projeto Onde o app.db é criado. Útil em hosts com volume montado (ex.: /data no HF Space).
IMAGES_DIR motores Pasta com imagens a anotar.
CLASSES objeto Classes iniciais — só lidas no primeiro boot para semear a tabela app_classes. Depois a fonte da verdade é o DB (gerencie em /admin).
EXPECTED_BOXES_PER_IMAGE 1 Referência visual no anotador.
DEFAULT_CONF 0.30 Confiança padrão da predição.
DEFAULT_EPOCHS 100 Épocas padrão do treino.
IMG_SIZE 640 Tamanho da imagem no treino.
VAL_SPLIT 0.2 Split de validação.

Autenticação

  • Cookie: annauth (HttpOnly, SameSite=Lax, JWT HS256, validade 7 dias).
  • Login: POST /auth/login (form username+password). Logout: POST /auth/logout.
  • Cadastro: POST /auth/register. Reset: /auth/forgot-password + /auth/reset-password. Em modo POC o token de reset é impresso no log do servidor (veja users.py).
  • Middleware auth_gate em app.py: APIs (/api/*, /users/*, /images/*, /runs/*) exigem cookie válido (401 se não tiver). Qualquer outro caminho serve o index.html da SPA — o cliente chama /api/me e redireciona para /login se necessário.

Papéis

Papel Pode
Usuário ativo Anotar, salvar, navegar, ver runs, exportar labels, treinar (/api/train), rodar predição.
Superuser Acima + /admin, CRUD de usuários e classes, rotas destrutivas (/api/reset, /api/models/runs, /api/merge, /api/models/export).

Endpoints

Auth (fastapi-users)

  • POST /auth/login, POST /auth/logout, POST /auth/register
  • POST /auth/forgot-password, POST /auth/reset-password
  • POST /auth/request-verify-token, POST /auth/verify

Usuários (fastapi-users)

  • GET /users/me, PATCH /users/me
  • GET /users/{id}, PATCH /users/{id}, DELETE /users/{id} (superuser)

Admin custom

  • GET /api/admin/users
  • GET /api/admin/classes, POST /api/admin/classes, DELETE /api/admin/classes/{id}, POST /api/admin/classes/reorder

App

  • GET /api/config — classes + defaults
  • GET /api/settings — leitura do .env + classes (read-only via UI)
  • GET /api/me — sessão atual
  • GET /api/images, GET /images/{filename}
  • GET /api/annotations, POST /api/annotations
  • POST /api/train, GET /api/train/status, GET /api/train/results
  • POST /api/predict
  • GET /api/exports, GET /api/models
  • POST /api/export (labels YOLO)
  • POST /api/models/export (admin), POST /api/merge (admin)
  • POST /api/reset (admin), DELETE /api/models/runs (admin)
  • GET /runs/{path} — gráficos/artefatos de treino

Modelo de dados (SQLite — app.db)

user(id UUID, email, hashed_password, is_active, is_superuser, is_verified)
app_classes(id, name UNIQUE, position)

Tabelas criadas no startup via lifespancreate_db_and_tables(). CLASSES do .env semeia app_classes apenas no primeiro boot.


Tema visual ("Instrument")

  • Tipografia: IBM Plex Sans (UI) + IBM Plex Mono (dados, badges, atalhos).
  • Accent: âmbar (#d97706 light / #f59e0b dark).
  • Background com malha sutil de grade 32px, borders hairline.
  • Toggle dark/light persistido em localStorage.theme. Antes do paint, um script no <head> aplica data-theme no <html> para evitar flash.

Comandos úteis

# Criar outro admin
uv run python seed_admin.py outro@local.dev senha

# Resetar tudo (apaga usuários e classes)
rm app.db && uv run python seed_admin.py admin@local.dev senha123

# Backend com auto-reload
uv run uvicorn app:app --host 0.0.0.0 --port 8888 --reload

# Build do frontend
cd frontend && npm run build

# Dev do frontend (hot reload)
cd frontend && npm run dev

# Limpar artefatos do Vite
rm -rf frontend/dist frontend/node_modules

Notas de POC / produção

  • COOKIE_SECURE=false por padrão para funcionar em http://localhost. Em produção sirva via HTTPS e troque para true.
  • POST /auth/register está aberto (padrão do fastapi-users). Para travar, remova o get_register_router em app.py e crie usuários só via /admin.
  • AUTH_SECRET: rotacionar invalida todas as sessões existentes.
  • Em modo POC, links de reset de senha são impressos no log do servidor (veja users.py). Para produção, plugue fastapi-mail + Resend/Mailtrap.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages