Persistent 'websockets.asyncio' Error in Gradio Space with yfinance。

Dear Hugging Face Team / Community,

I am experiencing a persistent and critical environment issue while attempting to deploy a Gradio application that uses the yfinance library in my Space, ValueEngineApp/DCF-Stock-Final.

My application code (app.py) has been verified as correct. However, the Space fails to launch and continuously reports a runtime error related to dependencies.

The Core Issue:

The container logs consistently show a Runtime error and the following critical traceback:

  • Error Message: ModuleNotFoundError: No module named 'websockets.asyncio'.

  • Context: This occurs during the initialization of yfinance.

Troubleshooting Steps Taken:

I have exhausted all standard and advanced troubleshooting steps, including:

  1. Dependency Check: Confirmed that websockets is explicitly included in requirements.txt.

  2. Version Locking (Recommended Fix): I explicitly locked the key libraries to versions known to be more stable:

    • gradio==3.38.0

    • yfinance==0.2.28

  3. Environment Isolation: I created multiple new Spaces (e.g., DCF-Stock-Final) and performed repeated Factory Rebuilds to rule out cache corruption.

  4. SDK Change: I attempted to switch the SDK to docker to bypass the Gradio environment entirely, but this also resulted in configuration/runtime failures.

Since this error persists across multiple clean Spaces with correct configurations, it strongly suggests an incompatibility or failure in the underlying Gradio base container image regarding the installation and loading of yfinance’s websockets dependency.

Request for Assistance:

Could you please investigate this platform-level issue? I require support to get this dependency chain working correctly within the Gradio environment.

Thank you for your time.

1 Like

Probably just a really annoying library version mismatch…


1. What the error actually means

You are seeing:

ModuleNotFoundError: No module named 'websockets.asyncio'

This is not “websockets is missing”. It means:

  • The websockets package is installed, but
  • It is an older version that doesn’t contain the websockets.asyncio package.

The websockets library reorganised itself:

  • “New” implementation lives in websockets.asyncio.*.
  • “Old” implementation was moved to websockets.legacy.* and kept for backwards compatibility.

If code tries to do:

from websockets.asyncio.client import connect   # or ClientConnection etc.

and the environment has an old websockets (before this layout), Python raises exactly the error you are seeing.

So the fundamental bug is:

Libraries in your Space expect new-style websockets.asyncio, but the Space actually has old websockets installed.

Everything else is symptoms of that mismatch.


2. How yfinance and Gradio got involved

2.1 yfinance

Recent yfinance releases added WebSocket-based live streaming data (WebSocket and AsyncWebSocket).

Internally, that module imports:

from websockets.asyncio.client import connect as async_connect

and is pulled in when you import yfinance. A GitHub issue shows users hitting exactly your error when they do import yfinance and have an old websockets installed.

So:

  • yfinance >= 0.2.59 + websockets < 13ModuleNotFoundError: websockets.asyncio.

Even if your code never uses live streaming, the import still runs and still fails.

2.2 Gradio / gradio_client

Newer Gradio uses WebSockets internally and its Python client imports:

from websockets.asyncio.client import ClientConnection

The Gradio changelog explicitly mentions a fix:

“fix(client): websockets minimum version for asyncio” in Gradio 5.47.0, raising the minimum websockets version so that the asyncio API is present.

Before that fix, there was a bad combination:

  • gradio-client 1.5.0 required websockets < 13.0.
  • At the same time, code in the client (and in other libs such as Supabase) imported websockets.asyncio.client.*.

This combination makes it impossible to satisfy all requirements: the client forces an old websockets that doesn’t have websockets.asyncio, and the code then tries to import websockets.asyncio.

There is a Gradio issue where a user deploying to Hugging Face Spaces suddenly starts getting:

ModuleNotFoundError: No module named 'websockets.asyncio'

just from importing Supabase in a Gradio Space, after everything had worked previously.

That is the same pattern you are seeing.


3. Why it’s so persistent specifically on Hugging Face Spaces

Locally, you can just do:

pip install "gradio>=5.47.0" "yfinance>=0.2.59" "websockets>=13"

and be done.

In a Gradio Space, the installation order is different:

  1. The runner installs your requirements.txt.

  2. Then it installs the Gradio SDK specified by the sdk / sdk_version fields in README.md.

    The Hugging Face docs say:

    “The gradio package is pre-installed and its version is set in the sdk_version field in the README.md file.”

  3. That SDK install pulls in its own gradio-client and can override versions you requested in requirements.txt.

The result:

  • Pinning websockets in requirements.txt does not guarantee that version in the final container.
  • Pinning gradio==3.38.0 in requirements.txt also does not control the actual Gradio version on a Gradio Space; HF staff explicitly recommend not pinning Gradio in requirements.txt and using sdk_version instead.
  • Some Gradio / gradio-client versions used by Spaces still depend on websockets<13.

There is also a community post showing that the Space base image first runs pip install -r requirements.txt and then later installs other packages (like Gradio and spaces), which can silently change versions again.

This explains your situation:

  • You add websockets to requirements.txt and pin versions.
  • During the SDK install step, Spaces installs a Gradio / gradio-client combo that downgrades websockets or upgrades yfinance beyond what you pinned.
  • Then import yfinance or import gradio hits websockets.asyncio with an incompatible websockets version and crashes.

So yes, it behaves as a platform-level environment issue: the final dependency stack in the Space is not what your requirements.txt suggests.


4. Diagnosing your Space concretely

Before changing things, you want to see what’s actually installed inside the Space (since requirements.txt is not the final truth).

At the top of app.py, temporarily add:

import sys

print("Python:", sys.version)

def _debug_versions():
    import gradio, yfinance, websockets
    print("Gradio version:", gradio.__version__)
    print("yfinance version:", yfinance.__version__)
    print("websockets version:", websockets.__version__)
    try:
        from websockets.asyncio import client as _c
        print("websockets.asyncio IS available")
    except Exception as e:
        print("websockets.asyncio import FAILED:", repr(e))

_debug_versions()

Then trigger a Factory rebuild and look at the container logs.

You will almost certainly see one of these:

  • websockets is <13 and websockets.asyncio import FAILED, or
  • yfinance version is higher than what you pinned (e.g. ≥ 0.2.59 even if requirements.txt says 0.2.28).

That tells you which part of the stack is violating your expectation.


5. Workaround / solution options

There are three practical approaches.

Option A – Modern stack: align everything on websockets>=13 (recommended if you’re comfortable upgrading)

Goal: run new Gradio, new yfinance, and a new websockets that includes websockets.asyncio.

  1. Control Gradio via sdk_version, not requirements.txt.

    In README.md:

    ---
    title: DCF-Stock-Final
    sdk: gradio
    sdk_version: 5.47.1  # or any ≥ 5.47.0
    app_file: app.py
    python_version: 3.10
    ---
    

    Gradio 5.47.0 is where they fixed the client to require a sufficiently new websockets for asyncio.

    Remove any gradio==... line from requirements.txt for this Space.

  2. Pin the other key packages in requirements.txt.

    Example:

    # yfinance with websocket support (if you want live streaming)
    yfinance>=0.2.59,<0.3
    
    # Ensure the asyncio API exists
    websockets>=13,<16
    
    # your other deps (pandas, numpy, etc.)
    
    • websockets>=13 ensures the websockets.asyncio package exists.
    • yfinance 0.2.59+ is designed to use WebSocket features and assumes a recent websockets.
  3. Factory rebuild and re-check the _debug_versions() output.

    You want:

    • Gradio ≈ 5.47+,
    • websockets ≥ 13, and
    • websockets.asyncio IS available”.

If that’s true, the ModuleNotFoundError: websockets.asyncio should vanish, because:

  • Gradio’s client now explicitly requires websockets new enough, and
  • yfinance’s live.py can import websockets.asyncio.client.connect normally.

Option B – Avoid the WebSocket dependency entirely (older yfinance, older Gradio)

If you do not need yfinance live streaming for your DCF tool (most DCF tools only use historical data), you can sidestep the entire websockets chain.

  1. Pin yfinance to a version before the WebSocket module was introduced – for example:

    yfinance==0.2.58    # or another pre-WebSocket version you’ve tested
    

    A serverless deployment issue notes that 0.2.59 introduced changes that pulled in websockets and caused environment failures; older versions did not.

    Those older versions don’t import websockets.asyncio at all.

  2. Do not depend on websockets directly in your code or requirements (unless absolutely needed elsewhere).

    If nobody imports websockets.asyncio, it no longer matters which websockets version the Space image happens to ship.

  3. Optionally choose a Gradio sdk_version before the websockets-asyncio changes in gradio-client, or any current version where you do not use features requiring websockets.asyncio. For a simple DCF form, an older but stable Gradio is usually fine.

This is essentially the “stay on the last non-WebSocket yfinance” approach people used on platforms like Azure Functions when the new versions started breaking their environments.

Option C – Docker Space with full control

If you want to completely isolate yourself from HF’s base image and future changes:

  1. Convert the Space to Docker SDK (sdk: docker) in the README and add a Dockerfile.

  2. Minimal Dockerfile:

    FROM python:3.10-slim
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . .
    
    CMD ["python", "app.py"]
    
  3. In requirements.txt for this Docker build, you can now fix everything exactly:

    gradio==5.47.1
    yfinance==0.2.59
    websockets>=13,<16
    # other deps...
    

Here the HF platform simply builds your image; it no longer installs its own Gradio SDK afterwards, so you avoid surprise downgrades or conflicts.


6. Short bullet summary

  • The error means: code imports websockets.asyncio.* but the installed websockets is too old to have that package.

  • Newer yfinance and Gradio both rely on websockets.asyncio.

  • HF Gradio Spaces pre-install Gradio based on sdk_version and can override versions from requirements.txt, including downgrading websockets.

  • That’s why your Space keeps failing even with seemingly correct pins: the final container doesn’t match requirements.txt.

  • Fixes/workarounds:

    • Option A: use a recent Gradio SDK (≥5.47), don’t pin Gradio in requirements, and pin websockets>=13 + compatible yfinance.
    • Option B: pin yfinance to a pre-WebSocket version (≤0.2.58) and avoid websockets entirely if you don’t need live streaming.
    • Option C: switch to Docker SDK and control all versions yourself.

8. Source links (for quick reference)

1 Like

This topic was automatically closed 12 hours after the last reply. New replies are no longer allowed.