feat: enhance HAR provider, image handling, markdown upload & cache

- **g4f/Provider/har/__init__.py**
  - `get_models`/`create_async`: iterate over `(domain, harFile)` and filter with `domain in request_url`
  - `read_har_files` now yields `(domain, har_data)`; fixes file variable shadowing and uses `json.load`
  - remove stray `print`, add type hint for `find_str`, replace manual loops with `yield from`
  - small whitespace clean-up

- **g4f/Provider/needs_auth/Grok.py**
  - `ImagePreview` now passes `auth_result.cookies` and `auth_result.headers`

- **g4f/Provider/needs_auth/OpenaiChat.py**
  - add `Union` import; rename/refactor `get_generated_images` → `get_generated_image`
  - support `file-service://` and `sediment://` pointers; choose correct download URL
  - return `ImagePreview` or `ImageResponse` accordingly and stream each image part
  - propagate 422 errors, update prompt assignment and image handling paths

- **g4f/client/__init__.py**
  - drop unused `ignore_working` parameter in sync/async `Completions`
  - normalise `media` argument: accept single tuple, infer filename when missing, fix index loop
  - `Images.create_variation` updated to use the new media logic

- **g4f/gui/server/api.py**
  - expose `latest_version_cached` via `?cache=` query parameter

- **g4f/gui/server/backend_api.py**
  - optional Markdown extraction via `MarkItDown`; save rendered text as `<file>.md`
  - upload flow rewrites: copy to temp file, move to bucket/media dir, clean temp, store filenames
  - introduce `has_markitdown` guard and improved logging/exception handling

- **g4f/tools/files.py**
  - remove trailing spaces in HAR code-block header string

- **g4f/version.py**
  - add `latest_version_cached` `@cached_property` for memoised version lookup
This commit is contained in:
hlohaus 2025-04-24 15:18:21 +02:00
parent db47d71f4c
commit 8f63f656a2
8 changed files with 95 additions and 36 deletions

View file

@ -16,6 +16,12 @@ from pathlib import Path
from urllib.parse import quote_plus
from hashlib import sha256
try:
from markitdown import MarkItDown
has_markitdown = True
except ImportError:
has_markitdown = False
from ...client.service import convert_to_provider
from ...providers.asyncio import to_sync_generator
from ...providers.response import FinishReason
@ -299,8 +305,24 @@ class Backend_Api(Api):
filenames = []
media = []
for file in request.files.getlist('files'):
try:
filename = secure_filename(file.filename)
# Copy the file to a temporary location
filename = secure_filename(file.filename)
copyfile = tempfile.NamedTemporaryFile(suffix=filename, delete=False)
shutil.copyfileobj(file.stream, copyfile)
copyfile.close()
file.stream.close()
result = None
if has_markitdown:
try:
md = MarkItDown()
result = md.convert(copyfile.name).text_content
with open(os.path.join(bucket_dir, f"{filename}.md"), 'w') as f:
f.write(f"{result.text_content}\n")
filenames.append(f"{filename}.md")
except Exception as e:
logger.exception(e)
if not result:
if is_allowed_extension(filename):
os.makedirs(media_dir, exist_ok=True)
newfile = os.path.join(media_dir, filename)
@ -309,11 +331,10 @@ class Backend_Api(Api):
newfile = os.path.join(bucket_dir, filename)
filenames.append(filename)
else:
os.remove(copyfile.name)
continue
with open(newfile, 'wb') as f:
shutil.copyfileobj(file.stream, f)
finally:
file.stream.close()
shutil.copyfile(copyfile.name, newfile)
os.remove(copyfile.name)
with open(os.path.join(bucket_dir, "files.txt"), 'w') as f:
[f.write(f"{filename}\n") for filename in filenames]
return {"bucket_id": bucket_id, "files": filenames, "media": media}