Compare commits

..
Author SHA1 Message Date
dependabot[bot] 8ec596bc8a Chore(deps): Bump nltk in the data-nlp-search group
Bumps the data-nlp-search group with 1 update: [nltk](https://github.com/nltk/nltk).


Updates `nltk` from 3.10.0 to 3.10.3
- [Release notes](https://github.com/nltk/nltk/releases)
- [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog)
- [Commits](https://github.com/nltk/nltk/compare/v3.10.0...v3.10.3)

---
updated-dependencies:
- dependency-name: nltk
  dependency-version: 3.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: data-nlp-search
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-01 20:20:03 +00:00
7 changed files with 10 additions and 150 deletions
+3 -3
View File
@@ -50,18 +50,18 @@ repos:
- 'prettier-plugin-organize-imports@4.3.0'
# Python hooks
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.16.4
rev: v0.16.1
hooks:
- id: ruff-check
- id: ruff-format
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "v2.28.1"
rev: "v2.26.0"
hooks:
- id: pyproject-fmt
additional_dependencies: [tomli]
# Dockerfile hooks
- repo: https://github.com/AleksaC/hadolint-py
rev: v2.15.1
rev: v2.14.0
hooks:
- id: hadolint
# Shell script hooks
-6
View File
@@ -2088,12 +2088,6 @@ password. All of these options come from their similarly-named [Django settings]
Defaults to "always".
#### [`PAPERLESS_REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS=<bool>`](#PAPERLESS_REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS) {#PAPERLESS_REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS}
: If set to false, Paperless blocks remote OCR endpoint URLs that resolve to non-public addresses (e.g., localhost, etc).
Defaults to True.
## AI {#ai}
#### [`PAPERLESS_AI_ENABLED=<bool>`](#PAPERLESS_AI_ENABLED) {#PAPERLESS_AI_ENABLED}
@@ -1063,79 +1063,3 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase):
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("non-public address", str(response.data).lower())
@override_settings(REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS=False)
def test_update_remote_ocr_endpoint_blocks_internal_endpoint_when_disallowed(
self,
) -> None:
"""
GIVEN:
- Internal remote OCR endpoints are disallowed
WHEN:
- The config is updated with a remote OCR endpoint resolving internally
THEN:
- The request is rejected
"""
response = self.client.patch(
f"{self.ENDPOINT}1/",
json.dumps(
{
"remote_ocr_endpoint": "http://127.0.0.1:5000",
},
),
content_type="application/json",
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("non-public address", str(response.data).lower())
@override_settings(REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS=True)
def test_update_remote_ocr_endpoint_allows_internal_endpoint_by_default(
self,
) -> None:
"""
GIVEN:
- Internal remote OCR endpoints are allowed (the default)
WHEN:
- The config is updated with a remote OCR endpoint resolving internally
THEN:
- The request is accepted, preserving existing self-hosted deployments
"""
response = self.client.patch(
f"{self.ENDPOINT}1/",
json.dumps(
{
"remote_ocr_endpoint": "http://127.0.0.1:5000",
},
),
content_type="application/json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(
response.data["remote_ocr_endpoint"],
"http://127.0.0.1:5000",
)
@override_settings(REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS=False)
def test_update_remote_ocr_endpoint_empty_value_skips_validation(
self,
) -> None:
"""
GIVEN:
- Internal remote OCR endpoints are disallowed
WHEN:
- The config is updated with an empty remote OCR endpoint
THEN:
- The request is accepted; clearing the field never needs
outbound URL validation
"""
response = self.client.patch(
f"{self.ENDPOINT}1/",
json.dumps(
{
"remote_ocr_endpoint": "",
},
),
content_type="application/json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["remote_ocr_endpoint"], "")
-38
View File
@@ -32,8 +32,6 @@ if TYPE_CHECKING:
import datetime
from types import TracebackType
from azure.core.pipeline import PipelineRequest
from paperless.parsers import MetadataEntry
from paperless.parsers import ParserContext
@@ -438,45 +436,9 @@ class RemoteDocumentParser:
from azure.ai.documentintelligence.models import DocumentContentFormat
from azure.core.credentials import AzureKeyCredential
from paperless.network import validate_outbound_http_url
allow_internal = settings.REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS
try:
validate_outbound_http_url(config.endpoint, allow_internal=allow_internal)
except ValueError as e:
raise ParseError(f"Invalid remote OCR endpoint: {e}") from e
def _revalidate_request_host(request: PipelineRequest) -> None:
"""Re-validates the destination host of every request sent.
The check above only covers the moment the client is built. A
single analysis involves several requests spread over the
polling loop below, and any one of them can be redirected.
Wiring this through ``raw_request_hook`` (Azure's built-in
CustomHookPolicy) rather than a custom policy means it runs
*after* RedirectPolicy in the pipeline, so it sees - and
re-checks - every actual outbound URL, including redirect
targets, not just the original request.
"""
validate_outbound_http_url(
request.http_request.url,
allow_internal=allow_internal,
)
client = DocumentIntelligenceClient(
endpoint=config.endpoint,
credential=AzureKeyCredential(config.api_key),
raw_request_hook=_revalidate_request_host,
# AzureKeyCredential is sent as Ocp-Apim-Subscription-Key, which
# Azure's default SensitiveHeaderCleanupPolicy does not strip on
# a cross-domain redirect (only Authorization and
# x-ms-authorization-auxiliary are, by default).
blocked_redirect_headers=[
"Authorization",
"x-ms-authorization-auxiliary",
"Ocp-Apim-Subscription-Key",
],
)
try:
-16
View File
@@ -305,22 +305,6 @@ class ApplicationConfigurationSerializer(
validate_llm_embedding_endpoint = validate_llm_endpoint
def validate_remote_ocr_endpoint(self, value: str | None) -> str | None:
if not value:
return value
try:
validate_outbound_http_url(
value,
allow_internal=settings.REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS,
)
except ValueError as e:
raise serializers.ValidationError(
f"Invalid remote OCR endpoint: {e.args[0]}, see logs for details",
) from e
return value
class Meta:
model = ApplicationConfiguration
fields = "__all__"
-4
View File
@@ -1208,10 +1208,6 @@ REMOTE_OCR_MODE = get_choice_from_env(
{"always", "workflow_only"},
default="always",
)
REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS = get_bool_from_env(
"PAPERLESS_REMOTE_OCR_ALLOW_INTERNAL_ENDPOINTS",
"true",
)
################################################################################
# AI Settings #
Generated
+7 -7
View File
@@ -4,11 +4,11 @@ requires-python = ">=3.11"
resolution-markers = [
"python_full_version >= '3.15' and sys_platform == 'darwin'",
"python_full_version >= '3.15' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version >= '3.12' and python_full_version < '3.15' and sys_platform == 'darwin'",
"python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'linux')",
"python_full_version < '3.12' and sys_platform == 'darwin'",
"python_full_version < '3.12' and sys_platform == 'linux'",
@@ -2718,7 +2718,7 @@ wheels = [
[[package]]
name = "nltk"
version = "3.10.0"
version = "3.10.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
@@ -2727,9 +2727,9 @@ dependencies = [
{ name = "regex" },
{ name = "tqdm" },
]
sdist = { url = "https://files.pythonhosted.org/packages/96/02/df4f105b28a7c16b0e41423bc09cf0f1b8a305df4ef0b10ca74a2e4c648c/nltk-3.10.0.tar.gz", hash = "sha256:4fbac1d98203cbcd1b5d94a2877fb822300072d80604a5e7fae49d2c5f84e8c1", size = 3089244, upload-time = "2026-07-08T02:39:13.562Z" }
sdist = { url = "https://files.pythonhosted.org/packages/e0/e6/fe51d2bb1a3b446f59c5c8165999a9fee208bc346af90a7cbf7657bc0d75/nltk-3.10.3.tar.gz", hash = "sha256:bb9327a461c3811c2fa4900e03840401f2126adfb30c0072827c433bd2444ea4", size = 5137152, upload-time = "2026-08-12T23:46:37.258Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6e/89/a0b0f35e2820d6a99d75ea1c11977ee6d5c9e6658eceb45b0c7620881faa/nltk-3.10.0-py3-none-any.whl", hash = "sha256:54ff84d4916d3ef127e8953bee0023f6a6b320b75d634a19e06ef056d3d244bf", size = 1716144, upload-time = "2026-07-08T02:39:09.753Z" },
{ url = "https://files.pythonhosted.org/packages/b6/6d/ebd2af4640b12168fdf0cb74b6118df2f32a2f62ec7e0c06fbfd80706639/nltk-3.10.3-py3-none-any.whl", hash = "sha256:ff9598a8e20518ee0d557745890cc4435b9578489e2dcbc69c4f81fa060caf7c", size = 1798643, upload-time = "2026-08-12T23:44:13.478Z" },
]
[[package]]
@@ -5014,10 +5014,10 @@ version = "2.13.0+cpu"
source = { registry = "https://download.pytorch.org/whl/cpu" }
resolution-markers = [
"python_full_version >= '3.15' and sys_platform == 'linux'",
"python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
"python_full_version == '3.14.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
"(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (python_full_version == '3.13.*' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'linux')",
"python_full_version < '3.12' and sys_platform == 'linux'",
]