```python:inference/core/roboflow_api.py
import urllib.parse


def _url_for_safe_logging(url: str) -> str:
    """Return a URL safe to log by stripping the query string (and params/fragment).

    Expects the full URL as used for the request (e.g. already wrapped).
    Use this when logging request URLs so that sensitive query parameters
    (e.g. api_key, tokens) are never written to logs.
    """
    # Use urlsplit (faster than urlparse for our needs) to separate scheme/netloc/path/query/fragment.
    parsed = urllib.parse.urlsplit(url)

    # Remove params from the last path segment (urlparse moves params into a separate attribute;
    # urlsplit leaves them in the path, so we emulate urlparse's behavior by trimming from the first
    # ';' after the last '/').
    path = parsed.path
    if path:
        last_slash = path.rfind('/')
        semicolon_index = path.find(';', last_slash + 1)
        if semicolon_index != -1:
            path = path[:semicolon_index]

    # Manually reconstruct the URL without params/query/fragment to avoid urlunparse overhead,
    # matching urlunparse((scheme, netloc, path, "", "", "")) semantics.
    if parsed.scheme:
        if parsed.netloc:
            return parsed.scheme + "://" + parsed.netloc + path
        else:
            return parsed.scheme + ":" + path
    else:
        if parsed.netloc:
            return "//" + parsed.netloc + path
        else:
            return path
```