fanout / django-eventstream

Server-Sent Events for Django
MIT License
638 stars 84 forks source link

How to run examples using Uvicorn? #135

Closed Scypio81 closed 4 months ago

Scypio81 commented 4 months ago

Hi, I'm trying to learn how to use django-eventstream by running examples. But trying to use Uvicorn results only in getting asyncio errors. Is there a way to run them using Uvicorn?

Sorry if this is inappropriate question here.

jkarneges commented 4 months ago

What error do you get? Uvicorn 0.27.1 works for me with the chat example, by adding whitenoise (to make static files work) and then running:

uvicorn server.asgi:application
Scypio81 commented 4 months ago

The problem:

  1. python manage.py runserver - goes with a bunch of DB warnings ("Accessing the database during app initialization is discouraged") but works fine, example runs on http://127.0.0.1:8000/ and browser shows the time updates nicely.
  2. uvicorn server.asgi:application --host 0.0.0.0 --port 4001 - crashes with SynchronousOnlyOperation error.

My best guess is this is somehow related to the DB warnings and I need to change something there? Like driver for async sqlite? I'm missing a step here, sorry.

Versions:

Command I use to run: uvicorn server.asgi:application --host 0.0.0.0 --port 4001

Error: django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async. Error trace:

Traceback (most recent call last):
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/bin/uvicorn", line 8, in <module>
    sys.exit(main())
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/uvicorn/main.py", line 418, in main
    run(
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/uvicorn/main.py", line 587, in run
    server.run()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/uvicorn/server.py", line 62, in run
    return asyncio.run(self.serve(sockets=sockets))
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/uvicorn/server.py", line 69, in serve
    config.load()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/uvicorn/config.py", line 458, in load
    self.loaded_app = import_from_string(self.app)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/uvicorn/importer.py", line 21, in import_from_string
    module = importlib.import_module(module_str)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/django-eventstream/examples/time/server/asgi.py", line 23, in <module>
    application = get_asgi_application()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/core/asgi.py", line 12, in get_asgi_application
    django.setup(set_prefix=False)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/apps/registry.py", line 124, in populate
    app_config.ready()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/django-eventstream/examples/time/timeapp/apps.py", line 12, in ready
    ensure_worker_started()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/django-eventstream/examples/time/timeapp/apps.py", line 24, in ensure_worker_started
    if not is_db_ready():
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/django-eventstream/examples/time/timeapp/apps.py", line 47, in is_db_ready
    Event.objects.count()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/db/models/query.py", line 620, in count
    return self.query.get_count(using=self.db)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 629, in get_count
    return obj.get_aggregation(using, {"__count": Count("*")})["__count"]
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/db/models/sql/query.py", line 615, in get_aggregation
    result = compiler.execute_sql(SINGLE)
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1560, in execute_sql
    cursor = self.connection.cursor()
  File "/media/Storage/_SRC/PYTHON/django_eventstream_example/my_venv/lib/python3.10/site-packages/django/utils/asyncio.py", line 24, in inner
    raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
jkarneges commented 4 months ago

Ah yeah, the time example tries to access the DB during startup. Offhand I'm not sure of the proper way to fix that, but you could try moving the ensure_worker_started() call from the app ready method to the view handler, so that the DB isn't accessed until the first request. You could also try the chat example.

Scypio81 commented 4 months ago

Thanks, I'll try. Thank you for your help.