XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

Fix go build

860489e7
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

5 个文件 +68 -72
Modified g4f-go/fetch-python.sh +58 -58
@@ -106,66 +106,66 @@ do_platform() {
106 106 *) echo " WARNING: no wheel tag for $name; runtime will need network on first run" >&2; tag="" ;;
107 107 esac
108 108 mkdir -p "$dir/wheels"
109 if [ -n "$tag" ]; then
110 # Windows pip can't read process-substitution FDs from its subprocess, so
111 # write the version floors to a real file once per platform.
112 local floors="$dir/wheels.floors"
113 printf '%s\n' "$WHEEL_FLOORS" > "$floors"
114 # Full dependency resolution (no --no-deps) so the runtime's offline
115 # `pip install g4f` finds every transitive wheel it needs.
116 # brotli is optional in g4f and has no cp314 wheel for win_arm64;
117 # fall back to fetching everything else if a single dep is unavailable.
118 if ! python3 -m pip download \
119 -r "$G4F_SRC/requirements-min.txt" \
120 --constraint "$floors" \
121 --only-binary=:all: \
122 --python-version "$PYVER" --implementation cp --abi "cp$(echo "$PYVER" | tr -d '.')" \
123 --platform "$tag" \
124 -d "$dir/wheels" -q 2>"$dir/pip.err"; then
125 echo " WARNING: full wheel set for $name not available; retrying without brotli (optional dep)" >&2
126 grep -v '^brotli$' "$G4F_SRC/requirements-min.txt" > "$dir/req-nobrotli.txt"
127 python3 -m pip download \
128 -r "$dir/req-nobrotli.txt" \
129 --constraint "$floors" \
130 --only-binary=:all: \
131 --python-version "$PYVER" --implementation cp --abi "cp$(echo "$PYVER" | tr -d '.')" \
132 --platform "$tag" \
133 -d "$dir/wheels" -q 2>>"$dir/pip.err" || {
134 echo " WARNING: wheel download for $name failed; runtime will need network on first run" >&2
135 }
136 fi
137 # Belt-and-braces: drop any wheel whose Requires-Python metadata excludes
138 # our interpreter. The --constraint above prevents this at resolve time;
139 # this catches stale wheels (e.g. copied in from wheels-cache) and covers
140 # ancient pure-python releases like aiohttp 0.13.1.
141 python3 - "$dir/wheels" "$PYVER" <<'PY' || true
142 import glob, os, sys, zipfile
143 from packaging.specifiers import SpecifierSet
144 from packaging.version import Version
145 want_v = Version(sys.argv[2])
146 for whl in glob.glob(os.path.join(sys.argv[1], "*.whl")):
147 try:
148 with zipfile.ZipFile(whl) as z:
149 meta = next((n for n in z.namelist() if n.endswith(".dist-info/METADATA")), None)
150 if not meta:
151 continue
152 txt = z.read(meta).decode("utf-8", "replace")
153 rp = next((l.split(":", 1)[1].strip() for l in txt.splitlines()
154 if l.lower().startswith("requires-python:")), None)
155 if rp and not SpecifierSet(rp).contains(want_v):
156 print(f" removing {os.path.basename(whl)} (Requires-Python {rp} excludes {sys.argv[2]})")
157 os.remove(whl)
158 except Exception as e:
159 print(f" skip check {os.path.basename(whl)}: {e}")
160 PY
161 fi
109 # if [ -n "$tag" ]; then
110 # # Windows pip can't read process-substitution FDs from its subprocess, so
111 # # write the version floors to a real file once per platform.
112 # local floors="$dir/wheels.floors"
113 # printf '%s\n' "$WHEEL_FLOORS" > "$floors"
114 # # Full dependency resolution (no --no-deps) so the runtime's offline
115 # # `pip install g4f` finds every transitive wheel it needs.
116 # # brotli is optional in g4f and has no cp314 wheel for win_arm64;
117 # # fall back to fetching everything else if a single dep is unavailable.
118 # if ! python3 -m pip download \
119 # -r "$G4F_SRC/requirements-min.txt" \
120 # --constraint "$floors" \
121 # --only-binary=:all: \
122 # --python-version "$PYVER" --implementation cp --abi "cp$(echo "$PYVER" | tr -d '.')" \
123 # --platform "$tag" \
124 # -d "$dir/wheels" -q 2>"$dir/pip.err"; then
125 # echo " WARNING: full wheel set for $name not available; retrying without brotli (optional dep)" >&2
126 # grep -v '^brotli$' "$G4F_SRC/requirements-min.txt" > "$dir/req-nobrotli.txt"
127 # python3 -m pip download \
128 # -r "$dir/req-nobrotli.txt" \
129 # --constraint "$floors" \
130 # --only-binary=:all: \
131 # --python-version "$PYVER" --implementation cp --abi "cp$(echo "$PYVER" | tr -d '.')" \
132 # --platform "$tag" \
133 # -d "$dir/wheels" -q 2>>"$dir/pip.err" || {
134 # echo " WARNING: wheel download for $name failed; runtime will need network on first run" >&2
135 # }
136 # fi
137 # # Belt-and-braces: drop any wheel whose Requires-Python metadata excludes
138 # # our interpreter. The --constraint above prevents this at resolve time;
139 # # this catches stale wheels (e.g. copied in from wheels-cache) and covers
140 # # ancient pure-python releases like aiohttp 0.13.1.
141 # python3 - "$dir/wheels" "$PYVER" <<'PY' || true
142 # import glob, os, sys, zipfile
143 # from packaging.specifiers import SpecifierSet
144 # from packaging.version import Version
145 # want_v = Version(sys.argv[2])
146 # for whl in glob.glob(os.path.join(sys.argv[1], "*.whl")):
147 # try:
148 # with zipfile.ZipFile(whl) as z:
149 # meta = next((n for n in z.namelist() if n.endswith(".dist-info/METADATA")), None)
150 # if not meta:
151 # continue
152 # txt = z.read(meta).decode("utf-8", "replace")
153 # rp = next((l.split(":", 1)[1].strip() for l in txt.splitlines()
154 # if l.lower().startswith("requires-python:")), None)
155 # if rp and not SpecifierSet(rp).contains(want_v):
156 # print(f" removing {os.path.basename(whl)} (Requires-Python {rp} excludes {sys.argv[2]})")
157 # os.remove(whl)
158 # except Exception as e:
159 # print(f" skip check {os.path.basename(whl)}: {e}")
160 # PY
161 # fi
162 162
163 163 # 3) Merge g4f package + wheels so the interpreter is self-contained.
164 rsync -a --exclude='.git' --exclude='g4f-go' --exclude='g4f.dev' --exclude='g4f.egg-info' \
165 "$G4F_SRC/g4f" "$dir/python-home/g4f"
166 rsync -a --exclude='.git' --exclude='g4f-go' --exclude='g4f.dev' --exclude='g4f.egg-info' \
167 "$G4F_SRC/requirements-min.txt" "$dir/python-home/requirements-min.txt"
168 cp -n "$WORK/wheels-cache/"*.whl "$dir/wheels/" 2>/dev/null || true
164 # rsync -a --exclude='.git' --exclude='g4f-go' --exclude='g4f.dev' --exclude='g4f.egg-info' \
165 # "$G4F_SRC/g4f" "$dir/python-home/g4f"
166 # rsync -a --exclude='.git' --exclude='g4f-go' --exclude='g4f.dev' --exclude='g4f.egg-info' \
167 # "$G4F_SRC/requirements-min.txt" "$dir/python-home/requirements-min.txt"
168 # cp -n "$WORK/wheels-cache/"*.whl "$dir/wheels/" 2>/dev/null || true
169 169
170 170 # 4) Pre-stamp install so first run is instant.
171 171 mkdir -p "$dir/.g4f-runtime"
Modified g4f-go/process.go +1 -5
@@ -132,11 +132,7 @@ func extractZip(r io.ReaderAt, size int64, dest string) error {
132 132 func pythonExecutable(binDir string) string {
133 133 home := filepath.Join(binDir, "python-home")
134 134 if runtime.GOOS == "windows" {
135 exe := filepath.Join(home, "python.exe")
136 if fi, err := os.Stat(exe); err == nil && !fi.IsDir() {
137 return exe
138 }
139 return filepath.Join(binDir, "python.exe")
135 return filepath.Join(home, "python.exe")
140 136 }
141 137 exe := filepath.Join(home, "bin", "python")
142 138 if fi, err := os.Stat(exe); err == nil && !fi.IsDir() {
Modified g4f-go/runtime.go +2 -4
@@ -160,8 +160,8 @@ func installG4F(binDir, exe string, start time.Time) error {
160 160 fmt.Printf("Installing gpt4free into the embedded Python runtime...\n")
161 161 code, err := runPython(noSignalCtx(), exe, []string{
162 162 "-m", "pip", "install",
163 "--no-input", "--no-index", "--find-links", "wheels",
164 "--no-cache-dir", "g4f",
163 "--no-input",
164 "--no-cache-dir", "g4f[slim]",
165 165 }, pipEnv(binDir)...)
166 166 if err != nil || code != 0 {
167 167 return fmt.Errorf("pip install g4f failed (exit %d): %w", code, err)
@@ -192,8 +192,6 @@ func pipEnv(binDir string) []string {
192 192 "PYTHONNOUSERSITE=1",
193 193 "PYTHONDONTWRITEBYTECODE=1",
194 194 "PYTHONUTF8=1",
195 "PIP_NO_INDEX=1",
196 "PIP_FIND_LINKS=" + filepath.Join(binDir, "wheels"),
197 195 "PYTHONPATH=" + lib,
198 196 }
199 197 }
Modified g4f/Provider/__init__.py +6 -0
@@ -117,6 +117,12 @@ def _resolve_provider(name: str) -> ProviderType:
117 117 from g4f.Provider.needs_auth.FenayAI import FenayAI
118 118
119 119 return FenayAI
120 elif name == "G4FSpace":
121 from ..client.factory import AbstractClientFactory
122 _loaded_providers[name] = AbstractClientFactory.create_provider(
123 None, "default"
124 )
125 return _loaded_providers[name]
120 126 elif name == "GLM":
121 127 from g4f.Provider.glm import GLM
122 128
Modified g4f/providers/any_provider.py +1 -5
@@ -4,11 +4,9 @@ import os
4 4 import re
5 5 import json
6 6 from ..typing import AsyncResult, Messages, MediaListType, Union
7 from ..errors import ModelNotFoundError
8 7 from ..image import is_data_an_audio
9 8 from ..providers.retry_provider import RotatedProvider
10 9 from ..providers.config_provider import RouterConfig, ConfigModelProvider
11 from ..client.factory import AbstractClientFactory
12 10 from ..Provider import __getattr__
13 11 from .base_provider import (
14 12 AsyncGeneratorProvider,
@@ -525,9 +523,7 @@ class AnyProvider(AsyncGeneratorProvider, AnyModelProviderMixin):
525 523 providers.sort(key=lambda p: bool(getattr(p, "needs_auth", False)))
526 524
527 525 if len(providers) == 0:
528 provider: AsyncGeneratorProvider = AbstractClientFactory.create_provider(
529 None, "default"
530 )
526 provider: AsyncGeneratorProvider = __getattr__("G4FSpace")
531 527 async for chunk in provider.create_async_generator(
532 528 model, messages, stream=stream, media=media, api_key=api_key, **kwargs
533 529 ):