diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 8135c969..7bd38f8f 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -37,6 +37,21 @@ jobs: echo "is_release=${IS_RELEASE}" >> $GITHUB_OUTPUT echo "Building version: ${G4F_VERSION}" + cat > g4f_cli.py << EOF + #!/usr/bin/env python3 + """ + Entry point for g4f CLI executable builds + """ + + import g4f.debug + g4f.debug.version_check = False + g4f.debug.version = "${{ needs.prepare.outputs.version }}" + + if __name__ == "__main__": + from g4f.cli import main + main() + EOF + # PyPI Package build-pypi: runs-on: ubuntu-latest diff --git a/g4f/__main__.py b/g4f/__main__.py index 751c9b81..5215752f 100644 --- a/g4f/__main__.py +++ b/g4f/__main__.py @@ -1,9 +1,4 @@ -from __future__ import annotations +from g4f.cli import main -from .cli import get_api_parser, run_api_args - -parser = get_api_parser() -args = parser.parse_args() -if args.gui is None: - args.gui = True -run_api_args(args) \ No newline at end of file +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/g4f/cli/__init__.py b/g4f/cli/__init__.py index 6812a254..e6fa0eec 100644 --- a/g4f/cli/__init__.py +++ b/g4f/cli/__init__.py @@ -1,5 +1,6 @@ from __future__ import annotations +import sys import argparse from argparse import ArgumentParser from .client import get_parser, run_client_args @@ -13,7 +14,8 @@ def get_api_parser(): api_parser.add_argument("--bind", default=None, help="The bind string. (Default: 0.0.0.0:1337)") api_parser.add_argument("--port", "-p", default=None, help="Change the port of the server.") api_parser.add_argument("--debug", "-d", action="store_true", help="Enable verbose logging.") - api_parser.add_argument("--gui", "-g", default=None, action="store_true", help="Start also the gui.") + api_parser.add_argument("--gui", "-g", default=None, action="store_true", help="(deprecated)") + api_parser.add_argument("--no-gui", "-ng", default=False, action="store_true", help="Start without the gui.") api_parser.add_argument("--model", default=None, help="Default model for chat completion. (incompatible with --reload and --workers)") api_parser.add_argument("--provider", choices=[provider.__name__ for provider in Provider.__providers__ if provider.working], default=None, help="Default provider for chat completion. (incompatible with --reload and --workers)") @@ -48,7 +50,7 @@ def run_api_args(args): media_provider=args.media_provider, proxy=args.proxy, model=args.model, - gui=args.gui, + gui=not args.no_gui, demo=args.demo, timeout=args.timeout, ) @@ -82,7 +84,9 @@ def main(): elif args.mode == "client": run_client_args(args) else: - parser.print_help() - exit(1) + raise argparse.ArgumentError(None, "No valid mode specified. Use 'api', 'gui', or 'client'.") except argparse.ArgumentError: - run_client_args(get_parser().parse_args()) \ No newline at end of file + try: + run_client_args(get_parser(exit_on_error=False).parse_args(), exit_on_error=False) + except argparse.ArgumentError: + run_api_args(get_api_parser().parse_args()) \ No newline at end of file diff --git a/g4f/cli/client.py b/g4f/cli/client.py index 8507926a..c4b6cbb7 100644 --- a/g4f/cli/client.py +++ b/g4f/cli/client.py @@ -190,10 +190,11 @@ def save_content(content, media: Optional[MediaResponse], filepath: str, allowed print("\nUnable to save content.", file=sys.stderr) return False -def get_parser(): +def get_parser(exit_on_error=True): parser = argparse.ArgumentParser( description="G4F CLI client with conversation history", - formatter_class=argparse.ArgumentDefaultsHelpFormatter + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + exit_on_error=exit_on_error ) parser.add_argument('-d', '--debug', action='store_true', help="Verbose debug") parser.add_argument('-p', '--provider', default=None, @@ -270,7 +271,7 @@ async def run_args(input_val, args): sys.exit(1) -def run_client_args(args): +def run_client_args(args, exit_on_error=True): input_txt = "" media = [] rest = 0 @@ -317,9 +318,11 @@ def run_client_args(args): else: val = input_txt.strip() - if not val: + if exit_on_error and not val: print("No input provided. Use -h.", file=sys.stderr) sys.exit(1) + elif not val: + raise argparse.ArgumentError(None, "No input provided. Use -h for help.") asyncio.run(run_args(val, args)) diff --git a/g4f/version.py b/g4f/version.py index a6a766a6..006b23f3 100644 --- a/g4f/version.py +++ b/g4f/version.py @@ -67,7 +67,7 @@ def get_git_version() -> str | None: text=True, stderr=PIPE ).strip() - except CalledProcessError: + except (CalledProcessError, FileNotFoundError): return None diff --git a/g4f_cli.py b/g4f_cli.py deleted file mode 100644 index e688a8fe..00000000 --- a/g4f_cli.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python3 -""" -Entry point for g4f CLI executable builds -""" - -if __name__ == "__main__": - from g4f.cli import main - main() \ No newline at end of file diff --git a/test.py b/test.py deleted file mode 100644 index a51b5f79..00000000 --- a/test.py +++ /dev/null @@ -1,43 +0,0 @@ -import asyncio -from pathlib import Path -from g4f.client import AsyncClient -from g4f.Provider import HuggingSpace, Azure -from g4f.cookies import read_cookie_files - -# Load cookies and authentication environment variables needed by providers -read_cookie_files() - -# Initialize asynchronous client to interact with providers -client = AsyncClient() - -# Define an async function that creates an image variation using the HuggingSpace provider -async def main_with_hugging_space(): - # Call create_variation with an image path, provider, model, prompt and desired response format - result = await client.images.create_variation( - image=Path("g4f.dev/docs/images/strawberry.jpg"), # Path to input image - provider=HuggingSpace, # Provider to use - model="flux-kontext-dev", # Model name for HuggingSpace - prompt="Change color to black and white", # Variation prompt - response_format="url" # Return URL to generated image - ) - print(result) # Print the URL or result returned by the provider - -# Define an async function that creates an image variation using the Azure provider -async def main_with_azure(): - result = await client.images.create_variation( - image=Path("g4f.dev/docs/images/strawberry.jpg"), - provider=Azure, - model="flux-kontext", - prompt="Add text 'Hello World' in the center", - response_format="url" - ) - print(result) # Print the returned URL or response - -# Run the Azure image variation example asynchronously -asyncio.run(main_with_azure()) - -# Import helper function to get directory used for cookies and related files -from g4f.cookies import get_cookies_dir - -# Print the directory currently used for storing cookies -print(get_cookies_dir()) \ No newline at end of file