Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
855fa05
Allow more lenient api key through configuration
PGijsbers Feb 12, 2026
5c551c7
Added RFC with some failing linting/type checks
PGijsbers Feb 11, 2026
81b4f60
make access safe even if toml doesn't have dev section
PGijsbers Feb 11, 2026
50ed235
Simplify model definition
PGijsbers Feb 12, 2026
dcc5fcd
Update name in docstring
PGijsbers Feb 12, 2026
b6db690
Rewrite errors to separate classes
PGijsbers Feb 13, 2026
5e12e74
Remove unused dictionary
PGijsbers Feb 13, 2026
4a0d5cb
Remove the ProblemType class as it was confusing and only for tests
PGijsbers Feb 13, 2026
97d5378
Provide default codes for the different errors based on PHP codes
PGijsbers Feb 13, 2026
9832365
chore: enable selective docstring linting (remove global D ignore)
Feb 27, 2026
9d865d8
Merge upstream/main with conflict resolution in datasets_test.py
Toton642 Feb 28, 2026
e7e7d63
fix: address code review comments - config handling and test assertions
Toton642 Feb 28, 2026
0fdfd4a
fix: remove duplicate line-length setting from [tool.ruff.lint]
Toton642 Feb 28, 2026
d893f56
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2026
9c283dd
fix: use AuthenticationRequiredError for missing user in tag_dataset
Toton642 Feb 28, 2026
8e5dbe5
Merge remote-tracking branch 'origin/feat/enable-docstring-linting' i…
Toton642 Feb 28, 2026
4dc3a5b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2026
8c8bba3
fix: handle race condition in study creation with alias
Toton642 Feb 28, 2026
83eb22f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2026
f55d3de
fix: handle non-JSON responses in datasets migration test
Toton642 Feb 28, 2026
1695f6f
fix: preserve original type of error code in problem+json response
Toton642 Feb 28, 2026
48ddac4
docs: add docstrings to core modules to enable docstring linting
Toton642 Feb 28, 2026
2518d9b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2026
6fcf09d
docs: add missing docstrings to database modules
Toton642 Feb 28, 2026
731c180
Merge remote-tracking branch 'origin/feat/enable-docstring-linting'
Toton642 Feb 28, 2026
880fc25
fix: resolve ruff docstring failures
Toton642 Feb 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions enable-docstring-linting.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
*** Begin Patch
*** Update File: pyproject.toml
@@
- [tool.ruff.lint]
- line-length = 100
- [tool.ruff.lint]
- # The D (doc) and DTZ (datetime zone) lint classes current heavily violated - fix later
- select = ["ALL"]
- ignore = [
- "CPY", # we do not require copyright in every file
- "D", # todo: docstring linting
- "D203",
- "D204",
- "D213",
- "DTZ", # To add
- # Linter does not detect when types are used for Pydantic
- "TC001",
- "TC003",
- ]
+ [tool.ruff.lint]
+ line-length = 100
+ # Gradually enable docstring (D) checks: remove global ignore for "D"
+ # and keep specific D-codes ignored that are still noisy.
+ select = ["ALL"]
+ ignore = [
+ "CPY", # we do not require copyright in every file
+ # D (docstrings) — removed to enable most D-rules. We continue to ignore
+ # some specific D-codes that are currently noisy:
+ "D203",
+ "D204",
+ "D213",
+ "DTZ", # to add
+ # Linter does not detect when types are used for Pydantic
+ "TC001",
+ "TC003",
+ ]
*** End Patch
10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ show_missing=true
line-length = 100

[tool.ruff.lint]
# The D (doc) and DTZ (datetime zone) lint classes current heavily violated - fix later
# Gradually enable docstring (D) checks: remove global ignore for "D"
# and keep specific D-codes ignored that are still noisy.
select = ["ALL"]
ignore = [
"CPY", # we do not require copyright in every file
"D", # todo: docstring linting
"CPY", # we do not require copyright in every file
# D (docstrings) — removed to enable most D-rules. We continue to ignore
# some specific D-codes that are currently noisy:
"D203",
"D204",
"D213",
"DTZ", # To add
"DTZ", # to add
# Linter does not detect when types are used for Pydantic
"TC001",
"TC003",
Expand Down
8 changes: 8 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""Configuration management for the OpenML REST API.

Handles loading and caching of configuration from TOML files and environment variables.
"""

import functools
import logging
import os
Expand Down Expand Up @@ -49,11 +54,13 @@ def _load_configuration(file: Path) -> TomlTable:


def load_routing_configuration(file: Path = _config_file) -> TomlTable:
"""Load routing configuration from the config file."""
return typing.cast("TomlTable", _load_configuration(file)["routing"])


@functools.cache
def load_database_configuration(file: Path = _config_file) -> TomlTable:
"""Load and cache database configuration with environment variable overrides."""
configuration = _load_configuration(file)
database_configuration = _apply_defaults_to_siblings(
configuration["databases"],
Expand All @@ -78,4 +85,5 @@ def load_database_configuration(file: Path = _config_file) -> TomlTable:


def load_configuration(file: Path = _config_file) -> TomlTable:
"""Load configuration from a TOML file."""
return tomllib.loads(file.read_text())
4 changes: 4 additions & 0 deletions src/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""Core utilities for the OpenML REST API.

Includes error handling, data conversions, access control, and formatting.
"""
5 changes: 5 additions & 0 deletions src/core/access.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""Access control utilities for the OpenML REST API.

Provides functions to check user permissions and dataset access.
"""

from sqlalchemy.engine import Row

from database.users import User, UserGroup
Expand Down
24 changes: 19 additions & 5 deletions src/core/conversions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
"""Utilities for converting between string and numeric representations.

Provides functions for recursive conversion of nested data structures.
"""

from collections.abc import Iterable, Mapping, Sequence
from typing import Any


def _str_to_num(string: str) -> int | float | str:
"""Tries to convert the string to integer, otherwise float, otherwise returns the input."""
"""Convert string to integer, float, or leave unchanged.

Attempts conversion in order: integer, float, then returns original string.
"""
if string.isdigit():
return int(string)
try:
Expand All @@ -13,8 +21,10 @@ def _str_to_num(string: str) -> int | float | str:


def nested_str_to_num(obj: Any) -> Any:
"""Recursively tries to convert all strings in the object to numbers.
For dictionaries, only the values will be converted."""
"""Recursively convert all strings in object to numbers.

For dictionaries, only the values will be converted.
"""
if isinstance(obj, str):
return _str_to_num(obj)
if isinstance(obj, Mapping):
Expand All @@ -25,8 +35,10 @@ def nested_str_to_num(obj: Any) -> Any:


def nested_num_to_str(obj: Any) -> Any:
"""Recursively tries to convert all numbers in the object to strings.
For dictionaries, only the values will be converted."""
"""Recursively convert all numbers in object to strings.

For dictionaries, only the values will be converted.
"""
if isinstance(obj, str):
return obj
if isinstance(obj, Mapping):
Expand All @@ -39,6 +51,7 @@ def nested_num_to_str(obj: Any) -> Any:


def nested_remove_nones(obj: Any) -> Any:
"""Recursively remove None values from nested data structures."""
if isinstance(obj, str):
return obj
if isinstance(obj, Mapping):
Expand All @@ -53,6 +66,7 @@ def nested_remove_nones(obj: Any) -> Any:


def nested_remove_single_element_list(obj: Any) -> Any:
"""Recursively unwrap single-element lists in nested data structures."""
if isinstance(obj, str):
return obj
if isinstance(obj, Mapping):
Expand Down
Loading