mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 14:15:52 +00:00
Merge pull request #2761 from arc53/chore/bump-backend-deps-2026-09
chore(deps): bring the backend dependencies up to date
This commit is contained in:
19 files changed
+1495
-1376
No files matched your search
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Lint with Ruff
|
||||
uses: chartboost/ruff-action@v1
|
||||
with:
|
||||
version: 0.14.10
|
||||
version: 0.16.7
|
||||
|
||||
requirements-in-sync:
|
||||
# application/requirements*.txt are exported from uv.lock; fail when a
|
||||
|
||||
+8
-1
@@ -1,6 +1,13 @@
|
||||
# Allow lines to be as long as 120 characters.
|
||||
line-length = 120
|
||||
|
||||
[lint]
|
||||
# Ruff's historical default rule set, stated explicitly: 0.16 widened the
|
||||
# implicit default (pyupgrade and friends), which silently turns a linter
|
||||
# upgrade into thousands of findings across the tree. Adding rules is a
|
||||
# deliberate change, not a side effect of bumping the pin.
|
||||
select = ["E4", "E7", "E9", "F"]
|
||||
|
||||
[lint.per-file-ignores]
|
||||
# Integration tests use sys.path.insert() before imports for standalone execution
|
||||
"tests/integration/*.py" = ["E402"]
|
||||
"tests/integration/*.py" = ["E402"]
|
||||
@@ -23,15 +23,23 @@ DEFAULT_MAX_TOKENS = 4096
|
||||
# OpenAI-only key (``frequency_penalty``, ``response_format``,
|
||||
# ``reasoning_effort``, ...) from 400-ing an Anthropic request.
|
||||
_PASSTHROUGH_PARAMS = (
|
||||
"temperature",
|
||||
"top_p",
|
||||
"top_k",
|
||||
"stop_sequences",
|
||||
"tool_choice",
|
||||
"thinking",
|
||||
"metadata",
|
||||
)
|
||||
|
||||
# Sampling params the Messages API still honours on the models that accept
|
||||
# them, but which anthropic 1.x removed from ``messages.create``'s signature
|
||||
# (passing one is a TypeError). They go through ``extra_body``, which the SDK
|
||||
# merges into the request JSON as-is, so the wire request is unchanged and a
|
||||
# model that rejects them 400s exactly as it does today.
|
||||
_SAMPLING_PARAMS = (
|
||||
"temperature",
|
||||
"top_p",
|
||||
"top_k",
|
||||
)
|
||||
|
||||
# ``tool_choice`` values in OpenAI's vocabulary mapped to Anthropic's. OpenAI
|
||||
# sends a bare string; Anthropic requires an object and 400s on the string.
|
||||
# ``any``/``auto``/``none`` are also accepted spelled Anthropic-style, for a
|
||||
@@ -448,7 +456,8 @@ class AnthropicLLM(BaseLLM):
|
||||
messages: Internal conversation history.
|
||||
tools: OpenAI-shaped tool definitions, or ``None``.
|
||||
kwargs: Caller kwargs; the params in ``_PASSTHROUGH_PARAMS`` are
|
||||
forwarded verbatim, and the OpenAI aliases ``max_tokens`` /
|
||||
forwarded verbatim, those in ``_SAMPLING_PARAMS`` through
|
||||
``extra_body``, and the OpenAI aliases ``max_tokens`` /
|
||||
``max_completion_tokens``, ``stop`` and ``tool_choice`` are
|
||||
translated. Everything else is dropped.
|
||||
|
||||
@@ -483,6 +492,12 @@ class AnthropicLLM(BaseLLM):
|
||||
if kwargs.get(key) is not None:
|
||||
params[key] = kwargs[key]
|
||||
|
||||
sampling = {
|
||||
key: kwargs[key] for key in _SAMPLING_PARAMS if kwargs.get(key) is not None
|
||||
}
|
||||
if sampling:
|
||||
params["extra_body"] = {**(params.get("extra_body") or {}), **sampling}
|
||||
|
||||
# OpenAI's ``stop`` is Anthropic's ``stop_sequences``. A caller that
|
||||
# already speaks Anthropic wins.
|
||||
if "stop_sequences" not in params:
|
||||
|
||||
+20
-10
@@ -3,6 +3,7 @@ from abc import ABC, abstractmethod
|
||||
from typing import ClassVar, Dict, Optional, Tuple
|
||||
|
||||
import httpx
|
||||
import httpx2
|
||||
import openai
|
||||
|
||||
from docsgpt.cache import gen_cache, stream_cache
|
||||
@@ -20,17 +21,26 @@ logger = logging.getLogger(__name__)
|
||||
# Excludes API-level errors (4xx / 5xx status) which are not transport
|
||||
# retries — RateLimitError needs backoff, BadRequestError won't get any
|
||||
# better on retry, and the existing fallback handles both.
|
||||
_STREAM_RETRYABLE_TRANSPORT_ERRORS = (
|
||||
httpx.RemoteProtocolError,
|
||||
httpx.ReadError,
|
||||
httpx.ReadTimeout,
|
||||
httpx.WriteError,
|
||||
httpx.WriteTimeout,
|
||||
httpx.ConnectError,
|
||||
httpx.ConnectTimeout,
|
||||
httpx.PoolTimeout,
|
||||
openai.APIConnectionError,
|
||||
# Both HTTP stacks are listed because the providers are split across them and
|
||||
# the two libraries' exception classes are unrelated types: openai, anthropic
|
||||
# and the MCP client run on httpx2, while google-genai, elevenlabs,
|
||||
# qdrant-client and daytona are still on httpx. Naming only one silently stops
|
||||
# matching for half the providers — the retry just never fires.
|
||||
_TRANSPORT_ERROR_NAMES = (
|
||||
"RemoteProtocolError",
|
||||
"ReadError",
|
||||
"ReadTimeout",
|
||||
"WriteError",
|
||||
"WriteTimeout",
|
||||
"ConnectError",
|
||||
"ConnectTimeout",
|
||||
"PoolTimeout",
|
||||
)
|
||||
_STREAM_RETRYABLE_TRANSPORT_ERRORS = tuple(
|
||||
getattr(module, name)
|
||||
for module in (httpx2, httpx)
|
||||
for name in _TRANSPORT_ERROR_NAMES
|
||||
) + (openai.APIConnectionError,)
|
||||
|
||||
|
||||
def optional_int(value) -> Optional[int]:
|
||||
|
||||
@@ -9,11 +9,11 @@ of 2.3 GB, with equivalent output on clean office files, CSV and text-layer
|
||||
PDFs.
|
||||
|
||||
anydoc never OCRs. It *detects* a scanned or image-only PDF and raises
|
||||
``UnsupportedError`` ("OCR is required"), which is the routing point: a
|
||||
parser given a ``fallback_parser`` (docling when installed, the native OCR
|
||||
parser when OCR is on without docling, otherwise the legacy parser for the
|
||||
suffix) delegates there; without one the file fails loudly as
|
||||
``DocumentParseError`` rather than being stored empty.
|
||||
``NeedsOcrError`` (``UnsupportedError`` "OCR is required" before 0.2.4),
|
||||
which is the routing point: a parser given a ``fallback_parser`` (docling
|
||||
when installed, the native OCR parser when OCR is on without docling,
|
||||
otherwise the legacy parser for the suffix) delegates there; without one the
|
||||
file fails loudly as ``DocumentParseError`` rather than being stored empty.
|
||||
"""
|
||||
import logging
|
||||
from pathlib import Path
|
||||
@@ -34,7 +34,7 @@ logger = logging.getLogger(__name__)
|
||||
# not content.
|
||||
_MIN_SCAN_FALLBACK_CHARS = 50
|
||||
|
||||
# Suffixes anydoc 0.2.3 converts, verified with ``anydoc.format_from_extension``.
|
||||
# Suffixes anydoc 0.2.4 converts, verified with ``anydoc.format_from_extension``.
|
||||
# ``.epub`` is deliberately absent: it stays on ``EpubParser``.
|
||||
ANYDOC_SUFFIXES: Tuple[str, ...] = (
|
||||
# Word processing
|
||||
@@ -91,6 +91,22 @@ def _result_chars(result: Union[str, List[str]]) -> int:
|
||||
return len(str(result).strip())
|
||||
|
||||
|
||||
def _needs_ocr(exc: Exception) -> bool:
|
||||
"""Whether an ``anydoc.ConvertError`` means "text exists but needs OCR".
|
||||
|
||||
anydoc 0.2.4 raises a dedicated ``NeedsOcrError`` for a PDF with no text
|
||||
layer; 0.2.3 raised ``UnsupportedError`` with "OCR" in the message. Both
|
||||
spellings route the same way, and the class is looked up lazily so an
|
||||
anydoc without it still works.
|
||||
"""
|
||||
import anydoc
|
||||
|
||||
needs_ocr_error = getattr(anydoc, "NeedsOcrError", None)
|
||||
if needs_ocr_error is not None and isinstance(exc, needs_ocr_error):
|
||||
return True
|
||||
return isinstance(exc, anydoc.UnsupportedError) and "OCR" in str(exc)
|
||||
|
||||
|
||||
def _is_docling_backed(parser: Optional[BaseParser]) -> bool:
|
||||
"""True when ``parser`` is a docling parser (worth a trust-check re-parse).
|
||||
|
||||
@@ -191,11 +207,10 @@ class AnydocParser(BaseParser):
|
||||
) from exc
|
||||
except anydoc.ConvertError as exc:
|
||||
# Typed, per-document failures another engine may still handle:
|
||||
# UnsupportedError (scanned PDF / unknown format), MalformedError,
|
||||
# EncryptedError, MissingPartError.
|
||||
ocr_needed = isinstance(exc, anydoc.UnsupportedError) and "OCR" in str(exc)
|
||||
# NeedsOcrError (scanned PDF), UnsupportedError (unknown format),
|
||||
# MalformedError, EncryptedError, MissingPartError.
|
||||
return self._delegate(
|
||||
path, errors, f"{type(exc).__name__}: {exc}", ocr_needed=ocr_needed
|
||||
path, errors, f"{type(exc).__name__}: {exc}", ocr_needed=_needs_ocr(exc)
|
||||
)
|
||||
except OSError as exc:
|
||||
raise DocumentParseError(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import Dict, Iterable, Optional, Tuple
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from openapi_parser import parse
|
||||
@@ -7,6 +8,20 @@ try:
|
||||
except ModuleNotFoundError:
|
||||
from base_parser import BaseParser
|
||||
|
||||
# openapi-parser 2.x models a path item as one field per HTTP method rather
|
||||
# than an ``operations`` list, so the methods are read in the order the
|
||||
# OpenAPI spec declares them.
|
||||
_HTTP_METHODS: Tuple[str, ...] = (
|
||||
"get",
|
||||
"put",
|
||||
"post",
|
||||
"delete",
|
||||
"options",
|
||||
"head",
|
||||
"patch",
|
||||
"trace",
|
||||
)
|
||||
|
||||
|
||||
class OpenAPI3Parser(BaseParser):
|
||||
def init_parser(self) -> None:
|
||||
@@ -21,14 +36,21 @@ class OpenAPI3Parser(BaseParser):
|
||||
base_urls.append(base_url)
|
||||
return base_urls
|
||||
|
||||
def get_info_from_paths(self, path):
|
||||
def get_operations(self, path_item) -> Iterable[Tuple[str, object]]:
|
||||
"""Yield ``(method, operation)`` for every method the path item defines."""
|
||||
for method in _HTTP_METHODS:
|
||||
operation = getattr(path_item, method, None)
|
||||
if operation is not None:
|
||||
yield method, operation
|
||||
|
||||
def get_info_from_paths(self, path_item) -> str:
|
||||
"""Render one line per method as ``\\n<method>=<first response description>``."""
|
||||
info = ""
|
||||
if path.operations:
|
||||
for operation in path.operations:
|
||||
info += (
|
||||
f"\n{operation.method.value}="
|
||||
f"{operation.responses[0].description}"
|
||||
)
|
||||
for method, operation in self.get_operations(path_item):
|
||||
responses = operation.responses or {}
|
||||
first = next(iter(responses.values()), None)
|
||||
description = getattr(first, "description", None)
|
||||
info += f"\n{method}={description}"
|
||||
return info
|
||||
|
||||
def parse_file(self, file_path):
|
||||
@@ -37,15 +59,14 @@ class OpenAPI3Parser(BaseParser):
|
||||
base_urls = self.get_base_urls(link.url for link in data.servers)
|
||||
base_urls = ",".join([base_url for base_url in base_urls])
|
||||
results += f"Base URL:{base_urls}\n"
|
||||
i = 1
|
||||
for path in data.paths:
|
||||
info = self.get_info_from_paths(path)
|
||||
paths: Optional[Dict] = data.paths or {}
|
||||
for i, (url, path_item) in enumerate(paths.items(), start=1):
|
||||
info = self.get_info_from_paths(path_item)
|
||||
results += (
|
||||
f"Path{i}: {path.url}\n"
|
||||
f"description: {path.description}\n"
|
||||
f"parameters: {path.parameters}\nmethods: {info}\n"
|
||||
f"Path{i}: {url}\n"
|
||||
f"description: {path_item.description}\n"
|
||||
f"parameters: {path_item.parameters or []}\nmethods: {info}\n"
|
||||
)
|
||||
i += 1
|
||||
with open("results.txt", "w") as f:
|
||||
f.write(results)
|
||||
return results
|
||||
@@ -18,10 +18,8 @@
|
||||
|
||||
a2wsgi==1.10.10
|
||||
# via docsgpt
|
||||
accelerate==1.14.0
|
||||
# via
|
||||
# docling-ibm-models
|
||||
# docling-slim
|
||||
accelerate==1.15.0
|
||||
# via docling-slim
|
||||
aiofile==3.12.3
|
||||
# via py-key-value-aio
|
||||
aiofiles==25.1.0
|
||||
@@ -43,7 +41,7 @@ aiohttp-retry==2.9.1
|
||||
# daytona-toolbox-api-client-async
|
||||
aiosignal==1.4.0
|
||||
# via aiohttp
|
||||
alembic==1.19.2
|
||||
alembic==1.20.0
|
||||
# via docsgpt
|
||||
amqp==5.3.1
|
||||
# via kombu
|
||||
@@ -53,7 +51,7 @@ annotated-doc==0.0.5
|
||||
# via typer
|
||||
annotated-types==0.8.0
|
||||
# via pydantic
|
||||
anthropic==0.121.0
|
||||
anthropic==1.5.0
|
||||
# via docsgpt
|
||||
antlr4-python3-runtime==4.9.3
|
||||
# via omegaconf
|
||||
@@ -63,6 +61,7 @@ anyio==4.15.1
|
||||
# google-genai
|
||||
# httpx
|
||||
# httpx-ws
|
||||
# httpx2
|
||||
# mcp
|
||||
# openai
|
||||
# py-key-value-aio
|
||||
@@ -75,7 +74,6 @@ attrs==26.1.0
|
||||
# via
|
||||
# aiohttp
|
||||
# cyclopts
|
||||
# jsonlines
|
||||
# jsonschema
|
||||
# jsonschema-path
|
||||
# referencing
|
||||
@@ -94,15 +92,15 @@ billiard==4.2.4
|
||||
# via celery
|
||||
blinker==1.9.0
|
||||
# via flask
|
||||
boto3==1.43.67
|
||||
boto3==1.43.93
|
||||
# via docsgpt
|
||||
botocore==1.43.89
|
||||
botocore==1.43.93
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
cachetools==7.1.8
|
||||
# via py-key-value-aio
|
||||
caio==0.12.2
|
||||
caio==0.12.4
|
||||
# via aiofile
|
||||
cel-python==0.5.0
|
||||
# via docsgpt
|
||||
@@ -120,8 +118,6 @@ certifi==2026.7.22
|
||||
# requests
|
||||
cffi==2.1.1 ; platform_python_implementation != 'PyPy'
|
||||
# via cryptography
|
||||
chardet==7.6.0
|
||||
# via prance
|
||||
charset-normalizer==3.5.1
|
||||
# via requests
|
||||
click==8.1.8
|
||||
@@ -152,7 +148,7 @@ colorlog==6.12.0
|
||||
# via rapidocr
|
||||
croniter==6.2.4
|
||||
# via docsgpt
|
||||
cryptography==50.0.0
|
||||
cryptography==50.0.1
|
||||
# via
|
||||
# authlib
|
||||
# docsgpt
|
||||
@@ -161,23 +157,23 @@ cryptography==50.0.0
|
||||
# msal
|
||||
# pyjwt
|
||||
# secretstorage
|
||||
cyclopts==4.24.0
|
||||
cyclopts==4.25.2
|
||||
# via fastmcp-slim
|
||||
dataclasses-json==0.6.7
|
||||
# via docsgpt
|
||||
daytona==0.205.1
|
||||
daytona==0.211.2
|
||||
# via docsgpt
|
||||
daytona-analytics-api-client==0.205.1
|
||||
daytona-analytics-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-analytics-api-client-async==0.205.1
|
||||
daytona-analytics-api-client-async==0.211.2
|
||||
# via daytona
|
||||
daytona-api-client==0.205.1
|
||||
daytona-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-api-client-async==0.205.1
|
||||
daytona-api-client-async==0.211.2
|
||||
# via daytona
|
||||
daytona-toolbox-api-client==0.205.1
|
||||
daytona-toolbox-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-toolbox-api-client-async==0.205.1
|
||||
daytona-toolbox-api-client-async==0.211.2
|
||||
# via daytona
|
||||
ddgs==9.16.0
|
||||
# via docsgpt
|
||||
@@ -194,26 +190,22 @@ deprecated==1.3.1
|
||||
dill==0.4.1
|
||||
# via multiprocess
|
||||
distro==1.9.0
|
||||
# via
|
||||
# anthropic
|
||||
# google-genai
|
||||
# openai
|
||||
# via google-genai
|
||||
dnspython==2.8.0
|
||||
# via email-validator
|
||||
doclang==0.7.3
|
||||
# via docling-core
|
||||
docling==2.119.0
|
||||
docling==2.126.0
|
||||
# via docsgpt
|
||||
docling-core==2.95.0
|
||||
docling-core==2.96.0
|
||||
# via
|
||||
# docling-ibm-models
|
||||
# docling-parse
|
||||
# docling-slim
|
||||
docling-ibm-models==3.15.0
|
||||
docling-ibm-models==4.0.2
|
||||
# via docling-slim
|
||||
docling-parse==7.17.0
|
||||
docling-parse==7.19.1
|
||||
# via docling-slim
|
||||
docling-slim==2.119.0
|
||||
docling-slim==2.126.0
|
||||
# via docling
|
||||
docstring-parser==0.18.0
|
||||
# via
|
||||
@@ -223,7 +215,7 @@ docx2txt==0.9
|
||||
# via docsgpt
|
||||
ecdsa==0.19.2
|
||||
# via python-jose
|
||||
elevenlabs==2.62.0
|
||||
elevenlabs==2.68.0
|
||||
# via docsgpt
|
||||
email-validator==2.3.0
|
||||
# via pydantic
|
||||
@@ -239,18 +231,18 @@ fast-ebook==0.2.0
|
||||
# via docsgpt
|
||||
fastembed==0.8.0
|
||||
# via docsgpt
|
||||
fastmcp==3.4.6
|
||||
fastmcp==4.0.3
|
||||
# via docsgpt
|
||||
fastmcp-slim==3.4.6
|
||||
fastmcp-slim==4.0.3
|
||||
# via fastmcp
|
||||
filelock==3.32.5
|
||||
filelock==3.32.6
|
||||
# via
|
||||
# huggingface-hub
|
||||
# tldextract
|
||||
# torch
|
||||
filetype==1.2.0
|
||||
# via docling-slim
|
||||
firecrawl-anydoc==0.2.3
|
||||
firecrawl-anydoc==0.2.4
|
||||
# via docsgpt
|
||||
flask==3.1.3
|
||||
# via
|
||||
@@ -270,9 +262,9 @@ fsspec==2026.7.0
|
||||
# torch
|
||||
google-api-core==2.36.0
|
||||
# via google-api-python-client
|
||||
google-api-python-client==2.198.0
|
||||
google-api-python-client==2.200.0
|
||||
# via docsgpt
|
||||
google-auth==2.57.1
|
||||
google-auth==2.58.0
|
||||
# via
|
||||
# google-api-core
|
||||
# google-api-python-client
|
||||
@@ -281,9 +273,9 @@ google-auth==2.57.1
|
||||
# google-genai
|
||||
google-auth-httplib2==0.4.2
|
||||
# via google-api-python-client
|
||||
google-auth-oauthlib==1.4.0
|
||||
google-auth-oauthlib==1.4.1
|
||||
# via docsgpt
|
||||
google-genai==2.17.0
|
||||
google-genai==2.23.0
|
||||
# via docsgpt
|
||||
google-re2==1.1.20251105
|
||||
# via cel-python
|
||||
@@ -302,13 +294,14 @@ grpcio==1.83.1
|
||||
# qdrant-client
|
||||
gtts==2.5.4
|
||||
# via docsgpt
|
||||
gunicorn==26.0.0
|
||||
gunicorn==26.2.0
|
||||
# via
|
||||
# docsgpt
|
||||
# uvicorn-worker
|
||||
h11==0.16.0
|
||||
# via
|
||||
# httpcore
|
||||
# httpcore2
|
||||
# uvicorn
|
||||
# wsproto
|
||||
h2==4.4.1
|
||||
@@ -321,6 +314,8 @@ httpcore==1.0.9
|
||||
# via
|
||||
# httpx
|
||||
# httpx-ws
|
||||
httpcore2==2.12.0 ; sys_platform != 'emscripten'
|
||||
# via httpx2
|
||||
httplib2==0.32.0
|
||||
# via
|
||||
# google-api-python-client
|
||||
@@ -329,21 +324,24 @@ httptools==0.8.0
|
||||
# via uvicorn
|
||||
httpx==0.28.1
|
||||
# via
|
||||
# anthropic
|
||||
# daytona
|
||||
# docling-slim
|
||||
# elevenlabs
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# httpx-ws
|
||||
# huggingface-hub
|
||||
# mcp
|
||||
# openai
|
||||
# qdrant-client
|
||||
httpx-sse==0.4.3
|
||||
# via mcp
|
||||
httpx-ws==0.9.0
|
||||
# via daytona
|
||||
httpx2==2.12.0
|
||||
# via
|
||||
# anthropic
|
||||
# docsgpt
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
# openai
|
||||
httpx2-jsfetch==1.0 ; sys_platform == 'emscripten'
|
||||
# via httpx2
|
||||
huggingface-hub==1.16.1
|
||||
# via
|
||||
# accelerate
|
||||
@@ -359,6 +357,7 @@ idna==3.19
|
||||
# anyio
|
||||
# email-validator
|
||||
# httpx
|
||||
# httpx2
|
||||
# requests
|
||||
# tldextract
|
||||
# yarl
|
||||
@@ -381,7 +380,7 @@ jinja2==3.1.6
|
||||
# docsgpt
|
||||
# flask
|
||||
# torch
|
||||
jiter==0.16.0
|
||||
jiter==0.17.0
|
||||
# via
|
||||
# anthropic
|
||||
# openai
|
||||
@@ -394,8 +393,6 @@ joserfc==1.7.5
|
||||
# via
|
||||
# authlib
|
||||
# fastmcp-slim
|
||||
jsonlines==4.0.0
|
||||
# via docling-ibm-models
|
||||
jsonref==1.1.0
|
||||
# via
|
||||
# docling-core
|
||||
@@ -405,16 +402,10 @@ jsonschema==4.26.0
|
||||
# docling-core
|
||||
# flask-restx
|
||||
# mcp
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
jsonschema-path==0.5.0
|
||||
# via
|
||||
# fastmcp-slim
|
||||
# openapi-spec-validator
|
||||
# via fastmcp-slim
|
||||
jsonschema-specifications==2025.9.1
|
||||
# via
|
||||
# jsonschema
|
||||
# openapi-schema-validator
|
||||
# via jsonschema
|
||||
keyring==25.7.0
|
||||
# via py-key-value-aio
|
||||
kombu==5.6.2
|
||||
@@ -423,10 +414,8 @@ kombu==5.6.2
|
||||
# docsgpt
|
||||
lark==1.3.1
|
||||
# via cel-python
|
||||
latex2mathml==3.81.0
|
||||
latex2mathml==3.81.1
|
||||
# via docling-core
|
||||
lazy-object-proxy==1.12.0
|
||||
# via openapi-spec-validator
|
||||
loguru==0.7.3
|
||||
# via fastembed
|
||||
lxml==6.1.3
|
||||
@@ -435,7 +424,7 @@ lxml==6.1.3
|
||||
# doclang
|
||||
# python-docx
|
||||
# python-pptx
|
||||
mail-parser==4.6.4
|
||||
mail-parser==4.6.5
|
||||
# via docling-slim
|
||||
mako==1.4.1
|
||||
# via alembic
|
||||
@@ -453,8 +442,12 @@ markupsafe==3.0.3
|
||||
# werkzeug
|
||||
marshmallow==3.26.2
|
||||
# via dataclasses-json
|
||||
mcp==1.29.1
|
||||
mcp==2.2.0
|
||||
# via fastmcp-slim
|
||||
mcp-types==2.2.0
|
||||
# via
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
mmh3==5.3.0
|
||||
@@ -467,9 +460,9 @@ mpire==2.10.2
|
||||
# via semchunk
|
||||
mpmath==1.3.0
|
||||
# via sympy
|
||||
msal==1.37.0
|
||||
msal==1.38.0
|
||||
# via docsgpt
|
||||
multidict==6.7.1
|
||||
multidict==6.8.0
|
||||
# via
|
||||
# aiohttp
|
||||
# yarl
|
||||
@@ -481,7 +474,7 @@ networkx==3.6.1
|
||||
# via
|
||||
# docsgpt
|
||||
# torch
|
||||
numpy==2.5.1
|
||||
numpy==2.5.3
|
||||
# via
|
||||
# accelerate
|
||||
# docling-ibm-models
|
||||
@@ -507,19 +500,15 @@ olefile==0.47
|
||||
# via python-oxmsg
|
||||
omegaconf==2.3.1
|
||||
# via rapidocr
|
||||
onnxruntime==1.28.0
|
||||
onnxruntime==1.30.0
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
openai==2.53.0
|
||||
openai==3.13.0
|
||||
# via docsgpt
|
||||
openapi-pydantic==0.5.1
|
||||
# via fastmcp-slim
|
||||
openapi-schema-validator==0.9.0
|
||||
# via openapi-spec-validator
|
||||
openapi-spec-validator==0.9.0
|
||||
# via openapi3-parser
|
||||
openapi3-parser==1.1.22
|
||||
openapi3-parser==2.0.0
|
||||
# via docsgpt
|
||||
opencv-python==5.0.0.93
|
||||
# via rapidocr
|
||||
@@ -532,6 +521,7 @@ opentelemetry-api==1.44.0
|
||||
# daytona
|
||||
# fastmcp-slim
|
||||
# google-api-core
|
||||
# mcp
|
||||
# opentelemetry-distro
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
# opentelemetry-exporter-otlp-proto-http
|
||||
@@ -642,7 +632,6 @@ packaging==26.3
|
||||
# accelerate
|
||||
# faiss-cpu
|
||||
# fastmcp-slim
|
||||
# gunicorn
|
||||
# huggingface-hub
|
||||
# kombu
|
||||
# marshmallow
|
||||
@@ -650,7 +639,6 @@ packaging==26.3
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-flask
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
# prance
|
||||
# transformers
|
||||
pandas==3.0.5
|
||||
# via
|
||||
@@ -676,7 +664,7 @@ pillow==12.3.0
|
||||
# python-pptx
|
||||
# rapidocr
|
||||
# torchvision
|
||||
platformdirs==4.11.7
|
||||
platformdirs==4.11.8
|
||||
# via fastmcp-slim
|
||||
pluggy==1.6.0
|
||||
# via docling-slim
|
||||
@@ -684,9 +672,7 @@ polyfactory==3.3.0
|
||||
# via docling-slim
|
||||
portalocker==3.2.0
|
||||
# via qdrant-client
|
||||
prance==26.7.19.0
|
||||
# via openapi3-parser
|
||||
praw==8.0.2
|
||||
praw==8.0.3
|
||||
# via docsgpt
|
||||
prawcore==4.0.0
|
||||
# via praw
|
||||
@@ -744,7 +730,6 @@ pydantic==2.13.5
|
||||
# daytona-toolbox-api-client
|
||||
# daytona-toolbox-api-client-async
|
||||
# docling-core
|
||||
# docling-ibm-models
|
||||
# docling-parse
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
@@ -752,10 +737,10 @@ pydantic==2.13.5
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# mcp
|
||||
# mcp-types
|
||||
# openai
|
||||
# openapi-pydantic
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
# openapi3-parser
|
||||
# pydantic-settings
|
||||
# qdrant-client
|
||||
pydantic-core==2.46.5
|
||||
@@ -768,15 +753,12 @@ pydantic-settings==2.15.0
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
pygments==2.21.0
|
||||
# via
|
||||
# mpire
|
||||
# rich
|
||||
# rich-rst
|
||||
pyjwt==2.13.0
|
||||
pyjwt==2.14.0
|
||||
# via
|
||||
# mcp
|
||||
# msal
|
||||
@@ -784,9 +766,9 @@ pylatexenc==2.11
|
||||
# via docling-slim
|
||||
pyparsing==3.3.2
|
||||
# via httplib2
|
||||
pypdf==6.15.0
|
||||
pypdf==6.18.1
|
||||
# via docsgpt
|
||||
pypdfium2==5.12.1
|
||||
pypdfium2==5.13.0
|
||||
# via
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
@@ -852,6 +834,7 @@ pyyaml==6.0.3
|
||||
# huggingface-hub
|
||||
# jsonschema-path
|
||||
# omegaconf
|
||||
# openapi3-parser
|
||||
# rapidocr
|
||||
# transformers
|
||||
# uvicorn
|
||||
@@ -861,7 +844,7 @@ rapidocr==3.9.2
|
||||
# via
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
redis==7.4.0
|
||||
redis==8.1.0
|
||||
# via
|
||||
# celery-redbeat
|
||||
# docsgpt
|
||||
@@ -871,8 +854,8 @@ referencing==0.37.0
|
||||
# jsonschema
|
||||
# jsonschema-path
|
||||
# jsonschema-specifications
|
||||
# openapi-schema-validator
|
||||
regex==2026.9.3
|
||||
# openapi3-parser
|
||||
regex==2026.9.10
|
||||
# via
|
||||
# tiktoken
|
||||
# transformers
|
||||
@@ -888,7 +871,6 @@ requests==2.34.2
|
||||
# gtts
|
||||
# msal
|
||||
# opentelemetry-exporter-otlp-proto-http
|
||||
# prance
|
||||
# prawcore
|
||||
# python-socketio
|
||||
# rapidocr
|
||||
@@ -902,8 +884,6 @@ requests-oauthlib==2.0.0
|
||||
# via google-auth-oauthlib
|
||||
retry==0.9.2
|
||||
# via docsgpt
|
||||
rfc3339-validator==0.1.4
|
||||
# via openapi-schema-validator
|
||||
rich==15.0.0
|
||||
# via
|
||||
# cyclopts
|
||||
@@ -920,11 +900,7 @@ rpds-py==2026.6.3
|
||||
rsa==4.9.1
|
||||
# via python-jose
|
||||
rtree==1.4.1
|
||||
# via
|
||||
# docling-ibm-models
|
||||
# docling-slim
|
||||
ruamel-yaml==0.19.1
|
||||
# via prance
|
||||
# via docling-slim
|
||||
s3transfer==0.19.2
|
||||
# via boto3
|
||||
safetensors==0.8.0
|
||||
@@ -938,7 +914,7 @@ secretstorage==3.5.0 ; sys_platform == 'linux'
|
||||
# via keyring
|
||||
semchunk==3.2.5
|
||||
# via docling-core
|
||||
setuptools==81.0.0
|
||||
setuptools==84.0.0
|
||||
# via torch
|
||||
shapely==2.1.2
|
||||
# via rapidocr
|
||||
@@ -952,7 +928,6 @@ six==1.17.0
|
||||
# markdownify
|
||||
# python-dateutil
|
||||
# rapidocr
|
||||
# rfc3339-validator
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# anthropic
|
||||
@@ -980,18 +955,18 @@ tenacity==9.1.4
|
||||
# via
|
||||
# celery-redbeat
|
||||
# google-genai
|
||||
tiktoken==0.13.0
|
||||
tiktoken==0.14.0
|
||||
# via docsgpt
|
||||
tldextract==5.3.2
|
||||
# via docsgpt
|
||||
tokenizers==0.22.2
|
||||
tokenizers==0.23.2
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
# transformers
|
||||
toml==0.10.2
|
||||
# via daytona
|
||||
torch==2.11.0 ; sys_platform != 'linux'
|
||||
torch==2.14.0 ; sys_platform != 'linux'
|
||||
# via
|
||||
# accelerate
|
||||
# docling-ibm-models
|
||||
@@ -999,7 +974,7 @@ torch==2.11.0 ; sys_platform != 'linux'
|
||||
# docsgpt
|
||||
# safetensors
|
||||
# torchvision
|
||||
torch==2.11.0+cpu ; sys_platform == 'linux'
|
||||
torch==2.14.0+cpu ; sys_platform == 'linux'
|
||||
# via
|
||||
# accelerate
|
||||
# docling-ibm-models
|
||||
@@ -1007,29 +982,27 @@ torch==2.11.0+cpu ; sys_platform == 'linux'
|
||||
# docsgpt
|
||||
# safetensors
|
||||
# torchvision
|
||||
torchvision==0.26.0 ; sys_platform != 'linux'
|
||||
torchvision==0.29.0 ; sys_platform != 'linux'
|
||||
# via
|
||||
# docling-ibm-models
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
torchvision==0.26.0+cpu ; sys_platform == 'linux'
|
||||
torchvision==0.29.0+cpu ; sys_platform == 'linux'
|
||||
# via
|
||||
# docling-ibm-models
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
tqdm==4.67.3
|
||||
tqdm==4.70.1
|
||||
# via
|
||||
# docling-ibm-models
|
||||
# docling-slim
|
||||
# docsgpt
|
||||
# fastembed
|
||||
# huggingface-hub
|
||||
# mpire
|
||||
# openai
|
||||
# rapidocr
|
||||
# semchunk
|
||||
# transformers
|
||||
transformers==5.8.1
|
||||
transformers==5.17.0
|
||||
# via
|
||||
# docling-core
|
||||
# docling-ibm-models
|
||||
@@ -1044,6 +1017,10 @@ tree-sitter-python==0.25.0
|
||||
# via docling-core
|
||||
tree-sitter-typescript==0.23.2
|
||||
# via docling-core
|
||||
truststore==0.10.4 ; sys_platform != 'emscripten'
|
||||
# via
|
||||
# httpcore2
|
||||
# httpx2
|
||||
typer==0.26.8
|
||||
# via
|
||||
# doclang
|
||||
@@ -1072,8 +1049,10 @@ typing-extensions==4.16.0
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# grpcio
|
||||
# httpx2
|
||||
# huggingface-hub
|
||||
# mcp
|
||||
# mcp-types
|
||||
# obstore
|
||||
# openai
|
||||
# opentelemetry-api
|
||||
@@ -1103,7 +1082,7 @@ typing-inspection==0.4.4
|
||||
# mcp
|
||||
# pydantic
|
||||
# pydantic-settings
|
||||
tzdata==2026.3
|
||||
tzdata==2026.4
|
||||
# via
|
||||
# faker
|
||||
# kombu
|
||||
@@ -1149,7 +1128,7 @@ watchfiles==1.2.0
|
||||
# uvicorn
|
||||
wcwidth==0.8.3
|
||||
# via prompt-toolkit
|
||||
websocket-client==1.9.0
|
||||
websocket-client==1.9.2
|
||||
# via
|
||||
# docsgpt
|
||||
# praw
|
||||
@@ -1168,7 +1147,7 @@ werkzeug==3.1.8
|
||||
# flask-restx
|
||||
win32-setctime==1.2.0 ; sys_platform == 'win32'
|
||||
# via loguru
|
||||
wrapt==2.4.0
|
||||
wrapt==2.4.1
|
||||
# via
|
||||
# deprecated
|
||||
# opentelemetry-instrumentation
|
||||
|
||||
@@ -27,7 +27,7 @@ aiohttp-retry==2.9.1
|
||||
# daytona-toolbox-api-client-async
|
||||
aiosignal==1.4.0
|
||||
# via aiohttp
|
||||
alembic==1.19.2
|
||||
alembic==1.20.0
|
||||
# via docsgpt
|
||||
amqp==5.3.1
|
||||
# via kombu
|
||||
@@ -37,7 +37,7 @@ annotated-doc==0.0.5
|
||||
# via typer
|
||||
annotated-types==0.8.0
|
||||
# via pydantic
|
||||
anthropic==0.121.0
|
||||
anthropic==1.5.0
|
||||
# via docsgpt
|
||||
anyio==4.15.1
|
||||
# via
|
||||
@@ -45,6 +45,7 @@ anyio==4.15.1
|
||||
# google-genai
|
||||
# httpx
|
||||
# httpx-ws
|
||||
# httpx2
|
||||
# mcp
|
||||
# openai
|
||||
# py-key-value-aio
|
||||
@@ -74,9 +75,9 @@ billiard==4.2.4
|
||||
# via celery
|
||||
blinker==1.9.0
|
||||
# via flask
|
||||
boto3==1.43.67
|
||||
boto3==1.43.93
|
||||
# via docsgpt
|
||||
botocore==1.43.89
|
||||
botocore==1.43.93
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
@@ -84,7 +85,7 @@ cachetools==7.1.8
|
||||
# via
|
||||
# py-key-value-aio
|
||||
# pymilvus
|
||||
caio==0.12.2
|
||||
caio==0.12.4
|
||||
# via aiofile
|
||||
cel-python==0.5.0
|
||||
# via docsgpt
|
||||
@@ -101,8 +102,6 @@ certifi==2026.7.22
|
||||
# requests
|
||||
cffi==2.1.1 ; platform_python_implementation != 'PyPy'
|
||||
# via cryptography
|
||||
chardet==7.6.0
|
||||
# via prance
|
||||
charset-normalizer==3.5.1
|
||||
# via requests
|
||||
click==8.1.8
|
||||
@@ -129,7 +128,7 @@ colorama==0.4.6 ; sys_platform == 'win32'
|
||||
# typer
|
||||
croniter==6.2.4
|
||||
# via docsgpt
|
||||
cryptography==50.0.0
|
||||
cryptography==50.0.1
|
||||
# via
|
||||
# authlib
|
||||
# docsgpt
|
||||
@@ -138,23 +137,23 @@ cryptography==50.0.0
|
||||
# msal
|
||||
# pyjwt
|
||||
# secretstorage
|
||||
cyclopts==4.24.0
|
||||
cyclopts==4.25.2
|
||||
# via fastmcp-slim
|
||||
dataclasses-json==0.6.7
|
||||
# via docsgpt
|
||||
daytona==0.205.1
|
||||
daytona==0.211.2
|
||||
# via docsgpt
|
||||
daytona-analytics-api-client==0.205.1
|
||||
daytona-analytics-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-analytics-api-client-async==0.205.1
|
||||
daytona-analytics-api-client-async==0.211.2
|
||||
# via daytona
|
||||
daytona-api-client==0.205.1
|
||||
daytona-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-api-client-async==0.205.1
|
||||
daytona-api-client-async==0.211.2
|
||||
# via daytona
|
||||
daytona-toolbox-api-client==0.205.1
|
||||
daytona-toolbox-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-toolbox-api-client-async==0.205.1
|
||||
daytona-toolbox-api-client-async==0.211.2
|
||||
# via daytona
|
||||
ddgs==9.16.0
|
||||
# via docsgpt
|
||||
@@ -167,10 +166,7 @@ defusedxml==0.7.1
|
||||
deprecated==1.3.1
|
||||
# via daytona
|
||||
distro==1.9.0
|
||||
# via
|
||||
# anthropic
|
||||
# google-genai
|
||||
# openai
|
||||
# via google-genai
|
||||
dnspython==2.8.0
|
||||
# via email-validator
|
||||
docstring-parser==0.18.0
|
||||
@@ -181,7 +177,7 @@ docx2txt==0.9
|
||||
# via docsgpt
|
||||
ecdsa==0.19.2
|
||||
# via python-jose
|
||||
elevenlabs==2.62.0
|
||||
elevenlabs==2.68.0
|
||||
# via docsgpt
|
||||
email-validator==2.3.0
|
||||
# via pydantic
|
||||
@@ -197,15 +193,15 @@ fast-ebook==0.2.0
|
||||
# via docsgpt
|
||||
fastembed==0.8.0
|
||||
# via docsgpt
|
||||
fastmcp==3.4.6
|
||||
fastmcp==4.0.3
|
||||
# via docsgpt
|
||||
fastmcp-slim==3.4.6
|
||||
fastmcp-slim==4.0.3
|
||||
# via fastmcp
|
||||
filelock==3.32.5
|
||||
filelock==3.32.6
|
||||
# via
|
||||
# huggingface-hub
|
||||
# tldextract
|
||||
firecrawl-anydoc==0.2.3
|
||||
firecrawl-anydoc==0.2.4
|
||||
# via docsgpt
|
||||
flask==3.1.3
|
||||
# via
|
||||
@@ -223,9 +219,9 @@ fsspec==2026.7.0
|
||||
# via huggingface-hub
|
||||
google-api-core==2.36.0
|
||||
# via google-api-python-client
|
||||
google-api-python-client==2.198.0
|
||||
google-api-python-client==2.200.0
|
||||
# via docsgpt
|
||||
google-auth==2.57.1
|
||||
google-auth==2.58.0
|
||||
# via
|
||||
# google-api-core
|
||||
# google-api-python-client
|
||||
@@ -234,9 +230,9 @@ google-auth==2.57.1
|
||||
# google-genai
|
||||
google-auth-httplib2==0.4.2
|
||||
# via google-api-python-client
|
||||
google-auth-oauthlib==1.4.0
|
||||
google-auth-oauthlib==1.4.1
|
||||
# via docsgpt
|
||||
google-genai==2.17.0
|
||||
google-genai==2.23.0
|
||||
# via docsgpt
|
||||
google-re2==1.1.20251105
|
||||
# via cel-python
|
||||
@@ -257,13 +253,14 @@ grpcio==1.83.1
|
||||
# qdrant-client
|
||||
gtts==2.5.4
|
||||
# via docsgpt
|
||||
gunicorn==26.0.0
|
||||
gunicorn==26.2.0
|
||||
# via
|
||||
# docsgpt
|
||||
# uvicorn-worker
|
||||
h11==0.16.0
|
||||
# via
|
||||
# httpcore
|
||||
# httpcore2
|
||||
# uvicorn
|
||||
# wsproto
|
||||
h2==4.4.1
|
||||
@@ -276,6 +273,8 @@ httpcore==1.0.9
|
||||
# via
|
||||
# httpx
|
||||
# httpx-ws
|
||||
httpcore2==2.12.0 ; sys_platform != 'emscripten'
|
||||
# via httpx2
|
||||
httplib2==0.32.0
|
||||
# via
|
||||
# google-api-python-client
|
||||
@@ -284,20 +283,23 @@ httptools==0.8.0
|
||||
# via uvicorn
|
||||
httpx==0.28.1
|
||||
# via
|
||||
# anthropic
|
||||
# daytona
|
||||
# elevenlabs
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# httpx-ws
|
||||
# huggingface-hub
|
||||
# mcp
|
||||
# openai
|
||||
# qdrant-client
|
||||
httpx-sse==0.4.3
|
||||
# via mcp
|
||||
httpx-ws==0.9.0
|
||||
# via daytona
|
||||
httpx2==2.12.0
|
||||
# via
|
||||
# anthropic
|
||||
# docsgpt
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
# openai
|
||||
httpx2-jsfetch==1.0 ; sys_platform == 'emscripten'
|
||||
# via httpx2
|
||||
huggingface-hub==1.16.1
|
||||
# via
|
||||
# fastembed
|
||||
@@ -309,6 +311,7 @@ idna==3.19
|
||||
# anyio
|
||||
# email-validator
|
||||
# httpx
|
||||
# httpx2
|
||||
# requests
|
||||
# tldextract
|
||||
# yarl
|
||||
@@ -330,7 +333,7 @@ jinja2==3.1.6
|
||||
# via
|
||||
# docsgpt
|
||||
# flask
|
||||
jiter==0.16.0
|
||||
jiter==0.17.0
|
||||
# via
|
||||
# anthropic
|
||||
# openai
|
||||
@@ -349,16 +352,10 @@ jsonschema==4.26.0
|
||||
# via
|
||||
# flask-restx
|
||||
# mcp
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
jsonschema-path==0.5.0
|
||||
# via
|
||||
# fastmcp-slim
|
||||
# openapi-spec-validator
|
||||
# via fastmcp-slim
|
||||
jsonschema-specifications==2025.9.1
|
||||
# via
|
||||
# jsonschema
|
||||
# openapi-schema-validator
|
||||
# via jsonschema
|
||||
keyring==25.7.0
|
||||
# via py-key-value-aio
|
||||
kombu==5.6.2
|
||||
@@ -367,8 +364,6 @@ kombu==5.6.2
|
||||
# docsgpt
|
||||
lark==1.3.1
|
||||
# via cel-python
|
||||
lazy-object-proxy==1.12.0
|
||||
# via openapi-spec-validator
|
||||
loguru==0.7.3
|
||||
# via fastembed
|
||||
lxml==6.1.3
|
||||
@@ -389,11 +384,15 @@ markupsafe==3.0.3
|
||||
# werkzeug
|
||||
marshmallow==3.26.2
|
||||
# via dataclasses-json
|
||||
mcp==1.29.1
|
||||
mcp==2.2.0
|
||||
# via fastmcp-slim
|
||||
mcp-types==2.2.0
|
||||
# via
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
milvus-lite==3.2.0 ; sys_platform != 'win32'
|
||||
milvus-lite==3.2.1 ; sys_platform != 'win32'
|
||||
# via docsgpt
|
||||
mmh3==5.3.0
|
||||
# via fastembed
|
||||
@@ -401,9 +400,9 @@ more-itertools==11.1.0
|
||||
# via
|
||||
# jaraco-classes
|
||||
# jaraco-functools
|
||||
msal==1.37.0
|
||||
msal==1.38.0
|
||||
# via docsgpt
|
||||
multidict==6.7.1
|
||||
multidict==6.8.0
|
||||
# via
|
||||
# aiohttp
|
||||
# yarl
|
||||
@@ -411,7 +410,7 @@ mypy-extensions==1.1.0
|
||||
# via typing-inspect
|
||||
networkx==3.6.1
|
||||
# via docsgpt
|
||||
numpy==2.5.1
|
||||
numpy==2.5.3
|
||||
# via
|
||||
# docsgpt
|
||||
# faiss-cpu
|
||||
@@ -424,19 +423,15 @@ oauthlib==3.3.1
|
||||
# via requests-oauthlib
|
||||
obstore==0.11.1
|
||||
# via daytona
|
||||
onnxruntime==1.28.0
|
||||
onnxruntime==1.30.0
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
openai==2.53.0
|
||||
openai==3.13.0
|
||||
# via docsgpt
|
||||
openapi-pydantic==0.5.1
|
||||
# via fastmcp-slim
|
||||
openapi-schema-validator==0.9.0
|
||||
# via openapi-spec-validator
|
||||
openapi-spec-validator==0.9.0
|
||||
# via openapi3-parser
|
||||
openapi3-parser==1.1.22
|
||||
openapi3-parser==2.0.0
|
||||
# via docsgpt
|
||||
openpyxl==3.1.5
|
||||
# via docsgpt
|
||||
@@ -445,6 +440,7 @@ opentelemetry-api==1.44.0
|
||||
# daytona
|
||||
# fastmcp-slim
|
||||
# google-api-core
|
||||
# mcp
|
||||
# opentelemetry-distro
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
# opentelemetry-exporter-otlp-proto-http
|
||||
@@ -556,7 +552,6 @@ packaging==26.3
|
||||
# via
|
||||
# faiss-cpu
|
||||
# fastmcp-slim
|
||||
# gunicorn
|
||||
# huggingface-hub
|
||||
# kombu
|
||||
# marshmallow
|
||||
@@ -564,7 +559,6 @@ packaging==26.3
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-flask
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
# prance
|
||||
pandas==3.0.5
|
||||
# via
|
||||
# docsgpt
|
||||
@@ -583,13 +577,11 @@ pillow==12.3.0
|
||||
# fastembed
|
||||
# pdf2image
|
||||
# python-pptx
|
||||
platformdirs==4.11.7
|
||||
platformdirs==4.11.8
|
||||
# via fastmcp-slim
|
||||
portalocker==3.2.0
|
||||
# via qdrant-client
|
||||
prance==26.7.19.0
|
||||
# via openapi3-parser
|
||||
praw==8.0.2
|
||||
praw==8.0.3
|
||||
# via docsgpt
|
||||
prawcore==4.0.0
|
||||
# via praw
|
||||
@@ -650,10 +642,10 @@ pydantic==2.13.5
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# mcp
|
||||
# mcp-types
|
||||
# openai
|
||||
# openapi-pydantic
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
# openapi3-parser
|
||||
# pydantic-settings
|
||||
# qdrant-client
|
||||
pydantic-core==2.46.5
|
||||
@@ -664,14 +656,11 @@ pydantic-settings==2.15.0
|
||||
# via
|
||||
# docsgpt
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
pygments==2.21.0
|
||||
# via
|
||||
# rich
|
||||
# rich-rst
|
||||
pyjwt==2.13.0
|
||||
pyjwt==2.14.0
|
||||
# via
|
||||
# mcp
|
||||
# msal
|
||||
@@ -679,9 +668,9 @@ pymilvus==3.0.1
|
||||
# via docsgpt
|
||||
pyparsing==3.3.2
|
||||
# via httplib2
|
||||
pypdf==6.15.0
|
||||
pypdf==6.18.1
|
||||
# via docsgpt
|
||||
pypdfium2==5.12.1
|
||||
pypdfium2==5.13.0
|
||||
# via docsgpt
|
||||
pyperclip==1.11.0
|
||||
# via fastmcp-slim
|
||||
@@ -734,10 +723,11 @@ pyyaml==6.0.3
|
||||
# fastmcp-slim
|
||||
# huggingface-hub
|
||||
# jsonschema-path
|
||||
# openapi3-parser
|
||||
# uvicorn
|
||||
qdrant-client==1.19.0
|
||||
# via docsgpt
|
||||
redis==7.4.0
|
||||
redis==8.1.0
|
||||
# via
|
||||
# celery-redbeat
|
||||
# docsgpt
|
||||
@@ -747,8 +737,8 @@ referencing==0.37.0
|
||||
# jsonschema
|
||||
# jsonschema-path
|
||||
# jsonschema-specifications
|
||||
# openapi-schema-validator
|
||||
regex==2026.9.3
|
||||
# openapi3-parser
|
||||
regex==2026.9.10
|
||||
# via tiktoken
|
||||
requests==2.34.2
|
||||
# via
|
||||
@@ -761,7 +751,6 @@ requests==2.34.2
|
||||
# gtts
|
||||
# msal
|
||||
# opentelemetry-exporter-otlp-proto-http
|
||||
# prance
|
||||
# prawcore
|
||||
# pymilvus
|
||||
# python-socketio
|
||||
@@ -775,8 +764,6 @@ requests-oauthlib==2.0.0
|
||||
# via google-auth-oauthlib
|
||||
retry==0.9.2
|
||||
# via docsgpt
|
||||
rfc3339-validator==0.1.4
|
||||
# via openapi-schema-validator
|
||||
rich==15.0.0
|
||||
# via
|
||||
# cyclopts
|
||||
@@ -791,8 +778,6 @@ rpds-py==2026.6.3
|
||||
# referencing
|
||||
rsa==4.9.1
|
||||
# via python-jose
|
||||
ruamel-yaml==0.19.1
|
||||
# via prance
|
||||
s3transfer==0.19.2
|
||||
# via boto3
|
||||
secretstorage==3.5.0 ; sys_platform == 'linux'
|
||||
@@ -806,7 +791,6 @@ six==1.17.0
|
||||
# ecdsa
|
||||
# markdownify
|
||||
# python-dateutil
|
||||
# rfc3339-validator
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# anthropic
|
||||
@@ -830,22 +814,25 @@ tenacity==9.1.4
|
||||
# via
|
||||
# celery-redbeat
|
||||
# google-genai
|
||||
tiktoken==0.13.0
|
||||
tiktoken==0.14.0
|
||||
# via docsgpt
|
||||
tldextract==5.3.2
|
||||
# via docsgpt
|
||||
tokenizers==0.22.2
|
||||
tokenizers==0.23.2
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
toml==0.10.2
|
||||
# via daytona
|
||||
tqdm==4.67.3
|
||||
tqdm==4.70.1
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
# huggingface-hub
|
||||
# openai
|
||||
truststore==0.10.4 ; sys_platform != 'emscripten'
|
||||
# via
|
||||
# httpcore2
|
||||
# httpx2
|
||||
typer==0.26.8
|
||||
# via huggingface-hub
|
||||
typing-extensions==4.16.0
|
||||
@@ -868,8 +855,10 @@ typing-extensions==4.16.0
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# grpcio
|
||||
# httpx2
|
||||
# huggingface-hub
|
||||
# mcp
|
||||
# mcp-types
|
||||
# obstore
|
||||
# openai
|
||||
# opentelemetry-api
|
||||
@@ -895,7 +884,7 @@ typing-inspection==0.4.4
|
||||
# mcp
|
||||
# pydantic
|
||||
# pydantic-settings
|
||||
tzdata==2026.3
|
||||
tzdata==2026.4
|
||||
# via
|
||||
# kombu
|
||||
# pandas
|
||||
@@ -940,7 +929,7 @@ watchfiles==1.2.0
|
||||
# uvicorn
|
||||
wcwidth==0.8.3
|
||||
# via prompt-toolkit
|
||||
websocket-client==1.9.0
|
||||
websocket-client==1.9.2
|
||||
# via
|
||||
# docsgpt
|
||||
# praw
|
||||
@@ -958,7 +947,7 @@ werkzeug==3.1.8
|
||||
# flask-restx
|
||||
win32-setctime==1.2.0 ; sys_platform == 'win32'
|
||||
# via loguru
|
||||
wrapt==2.4.0
|
||||
wrapt==2.4.1
|
||||
# via
|
||||
# deprecated
|
||||
# opentelemetry-instrumentation
|
||||
|
||||
+77
-88
@@ -27,7 +27,7 @@ aiohttp-retry==2.9.1
|
||||
# daytona-toolbox-api-client-async
|
||||
aiosignal==1.4.0
|
||||
# via aiohttp
|
||||
alembic==1.19.2
|
||||
alembic==1.20.0
|
||||
# via docsgpt
|
||||
amqp==5.3.1
|
||||
# via kombu
|
||||
@@ -37,7 +37,7 @@ annotated-doc==0.0.5
|
||||
# via typer
|
||||
annotated-types==0.8.0
|
||||
# via pydantic
|
||||
anthropic==0.121.0
|
||||
anthropic==1.5.0
|
||||
# via docsgpt
|
||||
anyio==4.15.1
|
||||
# via
|
||||
@@ -45,6 +45,7 @@ anyio==4.15.1
|
||||
# google-genai
|
||||
# httpx
|
||||
# httpx-ws
|
||||
# httpx2
|
||||
# mcp
|
||||
# openai
|
||||
# py-key-value-aio
|
||||
@@ -74,15 +75,15 @@ billiard==4.2.4
|
||||
# via celery
|
||||
blinker==1.9.0
|
||||
# via flask
|
||||
boto3==1.43.67
|
||||
boto3==1.43.93
|
||||
# via docsgpt
|
||||
botocore==1.43.89
|
||||
botocore==1.43.93
|
||||
# via
|
||||
# boto3
|
||||
# s3transfer
|
||||
cachetools==7.1.8
|
||||
# via py-key-value-aio
|
||||
caio==0.12.2
|
||||
caio==0.12.4
|
||||
# via aiofile
|
||||
cel-python==0.5.0
|
||||
# via docsgpt
|
||||
@@ -99,8 +100,6 @@ certifi==2026.7.22
|
||||
# requests
|
||||
cffi==2.1.1 ; platform_python_implementation != 'PyPy'
|
||||
# via cryptography
|
||||
chardet==7.6.0
|
||||
# via prance
|
||||
charset-normalizer==3.5.1
|
||||
# via requests
|
||||
click==8.1.8
|
||||
@@ -127,7 +126,7 @@ colorama==0.4.6 ; sys_platform == 'win32'
|
||||
# typer
|
||||
croniter==6.2.4
|
||||
# via docsgpt
|
||||
cryptography==50.0.0
|
||||
cryptography==50.0.1
|
||||
# via
|
||||
# authlib
|
||||
# docsgpt
|
||||
@@ -136,23 +135,23 @@ cryptography==50.0.0
|
||||
# msal
|
||||
# pyjwt
|
||||
# secretstorage
|
||||
cyclopts==4.24.0
|
||||
cyclopts==4.25.2
|
||||
# via fastmcp-slim
|
||||
dataclasses-json==0.6.7
|
||||
# via docsgpt
|
||||
daytona==0.205.1
|
||||
daytona==0.211.2
|
||||
# via docsgpt
|
||||
daytona-analytics-api-client==0.205.1
|
||||
daytona-analytics-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-analytics-api-client-async==0.205.1
|
||||
daytona-analytics-api-client-async==0.211.2
|
||||
# via daytona
|
||||
daytona-api-client==0.205.1
|
||||
daytona-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-api-client-async==0.205.1
|
||||
daytona-api-client-async==0.211.2
|
||||
# via daytona
|
||||
daytona-toolbox-api-client==0.205.1
|
||||
daytona-toolbox-api-client==0.211.2
|
||||
# via daytona
|
||||
daytona-toolbox-api-client-async==0.205.1
|
||||
daytona-toolbox-api-client-async==0.211.2
|
||||
# via daytona
|
||||
ddgs==9.16.0
|
||||
# via docsgpt
|
||||
@@ -165,10 +164,7 @@ defusedxml==0.7.1
|
||||
deprecated==1.3.1
|
||||
# via daytona
|
||||
distro==1.9.0
|
||||
# via
|
||||
# anthropic
|
||||
# google-genai
|
||||
# openai
|
||||
# via google-genai
|
||||
dnspython==2.8.0
|
||||
# via email-validator
|
||||
docstring-parser==0.18.0
|
||||
@@ -179,7 +175,7 @@ docx2txt==0.9
|
||||
# via docsgpt
|
||||
ecdsa==0.19.2
|
||||
# via python-jose
|
||||
elevenlabs==2.62.0
|
||||
elevenlabs==2.68.0
|
||||
# via docsgpt
|
||||
email-validator==2.3.0
|
||||
# via pydantic
|
||||
@@ -193,15 +189,15 @@ fast-ebook==0.2.0
|
||||
# via docsgpt
|
||||
fastembed==0.8.0
|
||||
# via docsgpt
|
||||
fastmcp==3.4.6
|
||||
fastmcp==4.0.3
|
||||
# via docsgpt
|
||||
fastmcp-slim==3.4.6
|
||||
fastmcp-slim==4.0.3
|
||||
# via fastmcp
|
||||
filelock==3.32.5
|
||||
filelock==3.32.6
|
||||
# via
|
||||
# huggingface-hub
|
||||
# tldextract
|
||||
firecrawl-anydoc==0.2.3
|
||||
firecrawl-anydoc==0.2.4
|
||||
# via docsgpt
|
||||
flask==3.1.3
|
||||
# via
|
||||
@@ -219,9 +215,9 @@ fsspec==2026.7.0
|
||||
# via huggingface-hub
|
||||
google-api-core==2.36.0
|
||||
# via google-api-python-client
|
||||
google-api-python-client==2.198.0
|
||||
google-api-python-client==2.200.0
|
||||
# via docsgpt
|
||||
google-auth==2.57.1
|
||||
google-auth==2.58.0
|
||||
# via
|
||||
# google-api-core
|
||||
# google-api-python-client
|
||||
@@ -230,9 +226,9 @@ google-auth==2.57.1
|
||||
# google-genai
|
||||
google-auth-httplib2==0.4.2
|
||||
# via google-api-python-client
|
||||
google-auth-oauthlib==1.4.0
|
||||
google-auth-oauthlib==1.4.1
|
||||
# via docsgpt
|
||||
google-genai==2.17.0
|
||||
google-genai==2.23.0
|
||||
# via docsgpt
|
||||
google-re2==1.1.20251105
|
||||
# via cel-python
|
||||
@@ -251,13 +247,14 @@ grpcio==1.83.1
|
||||
# qdrant-client
|
||||
gtts==2.5.4
|
||||
# via docsgpt
|
||||
gunicorn==26.0.0
|
||||
gunicorn==26.2.0
|
||||
# via
|
||||
# docsgpt
|
||||
# uvicorn-worker
|
||||
h11==0.16.0
|
||||
# via
|
||||
# httpcore
|
||||
# httpcore2
|
||||
# uvicorn
|
||||
# wsproto
|
||||
h2==4.4.1
|
||||
@@ -270,6 +267,8 @@ httpcore==1.0.9
|
||||
# via
|
||||
# httpx
|
||||
# httpx-ws
|
||||
httpcore2==2.12.0 ; sys_platform != 'emscripten'
|
||||
# via httpx2
|
||||
httplib2==0.32.0
|
||||
# via
|
||||
# google-api-python-client
|
||||
@@ -278,20 +277,23 @@ httptools==0.8.0
|
||||
# via uvicorn
|
||||
httpx==0.28.1
|
||||
# via
|
||||
# anthropic
|
||||
# daytona
|
||||
# elevenlabs
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# httpx-ws
|
||||
# huggingface-hub
|
||||
# mcp
|
||||
# openai
|
||||
# qdrant-client
|
||||
httpx-sse==0.4.3
|
||||
# via mcp
|
||||
httpx-ws==0.9.0
|
||||
# via daytona
|
||||
httpx2==2.12.0
|
||||
# via
|
||||
# anthropic
|
||||
# docsgpt
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
# openai
|
||||
httpx2-jsfetch==1.0 ; sys_platform == 'emscripten'
|
||||
# via httpx2
|
||||
huggingface-hub==1.16.1
|
||||
# via
|
||||
# fastembed
|
||||
@@ -303,6 +305,7 @@ idna==3.19
|
||||
# anyio
|
||||
# email-validator
|
||||
# httpx
|
||||
# httpx2
|
||||
# requests
|
||||
# tldextract
|
||||
# yarl
|
||||
@@ -324,7 +327,7 @@ jinja2==3.1.6
|
||||
# via
|
||||
# docsgpt
|
||||
# flask
|
||||
jiter==0.16.0
|
||||
jiter==0.17.0
|
||||
# via
|
||||
# anthropic
|
||||
# openai
|
||||
@@ -343,16 +346,10 @@ jsonschema==4.26.0
|
||||
# via
|
||||
# flask-restx
|
||||
# mcp
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
jsonschema-path==0.5.0
|
||||
# via
|
||||
# fastmcp-slim
|
||||
# openapi-spec-validator
|
||||
# via fastmcp-slim
|
||||
jsonschema-specifications==2025.9.1
|
||||
# via
|
||||
# jsonschema
|
||||
# openapi-schema-validator
|
||||
# via jsonschema
|
||||
keyring==25.7.0
|
||||
# via py-key-value-aio
|
||||
kombu==5.6.2
|
||||
@@ -361,8 +358,6 @@ kombu==5.6.2
|
||||
# docsgpt
|
||||
lark==1.3.1
|
||||
# via cel-python
|
||||
lazy-object-proxy==1.12.0
|
||||
# via openapi-spec-validator
|
||||
loguru==0.7.3
|
||||
# via fastembed
|
||||
lxml==6.1.3
|
||||
@@ -383,8 +378,12 @@ markupsafe==3.0.3
|
||||
# werkzeug
|
||||
marshmallow==3.26.2
|
||||
# via dataclasses-json
|
||||
mcp==1.29.1
|
||||
mcp==2.2.0
|
||||
# via fastmcp-slim
|
||||
mcp-types==2.2.0
|
||||
# via
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
mmh3==5.3.0
|
||||
@@ -393,9 +392,9 @@ more-itertools==11.1.0
|
||||
# via
|
||||
# jaraco-classes
|
||||
# jaraco-functools
|
||||
msal==1.37.0
|
||||
msal==1.38.0
|
||||
# via docsgpt
|
||||
multidict==6.7.1
|
||||
multidict==6.8.0
|
||||
# via
|
||||
# aiohttp
|
||||
# yarl
|
||||
@@ -403,7 +402,7 @@ mypy-extensions==1.1.0
|
||||
# via typing-inspect
|
||||
networkx==3.6.1
|
||||
# via docsgpt
|
||||
numpy==2.5.1
|
||||
numpy==2.5.3
|
||||
# via
|
||||
# docsgpt
|
||||
# faiss-cpu
|
||||
@@ -415,19 +414,15 @@ oauthlib==3.3.1
|
||||
# via requests-oauthlib
|
||||
obstore==0.11.1
|
||||
# via daytona
|
||||
onnxruntime==1.28.0
|
||||
onnxruntime==1.30.0
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
openai==2.53.0
|
||||
openai==3.13.0
|
||||
# via docsgpt
|
||||
openapi-pydantic==0.5.1
|
||||
# via fastmcp-slim
|
||||
openapi-schema-validator==0.9.0
|
||||
# via openapi-spec-validator
|
||||
openapi-spec-validator==0.9.0
|
||||
# via openapi3-parser
|
||||
openapi3-parser==1.1.22
|
||||
openapi3-parser==2.0.0
|
||||
# via docsgpt
|
||||
openpyxl==3.1.5
|
||||
# via docsgpt
|
||||
@@ -436,6 +431,7 @@ opentelemetry-api==1.44.0
|
||||
# daytona
|
||||
# fastmcp-slim
|
||||
# google-api-core
|
||||
# mcp
|
||||
# opentelemetry-distro
|
||||
# opentelemetry-exporter-otlp-proto-grpc
|
||||
# opentelemetry-exporter-otlp-proto-http
|
||||
@@ -545,7 +541,6 @@ packaging==26.3
|
||||
# via
|
||||
# faiss-cpu
|
||||
# fastmcp-slim
|
||||
# gunicorn
|
||||
# huggingface-hub
|
||||
# kombu
|
||||
# marshmallow
|
||||
@@ -553,7 +548,6 @@ packaging==26.3
|
||||
# opentelemetry-instrumentation
|
||||
# opentelemetry-instrumentation-flask
|
||||
# opentelemetry-instrumentation-sqlalchemy
|
||||
# prance
|
||||
pandas==3.0.5
|
||||
# via docsgpt
|
||||
pathable==0.6.0
|
||||
@@ -570,13 +564,11 @@ pillow==12.3.0
|
||||
# fastembed
|
||||
# pdf2image
|
||||
# python-pptx
|
||||
platformdirs==4.11.7
|
||||
platformdirs==4.11.8
|
||||
# via fastmcp-slim
|
||||
portalocker==3.2.0
|
||||
# via qdrant-client
|
||||
prance==26.7.19.0
|
||||
# via openapi3-parser
|
||||
praw==8.0.2
|
||||
praw==8.0.3
|
||||
# via docsgpt
|
||||
prawcore==4.0.0
|
||||
# via praw
|
||||
@@ -634,10 +626,10 @@ pydantic==2.13.5
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# mcp
|
||||
# mcp-types
|
||||
# openai
|
||||
# openapi-pydantic
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
# openapi3-parser
|
||||
# pydantic-settings
|
||||
# qdrant-client
|
||||
pydantic-core==2.46.5
|
||||
@@ -648,22 +640,19 @@ pydantic-settings==2.15.0
|
||||
# via
|
||||
# docsgpt
|
||||
# fastmcp-slim
|
||||
# mcp
|
||||
# openapi-schema-validator
|
||||
# openapi-spec-validator
|
||||
pygments==2.21.0
|
||||
# via
|
||||
# rich
|
||||
# rich-rst
|
||||
pyjwt==2.13.0
|
||||
pyjwt==2.14.0
|
||||
# via
|
||||
# mcp
|
||||
# msal
|
||||
pyparsing==3.3.2
|
||||
# via httplib2
|
||||
pypdf==6.15.0
|
||||
pypdf==6.18.1
|
||||
# via docsgpt
|
||||
pypdfium2==5.12.1
|
||||
pypdfium2==5.13.0
|
||||
# via docsgpt
|
||||
pyperclip==1.11.0
|
||||
# via fastmcp-slim
|
||||
@@ -715,10 +704,11 @@ pyyaml==6.0.3
|
||||
# fastmcp-slim
|
||||
# huggingface-hub
|
||||
# jsonschema-path
|
||||
# openapi3-parser
|
||||
# uvicorn
|
||||
qdrant-client==1.19.0
|
||||
# via docsgpt
|
||||
redis==7.4.0
|
||||
redis==8.1.0
|
||||
# via
|
||||
# celery-redbeat
|
||||
# docsgpt
|
||||
@@ -728,8 +718,8 @@ referencing==0.37.0
|
||||
# jsonschema
|
||||
# jsonschema-path
|
||||
# jsonschema-specifications
|
||||
# openapi-schema-validator
|
||||
regex==2026.9.3
|
||||
# openapi3-parser
|
||||
regex==2026.9.10
|
||||
# via tiktoken
|
||||
requests==2.34.2
|
||||
# via
|
||||
@@ -742,7 +732,6 @@ requests==2.34.2
|
||||
# gtts
|
||||
# msal
|
||||
# opentelemetry-exporter-otlp-proto-http
|
||||
# prance
|
||||
# prawcore
|
||||
# python-socketio
|
||||
# requests-file
|
||||
@@ -755,8 +744,6 @@ requests-oauthlib==2.0.0
|
||||
# via google-auth-oauthlib
|
||||
retry==0.9.2
|
||||
# via docsgpt
|
||||
rfc3339-validator==0.1.4
|
||||
# via openapi-schema-validator
|
||||
rich==15.0.0
|
||||
# via
|
||||
# cyclopts
|
||||
@@ -771,8 +758,6 @@ rpds-py==2026.6.3
|
||||
# referencing
|
||||
rsa==4.9.1
|
||||
# via python-jose
|
||||
ruamel-yaml==0.19.1
|
||||
# via prance
|
||||
s3transfer==0.19.2
|
||||
# via boto3
|
||||
secretstorage==3.5.0 ; sys_platform == 'linux'
|
||||
@@ -786,7 +771,6 @@ six==1.17.0
|
||||
# ecdsa
|
||||
# markdownify
|
||||
# python-dateutil
|
||||
# rfc3339-validator
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# anthropic
|
||||
@@ -810,22 +794,25 @@ tenacity==9.1.4
|
||||
# via
|
||||
# celery-redbeat
|
||||
# google-genai
|
||||
tiktoken==0.13.0
|
||||
tiktoken==0.14.0
|
||||
# via docsgpt
|
||||
tldextract==5.3.2
|
||||
# via docsgpt
|
||||
tokenizers==0.22.2
|
||||
tokenizers==0.23.2
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
toml==0.10.2
|
||||
# via daytona
|
||||
tqdm==4.67.3
|
||||
tqdm==4.70.1
|
||||
# via
|
||||
# docsgpt
|
||||
# fastembed
|
||||
# huggingface-hub
|
||||
# openai
|
||||
truststore==0.10.4 ; sys_platform != 'emscripten'
|
||||
# via
|
||||
# httpcore2
|
||||
# httpx2
|
||||
typer==0.26.8
|
||||
# via huggingface-hub
|
||||
typing-extensions==4.16.0
|
||||
@@ -848,8 +835,10 @@ typing-extensions==4.16.0
|
||||
# fastmcp-slim
|
||||
# google-genai
|
||||
# grpcio
|
||||
# httpx2
|
||||
# huggingface-hub
|
||||
# mcp
|
||||
# mcp-types
|
||||
# obstore
|
||||
# openai
|
||||
# opentelemetry-api
|
||||
@@ -875,7 +864,7 @@ typing-inspection==0.4.4
|
||||
# mcp
|
||||
# pydantic
|
||||
# pydantic-settings
|
||||
tzdata==2026.3
|
||||
tzdata==2026.4
|
||||
# via
|
||||
# kombu
|
||||
# pandas
|
||||
@@ -920,7 +909,7 @@ watchfiles==1.2.0
|
||||
# uvicorn
|
||||
wcwidth==0.8.3
|
||||
# via prompt-toolkit
|
||||
websocket-client==1.9.0
|
||||
websocket-client==1.9.2
|
||||
# via
|
||||
# docsgpt
|
||||
# praw
|
||||
@@ -938,7 +927,7 @@ werkzeug==3.1.8
|
||||
# flask-restx
|
||||
win32-setctime==1.2.0 ; sys_platform == 'win32'
|
||||
# via loguru
|
||||
wrapt==2.4.0
|
||||
wrapt==2.4.1
|
||||
# via
|
||||
# deprecated
|
||||
# opentelemetry-instrumentation
|
||||
|
||||
@@ -16,7 +16,7 @@ Three entry points:
|
||||
Resolves once, dials the IP literal, preserves the original hostname
|
||||
in the ``Host`` header and via SNI / cert verification for HTTPS.
|
||||
* :func:`pinned_httpx_client` — called at dispatch time when the caller
|
||||
hands an ``httpx.Client`` to a third-party SDK (e.g. the OpenAI
|
||||
hands an ``httpx2.Client`` to a third-party SDK (e.g. the OpenAI
|
||||
Python SDK via ``OpenAI(http_client=...)``). Same DNS-rebinding
|
||||
closure on the httpx transport layer.
|
||||
|
||||
@@ -35,7 +35,12 @@ import socket
|
||||
from typing import Any, Iterable
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
import httpx
|
||||
# httpx2 (the maintained fork of httpx, by its original author, published by
|
||||
# Pydantic at github.com/pydantic/httpx2) is what the OpenAI and Anthropic
|
||||
# SDKs run on; a client built on the old ``httpx`` is rejected at their
|
||||
# construction. This module uses it only for the pinned client below — its
|
||||
# own fetches go through ``requests``.
|
||||
import httpx2 as httpx
|
||||
import requests
|
||||
from requests.adapters import HTTPAdapter
|
||||
|
||||
@@ -507,7 +512,10 @@ class _PinnedHTTPSTransport(httpx.HTTPTransport):
|
||||
``httpcore`` feeds into ``start_tls``'s ``server_hostname``
|
||||
parameter. Without this, ``urllib3``-equivalent code would use
|
||||
the IP literal as SNI and cert verification would fail (the
|
||||
cert is for the original hostname, not the IP).
|
||||
cert is for the original hostname, not the IP). It must be a
|
||||
``str``: ``httpcore`` passes it through to
|
||||
``ssl.SSLContext.wrap_socket``, and the ``truststore`` backend
|
||||
httpx2 uses on macOS encodes it rather than accepting bytes.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
@@ -544,7 +552,7 @@ class _PinnedHTTPSTransport(httpx.HTTPTransport):
|
||||
# hostname even though TCP dials the IP literal.
|
||||
request.extensions = {
|
||||
**request.extensions,
|
||||
"sni_hostname": self._host.encode("ascii"),
|
||||
"sni_hostname": self._host,
|
||||
}
|
||||
request.url = request.url.copy_with(host=self._ip_netloc)
|
||||
return super().handle_request(request)
|
||||
|
||||
+21
-15
@@ -35,7 +35,7 @@ classifiers = [
|
||||
dependencies = [
|
||||
"a2wsgi>=1.10.10,<2",
|
||||
"alembic>=1.13,<2",
|
||||
"anthropic>=0.121.0,<0.122",
|
||||
"anthropic>=1.5.0,<2",
|
||||
"beautifulsoup4>=4.15.0,<5",
|
||||
"boto3>=1.43.67,<2",
|
||||
"cel-python>=0.5.0,<0.6",
|
||||
@@ -44,7 +44,7 @@ dependencies = [
|
||||
"croniter>=6.2.4,<7",
|
||||
"cryptography>=50.0.0,<51",
|
||||
"dataclasses-json>=0.6.7,<0.7",
|
||||
"daytona>=0.205.1,<0.206",
|
||||
"daytona>=0.211.2,<0.212",
|
||||
"ddgs>=8.0.0,<10",
|
||||
"defusedxml>=0.7.1,<0.8",
|
||||
"docx2txt>=0.9,<0.10",
|
||||
@@ -53,9 +53,9 @@ dependencies = [
|
||||
"fast-ebook>=0.2.0,<0.3",
|
||||
# Default document converter (DOC_PARSER_ENGINE=anydoc): a Rust extension
|
||||
# with no model downloads. The docling engine is the `docling` extra.
|
||||
"firecrawl-anydoc>=0.2.3,<0.3",
|
||||
"firecrawl-anydoc>=0.2.4,<0.3",
|
||||
"fastembed>=0.8.0,<0.9",
|
||||
"fastmcp>=3.4.6,<4",
|
||||
"fastmcp>=4.0.3,<5",
|
||||
"Flask>=3.1.3,<4",
|
||||
"flask-restx>=1.3.2,<2",
|
||||
"google-api-python-client>=2.198.0,<3",
|
||||
@@ -63,6 +63,9 @@ dependencies = [
|
||||
"google-genai>=2.17.0,<3",
|
||||
"gTTS>=2.5.4,<3",
|
||||
"gunicorn>=26.0.0,<27",
|
||||
# Imported directly by the BYOM DNS-pinning transport and the LLM
|
||||
# stream-retry error tuple; it is what anthropic and openai run on.
|
||||
"httpx2>=2.7.0,<3",
|
||||
"jinja2>=3.1.6,<4",
|
||||
"kombu>=5.6.2,<6",
|
||||
"markdownify>=1.2.3,<2",
|
||||
@@ -71,8 +74,8 @@ dependencies = [
|
||||
"numpy>=2.5.1,<3",
|
||||
# fastembed's runtime: local embeddings execute on it.
|
||||
"onnxruntime>=1.28.0,<2",
|
||||
"openai>=2.53.0,<3",
|
||||
"openapi3-parser>=1.1.22,<2",
|
||||
"openai>=3.13.0,<4",
|
||||
"openapi3-parser>=2.0.0,<3",
|
||||
# pandas reads .xlsx through openpyxl but does not depend on it.
|
||||
"openpyxl>=3.1.5,<4",
|
||||
"opentelemetry-distro>=0.50b0,<1",
|
||||
@@ -101,14 +104,14 @@ dependencies = [
|
||||
"python-pptx>=1.0.2,<2",
|
||||
"PyYAML>=6.0.3,<7",
|
||||
"qdrant-client>=1.19.0,<2",
|
||||
"redis>=7.4.0,<8",
|
||||
"redis>=8.1.0,<9",
|
||||
"requests>=2.34.2,<3",
|
||||
"retry>=0.9.2,<0.10",
|
||||
"sqlalchemy>=2.0,<3",
|
||||
"starlette>=1.0,<2",
|
||||
"tiktoken>=0.13.0,<0.14",
|
||||
"tiktoken>=0.14.0,<0.15",
|
||||
"tldextract>=5.3.2,<6",
|
||||
"tokenizers>=0.22.2,<0.23",
|
||||
"tokenizers>=0.23.2,<0.24",
|
||||
"tqdm>=4.67.3,<5",
|
||||
"uvicorn[standard]>=0.30,<1",
|
||||
"uvicorn-worker>=0.4,<1",
|
||||
@@ -129,11 +132,14 @@ docling = [
|
||||
"docling>=2.119.0,<3",
|
||||
"rapidocr>=3.9.2,<4",
|
||||
# docling's model stack. Declared here (not left transitive) so the floors
|
||||
# hold and the CPU index source below applies. transformers is capped by
|
||||
# docling-core at <5.9: 5.9+ breaks the PDF layout model on Apple Silicon.
|
||||
"torch>=2.11.0,<3",
|
||||
"torchvision>=0.26.0,<0.27",
|
||||
"transformers>=5.8.1,<5.9",
|
||||
# hold and the CPU index source below applies. transformers was held at
|
||||
# <5.9 because 5.9 broke the PDF layout model on Apple Silicon; 5.17 does
|
||||
# not — on a four-document benchmark (papers, a 30-page table corpus) the
|
||||
# converted Markdown is byte-identical on three and differs on the fourth
|
||||
# only by one dropped `<!-- image -->` placeholder.
|
||||
"torch>=2.14.0,<3",
|
||||
"torchvision>=0.29.0,<0.30",
|
||||
"transformers>=5.17.0,<6",
|
||||
]
|
||||
# VECTOR_STORE=milvus. milvus-lite (the embedded server) pulls pyarrow.
|
||||
milvus = [
|
||||
@@ -162,7 +168,7 @@ dev = [
|
||||
"pytest-postgresql>=6.0.0",
|
||||
"jupyter-client>=8.0",
|
||||
"python-docx>=1.1",
|
||||
"reportlab>=4.0,<5",
|
||||
"reportlab>=5.0.1,<6",
|
||||
"ruff",
|
||||
]
|
||||
|
||||
|
||||
@@ -416,12 +416,15 @@ class TestSecurityDispatchSSRFGuard:
|
||||
def test_dispatch_injects_pinned_http_client_for_user_model(
|
||||
self, pg_conn
|
||||
):
|
||||
"""LLMCreator must build a DNS-rebinding-safe httpx.Client and
|
||||
"""LLMCreator must build a DNS-rebinding-safe httpx2.Client and
|
||||
forward it to the OpenAI SDK so the SDK's request-time DNS
|
||||
lookup cannot escape the create-time SSRF guard. ``validate_
|
||||
user_base_url`` alone is TOCTOU and does not close the
|
||||
rebinding window — the pinned client is what does."""
|
||||
import httpx
|
||||
rebinding window — the pinned client is what does. The client
|
||||
must be httpx2's: the OpenAI SDK rejects an old-httpx client
|
||||
at construction, which would take the guard offline.
|
||||
"""
|
||||
import httpx2
|
||||
|
||||
from docsgpt.core.model_settings import (
|
||||
AvailableModel,
|
||||
@@ -474,7 +477,7 @@ class TestSecurityDispatchSSRFGuard:
|
||||
|
||||
client = captured["http_client"]
|
||||
try:
|
||||
assert isinstance(client, httpx.Client), (
|
||||
assert isinstance(client, httpx2.Client), (
|
||||
"http_client must be set for user-source models so the "
|
||||
"OpenAI SDK doesn't re-resolve DNS at request time"
|
||||
)
|
||||
|
||||
@@ -585,6 +585,10 @@ class TestRawGen:
|
||||
assert _sent(llm)["max_tokens"] == 1234
|
||||
|
||||
def test_sampling_params_forwarded(self, llm):
|
||||
"""anthropic 1.x dropped the sampling params from
|
||||
``messages.create``'s signature (passing one is a TypeError), so they
|
||||
ride in ``extra_body``, which the SDK merges into the request JSON
|
||||
as-is. The wire request is unchanged."""
|
||||
llm._raw_gen(
|
||||
llm,
|
||||
model="m",
|
||||
@@ -592,8 +596,10 @@ class TestRawGen:
|
||||
temperature=0.3,
|
||||
top_p=0.9,
|
||||
)
|
||||
assert _sent(llm)["temperature"] == 0.3
|
||||
assert _sent(llm)["top_p"] == 0.9
|
||||
sent = _sent(llm)
|
||||
assert sent["extra_body"] == {"temperature": 0.3, "top_p": 0.9}
|
||||
assert "temperature" not in sent
|
||||
assert "top_p" not in sent
|
||||
|
||||
def test_openai_only_params_not_forwarded(self, llm):
|
||||
"""OpenAI-shaped request params reach every provider via
|
||||
|
||||
@@ -10,6 +10,7 @@ import types
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import httpx
|
||||
import httpx2
|
||||
import pytest
|
||||
|
||||
from docsgpt.llm.anthropic import AnthropicLLM
|
||||
@@ -362,6 +363,37 @@ class TestStreamingFallback:
|
||||
assert primary.stream_calls == 2
|
||||
assert not backup.gen_stream_called
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"error",
|
||||
[httpx2.RemoteProtocolError, httpx.RemoteProtocolError],
|
||||
ids=["httpx2", "httpx"],
|
||||
)
|
||||
def test_stream_transport_error_retries_on_either_http_stack(
|
||||
self, patch_model_utils, error
|
||||
):
|
||||
"""The providers are split across two HTTP stacks whose exception
|
||||
classes are unrelated types: openai, anthropic and the MCP client
|
||||
raise from httpx2, google-genai and elevenlabs still from httpx.
|
||||
Naming one stack makes the retry silently stop firing for the other
|
||||
half.
|
||||
"""
|
||||
backup = FakeLLM(stream_chunks=["fallback"])
|
||||
patch_model_utils(
|
||||
get_provider=lambda m, **_kwargs: "openai",
|
||||
get_api_key=lambda p: "k",
|
||||
create_llm=lambda type, **kw: backup,
|
||||
)
|
||||
primary = FakeLLM(
|
||||
stream_chunks=["ok1", "ok2"],
|
||||
backup_models=["backup-model"],
|
||||
)
|
||||
primary.fail_schedule = [0, None]
|
||||
primary.error_schedule = [error, RuntimeError]
|
||||
|
||||
assert list(primary.gen_stream(**CALL_ARGS)) == ["ok1", "ok2"]
|
||||
assert primary.stream_calls == 2
|
||||
assert not backup.gen_stream_called
|
||||
|
||||
def test_stream_transport_error_retry_then_fails_uses_fallback(
|
||||
self, patch_model_utils
|
||||
):
|
||||
|
||||
@@ -79,11 +79,15 @@ def _fake_anydoc(monkeypatch, to_markdown):
|
||||
class UnsupportedError(ConvertError):
|
||||
pass
|
||||
|
||||
class NeedsOcrError(ConvertError):
|
||||
pass
|
||||
|
||||
class ResourceLimitError(ConvertError):
|
||||
pass
|
||||
|
||||
fake.ConvertError = ConvertError
|
||||
fake.UnsupportedError = UnsupportedError
|
||||
fake.NeedsOcrError = NeedsOcrError
|
||||
fake.ResourceLimitError = ResourceLimitError
|
||||
fake.to_markdown = to_markdown
|
||||
monkeypatch.setitem(sys.modules, "anydoc", fake)
|
||||
@@ -327,6 +331,22 @@ CID_PDF = FIXTURES / "nda_en_zh_cid_font.pdf"
|
||||
# Long enough to clear the near-empty guard a trust-check re-parse must pass.
|
||||
_REROUTE_TEXT = "docling reroute text, long enough to clear the near-empty reroute guard"
|
||||
|
||||
# What anydoc's CID-font silent drop looked like: the English column extracted,
|
||||
# the Chinese one gone. anydoc 0.2.4 refuses this PDF outright
|
||||
# (``test_cid_font_pdf_is_refused_as_needing_ocr``), so the trust check is
|
||||
# exercised against CID_PDF's real bytes with the dropped output stubbed in —
|
||||
# the check's own inputs, independent of which anydoc is installed.
|
||||
_CID_DROPPED_TEXT = (
|
||||
"# NON-DISCLOSURE AGREEMENT\n\nThis Agreement is entered into between the "
|
||||
"parties on the date set out below. Confidential Information shall not be "
|
||||
"disclosed to any third party."
|
||||
)
|
||||
|
||||
|
||||
def _anydoc_dropping_cjk(monkeypatch):
|
||||
"""Stub anydoc into the silent CID-font drop the trust check exists for."""
|
||||
return _fake_anydoc(monkeypatch, lambda path: _CID_DROPPED_TEXT)
|
||||
|
||||
|
||||
class _FakeDoclingFallback:
|
||||
"""Registered as a DoclingParser subclass so ``_is_docling_backed`` is True."""
|
||||
@@ -348,7 +368,20 @@ class _FakeDoclingFallback:
|
||||
return _Inner()
|
||||
|
||||
|
||||
def test_trust_flagged_pdf_reroutes_to_docling_fallback():
|
||||
def test_cid_font_pdf_is_refused_as_needing_ocr():
|
||||
"""anydoc 0.2.4 detects the unmappable CID font and raises NeedsOcrError
|
||||
rather than dropping the Chinese column silently; that must route as
|
||||
"needs OCR", which is what makes the scan guard fire."""
|
||||
fallback = _RecordingFallback(result=" ")
|
||||
fallback.ocr_enabled = False
|
||||
parser = AnydocParser(fallback_parser=fallback)
|
||||
|
||||
with pytest.raises(DocumentParseError, match="OCR_ENABLED=true"):
|
||||
parser.parse_file(CID_PDF)
|
||||
|
||||
|
||||
def test_trust_flagged_pdf_reroutes_to_docling_fallback(monkeypatch):
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
fallback = _FakeDoclingFallback()
|
||||
parser = AnydocParser(fallback_parser=fallback)
|
||||
|
||||
@@ -360,12 +393,13 @@ def test_trust_flagged_pdf_reroutes_to_docling_fallback():
|
||||
assert parser.get_file_metadata(CID_PDF) == {} # rerouted, nothing to warn about
|
||||
|
||||
|
||||
def test_trust_flagged_pdf_without_docling_keeps_output_and_warns():
|
||||
def test_trust_flagged_pdf_without_docling_keeps_output_and_warns(monkeypatch):
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
parser = AnydocParser(fallback_parser=_RecordingFallback()) # not docling-backed
|
||||
|
||||
out = parser.parse_file(CID_PDF)
|
||||
|
||||
assert "NON-DISCLOSURE" in out.upper() or len(out) > 50 # anydoc's own output kept
|
||||
assert "NON-DISCLOSURE" in out.upper() # anydoc's own output kept
|
||||
meta = parser.get_file_metadata(CID_PDF)
|
||||
assert "parse_warnings" in meta
|
||||
assert any("ToUnicode" in w for w in meta["parse_warnings"])
|
||||
@@ -377,6 +411,7 @@ def test_trust_check_disabled_stamps_nothing(monkeypatch):
|
||||
from docsgpt.parser.file import anydoc_parser as ap
|
||||
|
||||
monkeypatch.setattr(ap.settings, "PDF_TRUST_CHECK", False)
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
parser = AnydocParser()
|
||||
|
||||
parser.parse_file(CID_PDF)
|
||||
@@ -384,7 +419,8 @@ def test_trust_check_disabled_stamps_nothing(monkeypatch):
|
||||
assert parser.get_file_metadata(CID_PDF) == {}
|
||||
|
||||
|
||||
def test_trust_reroute_failure_keeps_anydoc_output():
|
||||
def test_trust_reroute_failure_keeps_anydoc_output(monkeypatch):
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
fallback = _FakeDoclingFallback()
|
||||
|
||||
def _boom(file, errors="ignore"):
|
||||
@@ -400,9 +436,10 @@ def test_trust_reroute_failure_keeps_anydoc_output():
|
||||
assert parser.last_engine == "anydoc"
|
||||
|
||||
|
||||
def test_trust_reroute_near_empty_keeps_anydoc_output():
|
||||
def test_trust_reroute_near_empty_keeps_anydoc_output(monkeypatch):
|
||||
"""A docling pipeline dropout ('' / '<!-- image -->') returns without
|
||||
raising; adopting it would swap anydoc's real text for an empty document."""
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
fallback = _FakeDoclingFallback()
|
||||
fallback.parse_file = lambda file, errors="ignore": "<!-- image -->"
|
||||
parser = AnydocParser(fallback_parser=fallback)
|
||||
@@ -414,7 +451,8 @@ def test_trust_reroute_near_empty_keeps_anydoc_output():
|
||||
assert parser.last_engine == "anydoc"
|
||||
|
||||
|
||||
def test_warnings_reset_between_files(tmp_path):
|
||||
def test_warnings_reset_between_files(monkeypatch, tmp_path):
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
parser = AnydocParser()
|
||||
parser.parse_file(CID_PDF)
|
||||
assert parser.get_file_metadata(CID_PDF) != {}
|
||||
@@ -474,6 +512,7 @@ def test_tableize_never_touches_docling_reroute(monkeypatch):
|
||||
from docsgpt.parser.file import anydoc_parser as ap
|
||||
|
||||
monkeypatch.setattr(ap.settings, "ANYDOC_TABLEIZE", True)
|
||||
_anydoc_dropping_cjk(monkeypatch)
|
||||
fallback = _FakeDoclingFallback()
|
||||
parser = AnydocParser(fallback_parser=fallback)
|
||||
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
_HTTP_METHODS = ("get", "put", "post", "delete", "options", "head", "patch", "trace")
|
||||
|
||||
|
||||
def _path_item(description=None, parameters=None, **operations):
|
||||
"""A stand-in for openapi-parser 2.x's PathItem: one field per HTTP method,
|
||||
``None`` where the spec defines no operation."""
|
||||
item = MagicMock()
|
||||
item.description = description
|
||||
item.parameters = parameters
|
||||
for method in _HTTP_METHODS:
|
||||
setattr(item, method, operations.get(method))
|
||||
return item
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestOpenAPI3ParserImportFallback:
|
||||
@@ -31,14 +44,12 @@ class TestOpenAPI3ParserImportFallback:
|
||||
assert len(urls) == 2
|
||||
|
||||
def test_get_info_from_paths_empty(self):
|
||||
"""Cover path with no operations."""
|
||||
"""Cover a path item that defines no methods."""
|
||||
with patch("docsgpt.parser.file.openapi3_parser.parse"):
|
||||
from docsgpt.parser.file.openapi3_parser import OpenAPI3Parser
|
||||
|
||||
parser = OpenAPI3Parser()
|
||||
mock_path = MagicMock()
|
||||
mock_path.operations = []
|
||||
result = parser.get_info_from_paths(mock_path)
|
||||
result = parser.get_info_from_paths(_path_item())
|
||||
assert result == ""
|
||||
|
||||
def test_parse_file_writes_results(self, tmp_path):
|
||||
@@ -49,15 +60,9 @@ class TestOpenAPI3ParserImportFallback:
|
||||
mock_server = MagicMock()
|
||||
mock_server.url = "https://api.example.com"
|
||||
|
||||
mock_path = MagicMock()
|
||||
mock_path.url = "/users"
|
||||
mock_path.description = "Get users"
|
||||
mock_path.parameters = []
|
||||
mock_path.operations = []
|
||||
|
||||
mock_data = MagicMock()
|
||||
mock_data.servers = [mock_server]
|
||||
mock_data.paths = [mock_path]
|
||||
mock_data.paths = {"/users": _path_item(description="Get users")}
|
||||
mock_parse.return_value = mock_data
|
||||
|
||||
parser = OpenAPI3Parser()
|
||||
|
||||
@@ -537,7 +537,7 @@ def _capture_httpx_handle_request(monkeypatch):
|
||||
opening a real socket.
|
||||
"""
|
||||
|
||||
import httpx
|
||||
import httpx2
|
||||
|
||||
captured: dict = {}
|
||||
|
||||
@@ -545,10 +545,10 @@ def _capture_httpx_handle_request(monkeypatch):
|
||||
captured["url"] = request.url
|
||||
captured["sni"] = request.extensions.get("sni_hostname")
|
||||
captured["host_header"] = request.headers.get("host")
|
||||
return httpx.Response(200, content=b"ok")
|
||||
return httpx2.Response(200, content=b"ok")
|
||||
|
||||
monkeypatch.setattr(
|
||||
"httpx.HTTPTransport.handle_request", fake_handle
|
||||
"httpx2.HTTPTransport.handle_request", fake_handle
|
||||
)
|
||||
return captured
|
||||
|
||||
@@ -610,7 +610,14 @@ def test_pinned_httpx_transport_rewrites_url_to_validated_ip(monkeypatch):
|
||||
def test_pinned_httpx_transport_sets_sni_for_original_hostname(monkeypatch):
|
||||
"""TLS SNI / cert verification must use the original hostname; the
|
||||
transport sets it via the ``sni_hostname`` extension that
|
||||
httpcore forwards to ``start_tls``'s ``server_hostname``."""
|
||||
httpcore forwards to ``start_tls``'s ``server_hostname``.
|
||||
|
||||
The value must be a ``str``, not ascii bytes: httpcore passes it
|
||||
straight to ``ssl.SSLContext.wrap_socket``, and the ``truststore``
|
||||
backend httpx2 uses for the default system trust store encodes it
|
||||
rather than accepting bytes — so bytes fail every real handshake
|
||||
while passing any test that stubs the transport out.
|
||||
"""
|
||||
|
||||
captured = _capture_httpx_handle_request(monkeypatch)
|
||||
|
||||
@@ -623,7 +630,8 @@ def test_pinned_httpx_transport_sets_sni_for_original_hostname(monkeypatch):
|
||||
finally:
|
||||
client.close()
|
||||
|
||||
assert captured["sni"] == b"api.example.com"
|
||||
assert captured["sni"] == "api.example.com"
|
||||
assert isinstance(captured["sni"], str)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@@ -712,7 +720,7 @@ def test_pinned_httpx_transport_refuses_unexpected_host(monkeypatch):
|
||||
transport refuses rather than silently dialing the validated IP
|
||||
with a different host's credentials."""
|
||||
|
||||
import httpx
|
||||
import httpx2
|
||||
|
||||
with mock.patch(
|
||||
"socket.getaddrinfo", return_value=_addrinfo("104.18.6.192")
|
||||
@@ -721,7 +729,7 @@ def test_pinned_httpx_transport_refuses_unexpected_host(monkeypatch):
|
||||
try:
|
||||
with pytest.raises(UnsafeUserUrlError, match="refused request"):
|
||||
client.get("https://other.example.com/v1/test")
|
||||
except httpx.RequestError:
|
||||
except httpx2.RequestError:
|
||||
# Some httpx versions may wrap the transport error; accept
|
||||
# either path so long as the request didn't succeed.
|
||||
pass
|
||||
|
||||
@@ -26,13 +26,25 @@ def test_get_base_urls(urls, expected_base_urls):
|
||||
def test_get_info_from_paths():
|
||||
file_path = "tests/test_openapi3.yaml"
|
||||
data = parse(file_path)
|
||||
path = data.paths[1]
|
||||
path_item = data.paths["/pets/{petId}"]
|
||||
assert (
|
||||
OpenAPI3Parser().get_info_from_paths(path)
|
||||
OpenAPI3Parser().get_info_from_paths(path_item)
|
||||
== "\nget=Expected response to a valid request"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_get_operations_follows_spec_method_order():
|
||||
"""openapi-parser 2.x exposes one field per method instead of an
|
||||
``operations`` list; the rendered order stays the spec's."""
|
||||
data = parse("tests/test_openapi3.yaml")
|
||||
path_item = data.paths["/pets"]
|
||||
assert [method for method, _ in OpenAPI3Parser().get_operations(path_item)] == [
|
||||
"get",
|
||||
"post",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_parse_file():
|
||||
file_path = "tests/test_openapi3.yaml"
|
||||
|
||||
Reference in new issue
Block a user