[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "alpine-bits-python-server" version = "0.1.2" description = "Alpine Bits Python Server implementation" readme = "README.md" requires-python = ">=3.13" dependencies = [ "aiosqlite>=0.21.0", "annotatedyaml>=1.0.0", "dotenv>=0.9.9", "fastapi>=0.117.1", "generateds>=2.44.3", "httpx>=0.28.1", "lxml>=6.0.1", "pydantic[email]>=2.11.9", "pytest>=8.4.2", "pytest-asyncio>=1.2.0", "redis>=6.4.0", "ruff>=0.13.1", "slowapi>=0.1.9", "sqlalchemy>=2.0.43", "uvicorn>=0.37.0", "voluptuous>=0.15.2", "xsdata-pydantic[cli,lxml,soap]>=24.5", "xsdata[cli,lxml,soap]>=25.7", ] [project.scripts] alpine-bits-server = "alpine_bits_python.main:main" [tool.hatch.build.targets.wheel] packages = ["src/alpine_bits_python"] [tool.pytest.ini_options] testpaths = ["tests"] pythonpath = ["src"] [tool.ruff] src = ["src", "tests"] [tool.ruff.lint] select = [ "A001", # Variable {name} is shadowing a Python builtin "ASYNC210", # Async functions should not call blocking HTTP methods "ASYNC220", # Async functions should not create subprocesses with blocking methods "ASYNC221", # Async functions should not run processes with blocking methods "ASYNC222", # Async functions should not wait on processes with blocking methods "ASYNC230", # Async functions should not open files with blocking methods like open "ASYNC251", # Async functions should not call time.sleep "B002", # Python does not support the unary prefix increment "B005", # Using .strip() with multi-character strings is misleading "B007", # Loop control variable {name} not used within loop body "B014", # Exception handler with duplicate exception "B015", # Pointless comparison. Did you mean to assign a value? Otherwise, prepend assert or remove it. "B017", # pytest.raises(BaseException) should be considered evil "B018", # Found useless attribute access. Either assign it to a variable or remove it. "B023", # Function definition does not bind loop variable {name} "B024", # `{name}` is an abstract base class, but it has no abstract methods or properties "B026", # Star-arg unpacking after a keyword argument is strongly discouraged "B032", # Possible unintentional type annotation (using :). Did you mean to assign (using =)? "B035", # Dictionary comprehension uses static key "B904", # Use raise from to specify exception cause "B905", # zip() without an explicit strict= parameter "BLE", "C", # complexity "COM818", # Trailing comma on bare tuple prohibited "D", # docstrings "DTZ003", # Use datetime.now(tz=) instead of datetime.utcnow() "DTZ004", # Use datetime.fromtimestamp(ts, tz=) instead of datetime.utcfromtimestamp(ts) "E", # pycodestyle "F", # pyflakes/autoflake "F541", # f-string without any placeholders "FLY", # flynt "FURB", # refurb "G", # flake8-logging-format "I", # isort "INP", # flake8-no-pep420 "ISC", # flake8-implicit-str-concat "ICN001", # import concentions; {name} should be imported as {asname} "LOG", # flake8-logging "N804", # First argument of a class method should be named cls "N805", # First argument of a method should be named self "N815", # Variable {name} in class scope should not be mixedCase "PERF", # Perflint "PGH", # pygrep-hooks "PIE", # flake8-pie "PL", # pylint "PT", # flake8-pytest-style "PTH", # flake8-pathlib "PYI", # flake8-pyi "RET", # flake8-return "RSE", # flake8-raise "RUF005", # Consider iterable unpacking instead of concatenation "RUF006", # Store a reference to the return value of asyncio.create_task "RUF007", # Prefer itertools.pairwise() over zip() when iterating over successive pairs "RUF008", # Do not use mutable default values for dataclass attributes "RUF010", # Use explicit conversion flag "RUF013", # PEP 484 prohibits implicit Optional "RUF016", # Slice in indexed access to type {value_type} uses type {index_type} instead of an integer "RUF017", # Avoid quadratic list summation "RUF018", # Avoid assignment expressions in assert statements "RUF019", # Unnecessary key check before dictionary access "RUF020", # {never_like} | T is equivalent to T "RUF021", # Parenthesize a and b expressions when chaining and and or together, to make the precedence clear "RUF022", # Sort __all__ "RUF023", # Sort __slots__ "RUF024", # Do not pass mutable objects as values to dict.fromkeys "RUF026", # default_factory is a positional-only argument to defaultdict "RUF030", # print() call in assert statement is likely unintentional "RUF032", # Decimal() called with float literal argument "RUF033", # __post_init__ method with argument defaults "RUF034", # Useless if-else condition "RUF100", # Unused `noqa` directive "RUF101", # noqa directives that use redirected rule codes "RUF200", # Failed to parse pyproject.toml: {message} "S102", # Use of exec detected "S103", # bad-file-permissions "S108", # hardcoded-temp-file "S306", # suspicious-mktemp-usage "S307", # suspicious-eval-usage "S313", # suspicious-xmlc-element-tree-usage "S314", # suspicious-xml-element-tree-usage "S315", # suspicious-xml-expat-reader-usage "S316", # suspicious-xml-expat-builder-usage "S317", # suspicious-xml-sax-usage "S318", # suspicious-xml-mini-dom-usage "S319", # suspicious-xml-pull-dom-usage "S601", # paramiko-call "S602", # subprocess-popen-with-shell-equals-true "S604", # call-with-shell-equals-true "S608", # hardcoded-sql-expression "S609", # unix-command-wildcard-injection "SIM", # flake8-simplify "SLF", # flake8-self "SLOT", # flake8-slots "T100", # Trace found: {name} used "T20", # flake8-print "TC", # flake8-type-checking "TID", # Tidy imports "TRY", # tryceratops "UP", # pyupgrade "UP031", # Use format specifiers instead of percent format "UP032", # Use f-string instead of `format` call "W", # pycodestyle ] [dependency-groups] dev = [ "pytest-cov>=7.0.0", ]