From 2e5115f7948bd1f0a0fa994da6c0c88a96823d1c Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 1 Apr 2025 08:52:43 +0200 Subject: [PATCH 1/4] python312Packages.docling: cleanup dependencies - remove `pyarrow` - add missing `pluggy` --- pkgs/development/python-modules/docling/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/development/python-modules/docling/default.nix b/pkgs/development/python-modules/docling/default.nix index 81e2200a4340..63d0a53f98f0 100644 --- a/pkgs/development/python-modules/docling/default.nix +++ b/pkgs/development/python-modules/docling/default.nix @@ -23,7 +23,7 @@ openpyxl, pandas, pillow, - pyarrow, + pluggy, pydantic, pydantic-settings, pylatexenc, @@ -80,7 +80,7 @@ buildPythonPackage rec { openpyxl pandas pillow - pyarrow + pluggy pydantic pydantic-settings pylatexenc From 96d9ab064ed55129d568955c5fec8a676415d6b8 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 1 Apr 2025 14:51:05 +0200 Subject: [PATCH 2/4] python312Packages.docling: disable one test --- pkgs/development/python-modules/docling/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/development/python-modules/docling/default.nix b/pkgs/development/python-modules/docling/default.nix index 63d0a53f98f0..7e60149238a0 100644 --- a/pkgs/development/python-modules/docling/default.nix +++ b/pkgs/development/python-modules/docling/default.nix @@ -177,6 +177,7 @@ buildPythonPackage rec { "tests/test_document_picture_classifier.py" "tests/test_e2e_conversion.py" "tests/test_e2e_ocr_conversion.py" + "tests/test_input_doc.py" "tests/test_interfaces.py" "tests/test_invalid_input.py" "tests/test_legacy_format_transform.py" From 426ef3f9d60bd82d952d0e7014f184df152707b0 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 1 Apr 2025 09:25:33 +0200 Subject: [PATCH 3/4] docling-serve: init at 0.7.0 --- pkgs/by-name/do/docling-serve/package.nix | 3 + .../python-modules/docling-serve/default.nix | 63 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 3 files changed, 68 insertions(+) create mode 100644 pkgs/by-name/do/docling-serve/package.nix create mode 100644 pkgs/development/python-modules/docling-serve/default.nix diff --git a/pkgs/by-name/do/docling-serve/package.nix b/pkgs/by-name/do/docling-serve/package.nix new file mode 100644 index 000000000000..79d8d642a03a --- /dev/null +++ b/pkgs/by-name/do/docling-serve/package.nix @@ -0,0 +1,3 @@ +{ python3Packages }: + +python3Packages.toPythonApplication python3Packages.docling-serve diff --git a/pkgs/development/python-modules/docling-serve/default.nix b/pkgs/development/python-modules/docling-serve/default.nix new file mode 100644 index 000000000000..3d8d487cf8ff --- /dev/null +++ b/pkgs/development/python-modules/docling-serve/default.nix @@ -0,0 +1,63 @@ +{ + lib, + buildPythonPackage, + fetchFromGitHub, + hatchling, + setuptools-scm, + # python dependencies + docling, + fastapi, + httpx, + pydantic-settings, + python-multipart, + uvicorn, + websockets, +}: + +buildPythonPackage rec { + pname = "docling-serve"; + version = "0.7.0"; + pyproject = true; + + src = fetchFromGitHub { + owner = "docling-project"; + repo = "docling-serve"; + tag = "v${version}"; + hash = "sha256-QasHVoJITOuys4hASwC43eIy5854G12Yvu7Zncr9ia8="; + }; + + build-system = [ + hatchling + setuptools-scm + ]; + + pythonRelaxDeps = [ + "websockets" + ]; + + dependencies = [ + docling + fastapi + httpx + pydantic-settings + python-multipart + uvicorn + websockets + ]; + + pythonImportsCheck = [ + "docling_serve" + ]; + + # Require network + doCheck = false; + + meta = { + changelog = "https://github.com/docling-project/docling-serve/blob/${src.tag}/CHANGELOG.md"; + description = "Running Docling as an API service"; + homepage = "https://github.com/docling-project/docling-serve"; + license = lib.licenses.mit; + mainProgram = "docling-serve"; + maintainers = with lib.maintainers; [ drupol ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index c30bcb888305..3b56c7d123f6 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -4005,6 +4005,8 @@ self: super: with self; { loguru-cpp = pkgs.loguru; }; + docling-serve = callPackage ../development/python-modules/docling-serve { }; + docloud = callPackage ../development/python-modules/docloud { }; docopt = callPackage ../development/python-modules/docopt { }; From 25264d105d4a34a8807141cc8587871b12dfe32b Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 1 Apr 2025 09:26:12 +0200 Subject: [PATCH 4/4] nixos/docling-serve: init --- .../manual/release-notes/rl-2505.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/services/misc/docling-serve.nix | 115 ++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/docling-serve.nix | 28 +++++ pkgs/by-name/do/docling-serve/package.nix | 9 +- 6 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 nixos/modules/services/misc/docling-serve.nix create mode 100644 nixos/tests/docling-serve.nix diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index a98c55885f5f..1950f41ef455 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -192,6 +192,8 @@ - [Orthanc](https://orthanc.uclouvain.be/) a lightweight, RESTful DICOM server for healthcare and medical research. Available as [services.orthanc](#opt-services.orthanc.enable). +- [Docling Serve](https://github.com/docling-project/docling-serve) running [Docling](https://github.com/docling-project/docling) as an API service. Available as [services.docling-serve](#opt-services.docling-serve.enable). + - [Pareto Security](https://paretosecurity.com/) is an alternative to corporate compliance solutions for companies that care about security but know it doesn't have to be invasive. Available as [services.paretosecurity](#opt-services.paretosecurity.enable) - [ipfs-cluster](https://ipfscluster.io/), Pinset orchestration for IPFS. Available as [services.ipfs-cluster](#opt-services.ipfs-cluster.enable) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 998c935fb8d7..5fb875c16ab4 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -790,6 +790,7 @@ ./services/misc/dictd.nix ./services/misc/disnix.nix ./services/misc/docker-registry.nix + ./services/misc/docling-serve.nix ./services/misc/domoticz.nix ./services/misc/duckdns.nix ./services/misc/duckling.nix diff --git a/nixos/modules/services/misc/docling-serve.nix b/nixos/modules/services/misc/docling-serve.nix new file mode 100644 index 000000000000..e717c1fe5e80 --- /dev/null +++ b/nixos/modules/services/misc/docling-serve.nix @@ -0,0 +1,115 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (lib) types; + + cfg = config.services.docling-serve; +in +{ + options = { + services.docling-serve = { + enable = lib.mkEnableOption "Docling Serve server"; + package = lib.mkPackageOption pkgs "docling-serve" { }; + + host = lib.mkOption { + type = types.str; + default = "127.0.0.1"; + example = "0.0.0.0"; + description = '' + The host address which the Docling Serve server HTTP interface listens to. + ''; + }; + + port = lib.mkOption { + type = types.port; + default = 5001; + example = 11111; + description = '' + Which port the Docling Serve server listens to. + ''; + }; + + environment = lib.mkOption { + type = types.attrsOf types.str; + default = { + DOCLING_SERVE_ENABLE_UI = "True"; + }; + example = '' + { + DOCLING_SERVE_ENABLE_UI = "False"; + } + ''; + description = '' + Extra environment variables for Docling Serve. + For more details see + ''; + }; + + environmentFile = lib.mkOption { + description = '' + Environment file to be passed to the systemd service. + Useful for passing secrets to the service to prevent them from being + world-readable in the Nix store. + ''; + type = lib.types.nullOr lib.types.path; + default = null; + example = "/var/lib/secrets/doclingServeSecrets"; + }; + + openFirewall = lib.mkOption { + type = types.bool; + default = false; + description = '' + Whether to open the firewall for Docling Serve. + This adds `services.Docling Serve.port` to `networking.firewall.allowedTCPPorts`. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.docling-serve = { + description = "Running Docling as an API service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + environment = cfg.environment; + + serviceConfig = { + ExecStart = "${lib.getExe cfg.package} run --host \"${cfg.host}\" --port ${toString cfg.port}"; + EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile; + PrivateTmp = true; + DynamicUser = true; + DevicePolicy = "closed"; + LockPersonality = true; + PrivateUsers = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + UMask = "0077"; + CapabilityBoundingSet = ""; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + ProtectClock = true; + ProtectProc = "invisible"; + }; + }; + + networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + }; + + meta.maintainers = with lib.maintainers; [ drupol ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index d1fe552bbc1f..f6857b54fc83 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -367,6 +367,7 @@ in docker-tools-nix-shell = runTest ./docker-tools-nix-shell.nix; docker-tools-cross = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./docker-tools-cross.nix { }; docker-tools-overlay = handleTestOn [ "x86_64-linux" ] ./docker-tools-overlay.nix { }; + docling-serve = runTest ./docling-serve.nix; documize = handleTest ./documize.nix { }; documentation = pkgs.callPackage ../modules/misc/documentation/test.nix { inherit nixosLib; }; doh-proxy-rust = handleTest ./doh-proxy-rust.nix { }; diff --git a/nixos/tests/docling-serve.nix b/nixos/tests/docling-serve.nix new file mode 100644 index 000000000000..ff31e003283b --- /dev/null +++ b/nixos/tests/docling-serve.nix @@ -0,0 +1,28 @@ +{ lib, ... }: +let + mainPort = "5001"; +in +{ + name = "docling-serve"; + meta = with lib.maintainers; { + maintainers = [ drupol ]; + }; + + nodes = { + machine = + { ... }: + { + services.docling-serve = { + enable = true; + }; + }; + }; + + testScript = '' + machine.start() + + machine.wait_for_unit("docling-serve.service") + machine.wait_for_open_port(${mainPort}) + machine.succeed("curl http://127.0.0.1:${mainPort}") + ''; +} diff --git a/pkgs/by-name/do/docling-serve/package.nix b/pkgs/by-name/do/docling-serve/package.nix index 79d8d642a03a..df0fb39a4724 100644 --- a/pkgs/by-name/do/docling-serve/package.nix +++ b/pkgs/by-name/do/docling-serve/package.nix @@ -1,3 +1,8 @@ -{ python3Packages }: +{ python3Packages, nixosTests }: -python3Packages.toPythonApplication python3Packages.docling-serve +(python3Packages.toPythonApplication python3Packages.docling-serve) +// { + passthru.tests = { + docling-serve = nixosTests.docling-serve; + }; +}