mirror of
https://github.com/Donkie/Spoolman.git
synced 2026-10-22 01:52:17 -05:00
The reader-to-Spoolman contract is one ordinary HTTP POST, which means a complete conforming reader fits in a hundred lines of stdlib and needs no NFC hardware at all. That is worth having as a tool: pairing, auto-navigate and filling the link dialog are otherwise only reachable by someone who owns an ESP32 and has already flashed it. Interactive by default, because the thing you want while clicking around the UI is to tap the same tag again, or a new one, without retyping a command. Blank input re-taps the last UID -- which is also how to watch the server's de-duplication behave, since it answers every repeat while broadcasting only the first, exactly as it does for a real reader re-reading a tag that is sitting on it. Writes nothing and deletes nothing, unlike its neighbours in this directory: a scan is an event, not a record.
134 lines
3.9 KiB
TOML
134 lines
3.9 KiB
TOML
[project]
|
|
name = "spoolman"
|
|
version = "0.26.1"
|
|
description = "A web service that keeps track of 3D printing spools."
|
|
license = "MIT"
|
|
readme = "README.md"
|
|
authors = [{ name = "Donkie", email = "daniel.cf.hultgren@gmail.com" }]
|
|
dependencies = [
|
|
"uvicorn~=0.34",
|
|
"httptools>=0.6.4; platform_machine != \"armv7l\"",
|
|
"uvloop!=0.15.0,!=0.15.1,>=0.21.0; platform_machine != \"armv7l\" and sys_platform != \"win32\" and (sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\")",
|
|
"fastapi~=0.115",
|
|
"SQLAlchemy[aiomysql,aiosqlite,asyncio,postgresql_asyncpg]~=2.0",
|
|
"pydantic~=2.10",
|
|
"platformdirs~=4.3",
|
|
"alembic~=1.15",
|
|
"scheduler~=0.8",
|
|
"sqlalchemy-cockroachdb~=2.0",
|
|
"asyncpg~=0.30",
|
|
"psycopg2-binary~=2.9",
|
|
"setuptools~=83.0",
|
|
"WebSockets~=15.0",
|
|
"prometheus-client~=0.21",
|
|
"httpx~=0.28",
|
|
"hishel~=0.1",
|
|
"aiomysql[rsa]~=0.3",
|
|
]
|
|
requires-python = ">=3.10"
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"ruff==0.14.10",
|
|
"pytest~=9.1.1",
|
|
"pytest-asyncio~=1.4.0",
|
|
"httpx~=0.28.1",
|
|
"poethepoet>=0.40.0",
|
|
]
|
|
|
|
[tool.poe.tasks.generate-docs]
|
|
script = "spoolman.docs:generate_docs"
|
|
help = "Generate API documentation for Spoolman."
|
|
|
|
[tool.poe.tasks.bump]
|
|
script = "spoolman.bump:bump"
|
|
help = "Bump Spoolman version."
|
|
|
|
[tool.poe.tasks.run]
|
|
cmd = "uvicorn spoolman.main:app"
|
|
help = "Start Spoolman."
|
|
|
|
[tool.poe.tasks.test]
|
|
cmd = "pytest tests"
|
|
help = "Runs the backend unit tests. These need no database or running server."
|
|
|
|
[tool.poe.tasks.stress-seed]
|
|
cmd = "python scripts/stress_seed.py"
|
|
help = "Fill a running dev instance with a large generated dataset. Never point it at real data."
|
|
|
|
[tool.poe.tasks.demo-seed]
|
|
cmd = "python scripts/demo_seed.py"
|
|
help = "Fill a running dev instance with the curated screenshot inventory. Never point it at real data."
|
|
|
|
[tool.poe.tasks.fake-reader]
|
|
cmd = "python scripts/fake_reader.py"
|
|
help = "Act as an NFC tag reader against a running instance, so the tag features need no hardware."
|
|
|
|
[tool.poe.tasks.itest]
|
|
cmd = "python tests_integration/run.py"
|
|
help = "Builds Spoolman and runs integration tests on the backend against all supported databases."
|
|
|
|
[tool.poe.tasks.itest-frontend]
|
|
cmd = "python tests_frontend/run.py"
|
|
help = "Builds Spoolman and runs Playwright frontend integration tests against a real deployment."
|
|
|
|
[tool.poe.tasks.itest-frontend-v2]
|
|
cmd = "python tests_frontend_v2/run.py"
|
|
help = "Builds Spoolman and runs Playwright frontend integration tests for client_v2 against a real deployment."
|
|
|
|
[tool.bumpversion]
|
|
current_version = "0.22.1"
|
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
serialize = ["{major}.{minor}.{patch}"]
|
|
allow_dirty = false
|
|
|
|
[[tool.bumpversion.files]]
|
|
filename = "pyproject.toml"
|
|
search = 'version = "{current_version}"'
|
|
replace = 'version = "{new_version}"'
|
|
|
|
[tool.pytest.ini_options]
|
|
# Only the unit tests. tests_integration needs a live server and is run via `poe itest`.
|
|
testpaths = ["tests"]
|
|
|
|
[tool.ruff]
|
|
line-length = 120
|
|
target-version = "py310"
|
|
extend-exclude = ["client_v2"]
|
|
|
|
[tool.ruff.lint]
|
|
select = ["ALL"]
|
|
ignore = [
|
|
"A003",
|
|
"COM812",
|
|
"D101",
|
|
"D104",
|
|
"D203",
|
|
"D213",
|
|
"D406",
|
|
"D407",
|
|
"DTZ003",
|
|
"EM101",
|
|
"EM102",
|
|
"FA100",
|
|
"FIX002",
|
|
"PLR0913",
|
|
"S104",
|
|
"S603",
|
|
"SIM108",
|
|
"TD002",
|
|
"TD003",
|
|
"TRY003",
|
|
"TRY201",
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"tests*/*" = ["ANN201", "ASYNC210", "S101", "PLR2004", "D103", "TID252"]
|
|
"migrations/versions/*" = ["N999"]
|
|
# Developer tooling, not shipped code: stdout is the user interface (T201), the
|
|
# generated test data is deliberately random (S311) and full of literal weights,
|
|
# diameters and counts (PLR2004), and the data generators are long by nature
|
|
# (C901/PLR0912/PLR0915). Everything else — including type annotations — is still
|
|
# enforced.
|
|
"scripts/*" = ["ANN401", "C901", "D102", "D103", "D107", "FBT003", "PLR0912", "PLR0915", "PLR2004", "S311", "T201"]
|