Merge pull request #128 from djlongy/fix/markdown-upload-content-type

fix: send Markdown uploads as text/markdown
This commit is contained in:
Tim Baek 2026-10-10 10:13:28 -05:00 • committed by GitHub
commit cbe5102ba2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View file

@ -3,11 +3,24 @@
from __future__ import annotations
import json
import mimetypes
import os
from typing import Any
import httpx
# Python 3.11 has no .md entry and slim images ship no /etc/mime.types, so a
# Markdown upload went out as application/octet-stream and Open WebUI handed it
# to its document extraction engine (Docling, Tika) instead of reading it as text.
_TEXT_TYPES = {".md": "text/markdown", ".markdown": "text/markdown"}
def _content_type(filename: str) -> str:
ext = os.path.splitext(filename)[1].lower()
return mimetypes.guess_type(filename)[0] or _TEXT_TYPES.get(ext, "application/octet-stream")
class OikbClient:
"""Stateless HTTP client for the Open WebUI KB API.
@ -84,7 +97,7 @@ class OikbClient:
resp = self._http.post(
"/files/",
files={"file": (filename, file_content)},
files={"file": (filename, file_content, _content_type(filename))},
data={"metadata": json.dumps(metadata)},
)
resp.raise_for_status()

View file

@ -1,9 +1,12 @@
import mimetypes
from unittest.mock import AsyncMock, Mock
import httpx
import pytest
import respx
from click.testing import CliRunner
from oikb.client import OikbClient
from oikb.connectors import BaseConnector, ManifestEntry
from oikb.kb_sync import group_entries_by_kb, run_entries_sync
from oikb.sync import SyncCancelled, SyncResult
@ -145,3 +148,11 @@ def test_upload_error_includes_server_detail():
client.upload_file.side_effect = httpx.HTTPStatusError("Bad Request", request=response.request, response=response)
result = run_entries_sync(client, [{"source": "one", "kb-id": "kb"}], resolve_connector=lambda *a, **kw: Source({"a.txt": b"a"}), quiet=True)
assert "extraction failed" in result.errors[0]
@respx.mock
def test_upload_sends_markdown_as_text_without_system_mime_types(monkeypatch):
monkeypatch.setattr(mimetypes, "guess_type", lambda *a, **kw: (None, None))
route = respx.post("https://webui.example/api/v1/files/").mock(return_value=httpx.Response(200, json={"id": "f"}))
OikbClient("https://webui.example", "token").upload_file(b"| a |\n| - |\n", "doc.md", "kb", "hash")
assert b"Content-Type: text/markdown" in route.calls.last.request.content