Visitar URL original
"RuntimeError: asyncio.run() cannot be called from a running event loop (first sample code) · Issue #5462 · flet-dev/flet · GitHub
Skip to content

"RuntimeError: asyncio.run() cannot be called from a running event loop (first sample code) #5462

Closed

Description

@DJuego

Duplicate Check

Describe the bug

Python version: 3.13.5.
Environment: Spyder 6.0.7

I recently discovered this library and have installed it in a virtual environment. However when I run the example code I get "RuntimeError: asyncio.run() cannot be called from a running event loop" I must warn that I am working in Spyder Environment (winpython)

DJuego

Code sample

Code
import flet as ft

def main(page: ft.Page):
    page.title = "Flet counter example"
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)

    def minus_click(e):
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()

    def plus_click(e):
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()

    page.add(
        ft.Row(
            [
                ft.IconButton(ft.Icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.Icons.ADD, on_click=plus_click),
            ],
            alignment=ft.alignment.center,
        )
    )

ft.app(main)

To reproduce

+Python version: 3.13.5.
+Environment: Spyder 6.0.7
+pip install flet

Run the sample code

Expected behavior

Display the example interface of flet.

Screenshots / Videos

Image

Operating System

Windows 10 x64

Operating system details

Flet version

Version: 0.28.3

Regression

No, it isn't

Suggestions

No response

Logs

Logs
[Paste your logs here]

Additional details

No response

Activity

  1. typedecker commented on Jul 21, 2025

    @typedecker

    spyder using the ipython console, which causes this error whenever you run async code on there. This isn't a bug with flet, its a spyder related issue. You can fix this by using the nest_asyncio module like so:

    import nest_asyncio
    nest_asyncio.apply()

    You gotta place this at the very start of your program. The reason this issue occurs is cuz spyder's ipython console, runs it's own asyncio loop.

  2. typedecker commented on Jul 21, 2025

    @typedecker

    Also I am pretty sure I tried working with it in spyder as well, and executing the code on there, but I've realized that due to a bunch of async and environment related issues, its easier to just run it off of the command line. Spyder is just not built for this I suppose, to run the program and test it, you must use the flet run command instead of what spyder uses to run the python file.

  3. FeodorFitsner commented on Jul 21, 2025

    @FeodorFitsner
    Contributor

    There is ft.app_async() method that does not start a new asyncio loop and can be awaited or run as a task in the existing event loop.

  4. DJuego commented on Jul 22, 2025

    @DJuego
    Author

    spyder using the ipython console, which causes this error whenever you run async code on there. This isn't a bug with flet, its a spyder related issue. You can fix this by using the nest_asyncio module like so:

    import nest_asyncio
    nest_asyncio.apply()

    You gotta place this at the very start of your program. The reason this issue occurs is cuz spyder's ipython console, runs it's own asyncio loop.

    Thank you for your reply!

    I try:

    # -*- coding: utf-8 -*-
    """
    Created on Sun Jul 20 18:46:03 2025
    
    @author: YO
    """
    
    import nest_asyncio
    nest_asyncio.apply()
    
    import flet as ft
    def main(page: ft.Page):
        page.title = "Flet counter example"
        page.vertical_alignment = ft.MainAxisAlignment.CENTER
    
        txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
    
        def minus_click(e):
            txt_number.value = str(int(txt_number.value) - 1)
            page.update()
    
        def plus_click(e):
            txt_number.value = str(int(txt_number.value) + 1)
            page.update()
    
        page.add(
            ft.Row(
                [
                    ft.IconButton(ft.Icons.REMOVE, on_click=minus_click),
                    txt_number,
                    ft.IconButton(ft.Icons.ADD, on_click=plus_click),
                ],
                alignment=ft.alignment.center,
            )
        )
    
    ft.app(main)

    I get:

    
    %runfile 'M:/Mis Proyectos/Flet/test_01.py' --wdir
    ---------------------------------------------------------------------------
    NotImplementedError                       Traceback (most recent call last)
    File m:\mis proyectos\flet\test_01.py:38
         25         page.update()
         27     page.add(
         28         ft.Row(
         29             [
       (...)
         35         )
         36     )
    ---> 38 ft.app(main)
         40 #if __name__ == "__main__":
         41     #ft.app_async(main)
         42     #ft.app(main)
       (...)
         45 #ft.app(main)
         46 #ft.app_async(main)
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\flet\app.py:64, in app(target, name, host, port, view, assets_dir, upload_dir, web_renderer, use_color_emoji, route_url_strategy, export_asgi_app)
         52     from flet_web.fastapi.serve_fastapi_web_app import get_fastapi_web_app
         54     return get_fastapi_web_app(
         55         session_handler=target,
         56         page_name=__get_page_name(name),
       (...)
         61         route_url_strategy=route_url_strategy,
         62     )
    ---> 64 return asyncio.run(
         65     app_async(
         66         target=target,
         67         name=name,
         68         host=host,
         69         port=port,
         70         view=view,
         71         assets_dir=assets_dir,
         72         upload_dir=upload_dir,
         73         web_renderer=web_renderer,
         74         use_color_emoji=use_color_emoji,
         75         route_url_strategy=route_url_strategy,
         76     )
         77 )
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\nest_asyncio.py:30, in _patch_asyncio.<locals>.run(main, debug)
         28 task = asyncio.ensure_future(main)
         29 try:
    ---> 30     return loop.run_until_complete(task)
         31 finally:
         32     if not task.done():
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\nest_asyncio.py:98, in _patch_loop.<locals>.run_until_complete(self, future)
         95 if not f.done():
         96     raise RuntimeError(
         97         'Event loop stopped before Future completed.')
    ---> 98 return f.result()
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\futures.py:199, in Future.result(self)
        197 self.__log_traceback = False
        198 if self._exception is not None:
    --> 199     raise self._exception.with_traceback(self._exception_tb)
        200 return self._result
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\tasks.py:304, in Task.__step_run_and_handle_result(***failed resolving arguments***)
        300 try:
        301     if exc is None:
        302         # We use the `send` method directly, because coroutines
        303         # don't have `__iter__` and `__next__` methods.
    --> 304         result = coro.send(None)
        305     else:
        306         result = coro.throw(exc)
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\flet\app.py:189, in app_async(target, name, host, port, view, assets_dir, upload_dir, web_renderer, use_color_emoji, route_url_strategy)
        185 from flet_desktop import close_flet_view, open_flet_view_async
        187 on_app_startup(conn.page_url)
    --> 189 fvp, pid_file = await open_flet_view_async(
        190     conn.page_url,
        191     assets_dir if view != AppView.FLET_APP_WEB else None,
        192     view == AppView.FLET_APP_HIDDEN,
        193 )
        194 try:
        195     await fvp.wait()
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\flet_desktop\__init__.py:43, in open_flet_view_async(page_url, assets_dir, hidden)
         38 async def open_flet_view_async(page_url, assets_dir, hidden):
         39     args, flet_env, pid_file = __locate_and_unpack_flet_view(
         40         page_url, assets_dir, hidden
         41     )
         42     return (
    ---> 43         await asyncio.create_subprocess_exec(args[0], *args[1:], env=flet_env),
         44         pid_file,
         45     )
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\subprocess.py:224, in create_subprocess_exec(program, stdin, stdout, stderr, limit, *args, **kwds)
        221 loop = events.get_running_loop()
        222 protocol_factory = lambda: SubprocessStreamProtocol(limit=limit,
        223                                                     loop=loop)
    --> 224 transport, protocol = await loop.subprocess_exec(
        225     protocol_factory,
        226     program, *args,
        227     stdin=stdin, stdout=stdout,
        228     stderr=stderr, **kwds)
        229 return Process(transport, protocol, loop)
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\base_events.py:1794, in BaseEventLoop.subprocess_exec(self, protocol_factory, program, stdin, stdout, stderr, universal_newlines, shell, bufsize, encoding, errors, text, *args, **kwargs)
       1792     debug_log = f'execute program {program!r}'
       1793     self._log_subprocess(debug_log, stdin, stdout, stderr)
    -> 1794 transport = await self._make_subprocess_transport(
       1795     protocol, popen_args, False, stdin, stdout, stderr,
       1796     bufsize, **kwargs)
       1797 if self._debug and debug_log is not None:
       1798     logger.info('%s: %r', debug_log, transport)
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\base_events.py:539, in BaseEventLoop._make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra, **kwargs)
        535 async def _make_subprocess_transport(self, protocol, args, shell,
        536                                      stdin, stdout, stderr, bufsize,
        537                                      extra=None, **kwargs):
        538     """Create subprocess transport."""
    --> 539     raise NotImplementedError
    
    NotImplementedError: 
    
  5. DJuego commented on Jul 22, 2025

    @DJuego
    Author

    There is ft.app_async() method that does not start a new asyncio loop and can be awaited or run as a task in the existing event loop.

    Also thank you for your reply.

    I try:

    import flet as ft
    def main(page: ft.Page):
        page.title = "Flet counter example"
        page.vertical_alignment = ft.MainAxisAlignment.CENTER
    
        txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
    
        def minus_click(e):
            txt_number.value = str(int(txt_number.value) - 1)
            page.update()
    
        def plus_click(e):
            txt_number.value = str(int(txt_number.value) + 1)
            page.update()
    
        page.add(
            ft.Row(
                [
                    ft.IconButton(ft.Icons.REMOVE, on_click=minus_click),
                    txt_number,
                    ft.IconButton(ft.Icons.ADD, on_click=plus_click),
                ],
                alignment=ft.alignment.center,
            )
        )
    
    ft.app_async(main)

    The promised interface does not open and I get:

    m:\mis proyectos\flet\test_01.py:38: RuntimeWarning: coroutine 'app_async' was never awaited
      ft.app_async(main)
    RuntimeWarning: Enable tracemalloc to get the object allocation traceback
    
    
  6. typedecker commented on Jul 24, 2025

    @typedecker

    There is ft.app_async() method that does not start a new asyncio loop and can be awaited or run as a task in the existing event loop.

    Also thank you for your reply.

    I try:

    import flet as ft
    def main(page: ft.Page):
    page.title = "Flet counter example"
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
    
    def minus_click(e):
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()
    
    def plus_click(e):
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()
    
    page.add(
        ft.Row(
            [
                ft.IconButton(ft.Icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.Icons.ADD, on_click=plus_click),
            ],
            alignment=ft.alignment.center,
        )
    )
    

    ft.app_async(main)
    The promised interface does not open and I get:

    m:\mis proyectos\flet\test_01.py:38: RuntimeWarning: coroutine 'app_async' was never awaited
      ft.app_async(main)
    RuntimeWarning: Enable tracemalloc to get the object allocation traceback
    

    You might just have to put it in asyncio.run or use it in an async context for it to work.
    The error message is suggesting that app_async is an async coroutine, and when trying to execute such coroutines, the await keyword needs to be used to call upon then, but the same cannot be done in a non-asyncio context, so the best way to run an async coroutine without await, is to run it using asyncio.run.

    I'd suggest having a look at the way it has been used here: https://docs.python.org/3/library/asyncio-runner.html#asyncio.run
    maybe trying something along the lines of asyncio.run(ft.app_async()) instead of just ft.app_async() might work.

  7. typedecker commented on Jul 24, 2025

    @typedecker

    spyder using the ipython console, which causes this error whenever you run async code on there. This isn't a bug with flet, its a spyder related issue. You can fix this by using the nest_asyncio module like so:
    import nest_asyncio
    nest_asyncio.apply()
    You gotta place this at the very start of your program. The reason this issue occurs is cuz spyder's ipython console, runs it's own asyncio loop.

    Thank you for your reply!

    I try:

    -- coding: utf-8 --

    """
    Created on Sun Jul 20 18:46:03 2025

    @author: YO
    """

    import nest_asyncio
    nest_asyncio.apply()

    import flet as ft
    def main(page: ft.Page):
    page.title = "Flet counter example"
    page.vertical_alignment = ft.MainAxisAlignment.CENTER

    txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)
    
    def minus_click(e):
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()
    
    def plus_click(e):
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()
    
    page.add(
        ft.Row(
            [
                ft.IconButton(ft.Icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.Icons.ADD, on_click=plus_click),
            ],
            alignment=ft.alignment.center,
        )
    )
    

    ft.app(main)
    I get:

    
    %runfile 'M:/Mis Proyectos/Flet/test_01.py' --wdir
    ---------------------------------------------------------------------------
    NotImplementedError                       Traceback (most recent call last)
    File m:\mis proyectos\flet\test_01.py:38
         25         page.update()
         27     page.add(
         28         ft.Row(
         29             [
       (...)
         35         )
         36     )
    ---> 38 ft.app(main)
         40 #if __name__ == "__main__":
         41     #ft.app_async(main)
         42     #ft.app(main)
       (...)
         45 #ft.app(main)
         46 #ft.app_async(main)
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\flet\app.py:64, in app(target, name, host, port, view, assets_dir, upload_dir, web_renderer, use_color_emoji, route_url_strategy, export_asgi_app)
         52     from flet_web.fastapi.serve_fastapi_web_app import get_fastapi_web_app
         54     return get_fastapi_web_app(
         55         session_handler=target,
         56         page_name=__get_page_name(name),
       (...)
         61         route_url_strategy=route_url_strategy,
         62     )
    ---> 64 return asyncio.run(
         65     app_async(
         66         target=target,
         67         name=name,
         68         host=host,
         69         port=port,
         70         view=view,
         71         assets_dir=assets_dir,
         72         upload_dir=upload_dir,
         73         web_renderer=web_renderer,
         74         use_color_emoji=use_color_emoji,
         75         route_url_strategy=route_url_strategy,
         76     )
         77 )
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\nest_asyncio.py:30, in _patch_asyncio.<locals>.run(main, debug)
         28 task = asyncio.ensure_future(main)
         29 try:
    ---> 30     return loop.run_until_complete(task)
         31 finally:
         32     if not task.done():
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\nest_asyncio.py:98, in _patch_loop.<locals>.run_until_complete(self, future)
         95 if not f.done():
         96     raise RuntimeError(
         97         'Event loop stopped before Future completed.')
    ---> 98 return f.result()
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\futures.py:199, in Future.result(self)
        197 self.__log_traceback = False
        198 if self._exception is not None:
    --> 199     raise self._exception.with_traceback(self._exception_tb)
        200 return self._result
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\tasks.py:304, in Task.__step_run_and_handle_result(***failed resolving arguments***)
        300 try:
        301     if exc is None:
        302         # We use the `send` method directly, because coroutines
        303         # don't have `__iter__` and `__next__` methods.
    --> 304         result = coro.send(None)
        305     else:
        306         result = coro.throw(exc)
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\flet\app.py:189, in app_async(target, name, host, port, view, assets_dir, upload_dir, web_renderer, use_color_emoji, route_url_strategy)
        185 from flet_desktop import close_flet_view, open_flet_view_async
        187 on_app_startup(conn.page_url)
    --> 189 fvp, pid_file = await open_flet_view_async(
        190     conn.page_url,
        191     assets_dir if view != AppView.FLET_APP_WEB else None,
        192     view == AppView.FLET_APP_HIDDEN,
        193 )
        194 try:
        195     await fvp.wait()
    
    File M:\Python\entornos_virtuales\desarrollo_aplicaciones\Lib\site-packages\flet_desktop\__init__.py:43, in open_flet_view_async(page_url, assets_dir, hidden)
         38 async def open_flet_view_async(page_url, assets_dir, hidden):
         39     args, flet_env, pid_file = __locate_and_unpack_flet_view(
         40         page_url, assets_dir, hidden
         41     )
         42     return (
    ---> 43         await asyncio.create_subprocess_exec(args[0], *args[1:], env=flet_env),
         44         pid_file,
         45     )
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\subprocess.py:224, in create_subprocess_exec(program, stdin, stdout, stderr, limit, *args, **kwds)
        221 loop = events.get_running_loop()
        222 protocol_factory = lambda: SubprocessStreamProtocol(limit=limit,
        223                                                     loop=loop)
    --> 224 transport, protocol = await loop.subprocess_exec(
        225     protocol_factory,
        226     program, *args,
        227     stdin=stdin, stdout=stdout,
        228     stderr=stderr, **kwds)
        229 return Process(transport, protocol, loop)
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\base_events.py:1794, in BaseEventLoop.subprocess_exec(self, protocol_factory, program, stdin, stdout, stderr, universal_newlines, shell, bufsize, encoding, errors, text, *args, **kwargs)
       1792     debug_log = f'execute program {program!r}'
       1793     self._log_subprocess(debug_log, stdin, stdout, stderr)
    -> 1794 transport = await self._make_subprocess_transport(
       1795     protocol, popen_args, False, stdin, stdout, stderr,
       1796     bufsize, **kwargs)
       1797 if self._debug and debug_log is not None:
       1798     logger.info('%s: %r', debug_log, transport)
    
    File M:\Python\Winpython64-3.13.5.0slim\WPy64-31350\python\Lib\asyncio\base_events.py:539, in BaseEventLoop._make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra, **kwargs)
        535 async def _make_subprocess_transport(self, protocol, args, shell,
        536                                      stdin, stdout, stderr, bufsize,
        537                                      extra=None, **kwargs):
        538     """Create subprocess transport."""
    --> 539     raise NotImplementedError
    
    NotImplementedError: 
    

    I am pretty sure this error is the result of the way spyder's internal async event loop is set. I am not sure if this can be fixed or solved in any way, cuz it is a problem with the IDE's working itself. But I wasn't previously aware of the ft.app_async() coroutine, but I feel like thats probably the best option we've got at getting it to work with spyder. I just gave up when I was trying, and decided to code in spyder but execute it in the command line.

  8. DJuego commented on Jul 24, 2025

    @DJuego
    Author

    Thank you, @typedecker , for dedicating your time and effort to trying to shed light on this issue. I'm afraid I'm at a dead end.

    Apparently, it's as you say:

    Spyder already has an asyncio event loop running. That's why neither asyncio.run() nor loop.run_until_complete() will work.

    The solution would be nest_asyncio, as already suggested in this thread.

    Unfortunately, it seems that the implementation of asyncio in Winpython is not complete and does not support the creation of asynchronous threads: NotImplementedError: asyncio.subprocess is not supported on this platform. :-(

    I'll see if I can configure Spyder to use the full Python distribution (e.g., the official one), and then use that nest_asyncio.

    DJuego

  9. typedecker commented on Jul 24, 2025

    @typedecker

    @DJuego I have made asyncio.run work in the past for discord bots made using discord.py, by using the nest_asyncio technique that I suggested, maybe try using that in conjunction with asyncio.run and ft.app_async()? unless you've already tried that 😅

    Also! I wrote a script that makes it easier for you to directly create and open a flet project within spyder without much work, the running part still needs to be done manually though, let me know if you'd need something like that <3 I can prolly write it up in a github codesheet or repo and share it here!

  10. typedecker commented on Jul 27, 2025

    @typedecker

    @DJuego I just finished writing up and testing a nice command line script, that can be used to run flet apps from within spyder, and also to create them! Let me know if you need a version of that, I'll make it available in a repo soon, but i'll also drop it here quickly if you'd like ^^

  11. DJuego commented on Jul 27, 2025

    @DJuego
    Author

    Wow! @typedecker That's excellent news! I'd like to try it out as soon as possible. 👍 As for me, after several unsuccessful attempts, I had already decided to raise an issue in the Winpython project to request better support for asyncio.

    However, I am sure there are compelling technical reasons for those limitations.

    P.S: Honestly, I was enthusiastic about PySimpleGui. Using PySimpleGui was satisfactory, and I coded a complete application with it this last year... but its license change was a disappointment. So I am currently trying to decide which graphical user interface library to choose for my Python programming.

    Recently I have used DearPyGui, which uses the immediate mode paradigm. It's my favorite right now, but it doesn't feel Python-like.

    Both (DearPyGui and PySimpleGui) work without any problems under Winpython/Spyder.

    I am also considering Kivy, although I have not tried it yet.

    Flet seems like what I'm looking for. It's modern, liberally licensed, and seems quite elegant. That's why I'm frustrated by its 'incompatibility' with my development environment of choice (Spyder on Winpython), which works well for everything else.

    DJuego

  12. typedecker commented on Jul 27, 2025

    @typedecker

    @DJuego Yes! Honestly I'd love to get in touch and talk more about this, I am not sure if its okay to talk about it in an issue thread exactly, but I have been having alot of success with kivy personally, flet is great too and I've some thoughts I'd like to share but they are a little too detailed for me to go over on an issue thread, are you on discord by any chance? or maybe if you've any other way of continuing this discussion (:

    If what you are looking for, is customizability and ease of use, whilst being great at right about everything, kivy takes the cake! Qt is great but the docs suck, flet is amazing but not ready for production use or for more complex apps imma be honest, and dearpygui just wasn't my thing to be honest. I have also worked for really long with tkinter and later -- customtkinter, and kivy is just like that but with so so much more customizability, you can make right about anything! So i've started tryna learn kivy and get more used to working with it, I'll still be contributing to flet ofcourse though :D! Kivy has issues with the spyder IDE too, but the issue is just that once your window shows up, if you try to close it, the program ends but the window doesn't disappear, it hangs, but you can always just close the console and create a new one everytime to prevent that. I have also reported the issue to the spyder dev in an issue thread, and hopefully he'll have a look at it <33.

  13. DJuego commented on Jul 29, 2025

    @DJuego
    Author

    Best regards, @typedecker, Thanks again for responding, and sorry for the delay in my reply. And thank you for sharing your experiences with different graphical interfaces on Python. It has been enlightening. You are very kind. Sadly, I don't speak English. Although now, as we all know, with the new generation of automatic language translators, it's less of a problem than before.

    I have worked with Qt in C++, and although it is indeed a tremendous library, it is too big and heavy. I find it cumbersome. And I'm not convinced by their license. I don't feel that it is free and open.

    I look forward to you releasing that "nice command line script, that can be used to run flet apps from within spyder, and also to create them".

    Meanwhile, today I tested Kivy on Winpython/Spyder and can confirm that the problem you describe so clearly in that thread does occur. I'll support the issue you raised. Considering your comment about Flet, I think Kivy deserves a chance. It seems to be well documented and the MIT license is one of my favorites. It looks like what I'm looking for,

    DJuego

  14. typedecker commented on Jul 30, 2025

    @typedecker

    @DJuego Ah no worries at all, thanks sm for the reply! And it has been my pleasure informing other developers about my experiences with these UI Frameworks! I am hoping for a better future of UI dev with python as well! Also, it is totally okay to not speak english as your first language, I am glad we could still have this conversational exchange, you seem like a really passionate developer as well (: AI can indeed be very helpful in translating stuff, I had a few discussions with some russian people in the past on the flet discord server, it allowed me to reach out to them and help them out in some cases!

    Also, yeah I've looked into pyside6 and I just feel like despite being very featureful, it lacks proper documentation on the python side to support the features. I found it really hard to understand how to work with QML, and even just the basic widgets, or how to customize all of them. The attributes/properties/slots and signals of each component were also hard to figure out cuz they are not fully mentioned on a single page per component. Kivy in this sense, has a much better documentation. I think flet has alot of potential as a framework, but it lacks customizability in many ways, and ease of use. I am planning on making a wrapper around flet that will hopefully deal with some of these things, though even then, it will be hard to maintain it, and add certain things I'd like to add, but I'll try my best!

    Kivy's devs themselves have said that kivy's aim is to be as atomic as possible, such that higher level behavior can be constructed using the atomic components provided. One thing I really love about kivy is that it doesn't make the decisions for us, but rather lets us be the one to decide how things should work, it exposes mostly every single property for most of it's widgets to the point where you can make an app of your dreams! The only issue with that is, that it sometimes takes a good while to understand how some of these concepts work, and it might take longer to build something huge, if you want it to be heavily customized. But yeah! I am still new to kivy but it gives me the kind of vibes tkinter used to give me in the early days before I mastered it <33 And, on top of all this, if you ever join the kivy discord, you'll see that the github repo is being worked on and updated throughout the day, its quite impressive actually. But yeah, for me, the kind of UI framework I am looking for, is definitely one that is heavily customizable and exposes behaviors and lets the developers choose how to utilize them in their apps!

  15. typedecker commented on Jul 30, 2025

    @typedecker

    About the spyder issue by the way, I am currently just running the program and then restarting the console afterwards to close the window. It works well enough. I think it has something to do with the fact that it says "Leaving application in progress" or "Leaving application running" or something like that, so kivy does infact know that the application is still running. I am hoping that the spyder dev realizes that sooner or later. Also, I do actually have the command line script readied, but it is part of a bigger, more diverse command line script that I made for use for my own self, so I am currently in the process of extracting the part of it required for flet projects and then putting that up as a repo, though if you wait a little more, I might as well add those commands to my new flet-wrapper framework directly.

  16. ndonkoHenri commented on Apr 18, 2026

    @ndonkoHenri
    Contributor

    ft.app() (which is now deprecated in latest Flet versions in favor of ft.run()) cannot be called from an environment that already has a running asyncio event loop.

    Spyder uses an IPython console, and IPython already runs its own event loop. Because ft.app() internally starts Flet with asyncio.run(...), Python raises:

    RuntimeError: asyncio.run() cannot be called from a running event loop
    

    This is not specific to Spyder. The same kind of issue can happen in Jupyter, IPython, async test runners, or any other host application that already owns the asyncio loop.

    When running inside an existing async environment, use the async API and await it:

    await ft.run_async(main)
    
    # or deprecated name
    # await ft.app_async(main)

    Calling ft.app_async(main) without await will only create a coroutine, which explains this warning:

    RuntimeWarning: coroutine 'app_async' was never awaited
    

    Let know if you have additional concerns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions