Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notify call no more working in 0.9.4 and newer with fastapi events #610

Closed
stefapi opened this issue Jun 20, 2022 · 7 comments
Closed

Notify call no more working in 0.9.4 and newer with fastapi events #610

stefapi opened this issue Jun 20, 2022 · 7 comments
Labels

Comments

@stefapi
Copy link

stefapi commented Jun 20, 2022

try this sample application:

# services/users/project/try_fail.py

import uvicorn
import apprise
from fastapi import FastAPI

app = FastAPI(
    title="apprise_failure",
    description="A sample",
)

@app.on_event("startup")
def system_startup():
        apobj = apprise.Apprise()
        apobj.notify(body = "Application Startup", title = "startup failed")
        print("passed !")


def main():
    uvicorn.run(
        "try_fail:app",
        host="0.0.0.0",
        port=9000,
        reload=True,
        reload_dirs=["."],
        debug=True,
        log_level='debug',
        log_config=None,
        workers=1,
        forwarded_allow_ips="*",
    )

if __name__ == "__main__":
    main()

This application works well with apprise 0.9.3 but does not work anymore with 0.9.4 and more recent versions.
You may use any recent version of fastapi and uvicorn.

@stefapi stefapi added the bug label Jun 20, 2022
@caronc
Copy link
Owner

caronc commented Jun 27, 2022

Hmm, I'm stumped with this one; i'd be open to any advice here from anyone else. I can certainly reproduce the problem, but nothing changed with the asyncio that I can see that would be related. If anything there is something new introduced in fastapi.

This is definitely a good bug.... 😕

python ../try_fail.py

Produces:

Traceback (most recent call last):
  File "/home/l2g/Development/apprise-api/lib64/python3.10/site-packages/apprise/py3compat/asyncio.py", line 67, in tosync
    return asyncio.run(cor, debug=debug)
  File "/usr/lib64/python3.10/asyncio/runners.py", line 33, in run
    raise RuntimeError(
RuntimeError: asyncio.run() cannot be called from a running event loop

I need a try/catch block around here. However when a loop is already running, i can't seem to find any good documentation on how to execute the coroutine in a blocking state so we can get the response. There seems to be reference to getting the nest-asyncio library to help. I'm not sure here...

Maybe @YoRyan has an idea here?

@caronc
Copy link
Owner

caronc commented Jul 3, 2022

As an update, this seems to work:

# services/users/project/try_fail.py

import uvicorn
import apprise
from fastapi import FastAPI
import nest_asyncio

app = FastAPI(
    title="apprise_failure",
    description="A sample",
)

@app.on_event("startup")
def system_startup():
        apobj = apprise.Apprise()
        apobj.notify(body = "Application Startup", title = "startup failed")
        print("passed !")


def main():
    nest_asyncio.apply()
    uvicorn.run(
        "try_fail:app",
        host="0.0.0.0",
        port=9000,
        reload=True,
        reload_dirs=["."],
        debug=True,
        log_level='debug',
        log_config=None,
        workers=1,
        forwarded_allow_ips="*",
    )

if __name__ == "__main__":
    main()

I only added 2 lines after running the following:

 pip install nest-asyncio
  1. First just the import itself at the head of the file (in your example)
    import nest_asyncio
  2. Then the following was added in the main() call area (at the start)
    nest_asyncio.apply()

@stefapi stefapi changed the title Notify call no more working in 0.9.4 and earlier with fastapi events Notify call no more working in 0.9.4 and newer with fastapi events Jul 5, 2022
@caronc
Copy link
Owner

caronc commented Jul 5, 2022

I see you changed the title 9hrs, ago. Were you able to try my modification to your sample code? That may resolve your issue.

@stefapi
Copy link
Author

stefapi commented Jul 6, 2022

Hi.
Yes, it now works on the target application. No more issue faced. It will be great to share this workaround in the documentation for the whole community.
Thx !

@caronc
Copy link
Owner

caronc commented Jul 6, 2022

It will be great to share this workaround in the documentation for the whole community.

Great idea!

I added a section here in Troubleshooting and also beefed up the documentation a bit here to explain how you can also leverage async_notify() if one chooses to.

This should address your documentation request? Thoughts?

@caronc caronc added question and removed bug labels Jul 6, 2022
@stefapi
Copy link
Author

stefapi commented Jul 6, 2022

yes, perfect ! thx to you

@stefapi stefapi closed this as completed Jul 6, 2022
@YoRyan
Copy link
Contributor

YoRyan commented Jul 7, 2022

If a framework has its own async event loop, it should also accept async handlers. So this works without requiring nest_asyncio:

@app.on_event("startup")
async def system_startup():
        apobj = apprise.Apprise()
        await apobj.async_notify(body = "Application Startup", title = "startup failed")
        print("passed !")

It's a shame we've broken existing code, but fortunately, the fix should be simple: If running in an existing event loop, switch to the new async_notify() method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants