0

I have come across this issue, where I want to return something and call another function afterwards (in python)

heres my current code:

def new_user(request):
'''Takes a request and enters it in the database IF that wallet id is not in the database! '''
data = request.body
if data != '':
    user_info = eval(data)
    if type(user_info) != type({}):
       ... more code here ...
                send_email(vCode)
                return HttpResponse(response)

I want to call send_email after returning a response. I have tried a few things here: -calling both new_user and send_email in another function but I need to return some sort of HttpResponse (so I can't call new_user without returning it...) so this does not work - tried to yield a request, cannot call another function after yield -tried threading, had a similar issue -Currently trying asyncio but i'm running into issues with that aswell, is there anything else I can do?

2
  • 3
    What observable difference would there be compared to doing what you do now (i.e., calling send_email just before returning)? Commented Sep 4, 2018 at 19:29
  • 1
    so the issue with calling send_email before returning an HttpResponse was that send email takes 30seconds-1 minute to execute and over all slows down my function new_user, the user waits for new_user to execute so it is annoying to wait over a minute to get a response... over all send_email was just slow Commented Sep 5, 2018 at 13:57

3 Answers 3

2

The only way I know to achieve this would be to run the function in another thread. You say you've tried that but had no success but didn't provide an example of what you tried. Below is an example of code which should work

import threading
...
def new_user(request):
'''Takes a request and enters it in the database IF that wallet id is not in the database! '''
data = request.body
if data != '':
    user_info = eval(data)
    if type(user_info) != type({}):
       ... more code here ...
                task = threading.Thread(target=send_email, args=(vCode,))
                task.daemon = True
                task.start()
                return HttpResponse(response)

Note: you need to mark this thread as a daemon so that python doesn't wait for it to be joined before closing. Since you're spinning this off to be run after your code finishes this is a necessary step.

Another option is to use some sort of task queue and send it off to be processed which you also say you're trying to do with asyncio. In a larger application that would be the better option.

Sign up to request clarification or add additional context in comments.

5 Comments

@rabiaasif, if this is the solution to your problem it is extremely likely that you have a much bigger problem. Unfortunately, you never responded to chepner's helpful question. If you had, we might have been able to help you with that bigger problem.
I don't understand why using threading would be a bigger problem?
@rabiaasif, (a) a view function probably isn't the right place to use multithreading and (b) chepner's question was valid and unanswered until just now. If you had asked about your actual problem (the time it takes to send email) instead of what you thought the solution was (sending email after returning; please read the XY problem link I provided) we might have suggested a better solution. For example, a scheduled job could be set up to send queued email. Or we could dig into why your mail takes so long to send.
I too think it would be good to see why sending an email takes so long... or move forward with a task queue, this is a very hacky solution. But if you're just writing a small script this should work fine...
I see your point, that was not something I thought of before... I am using smtplib, MIMEMultipart, MIMEText, MIMEImage these for python I don't do anything other than attach an image, and write a short message, so I dont see why this would be really slow or what I am doing to make it slow....
1

After your function Returns, you can't execute extra code in the same view. If your email has to be sent after the return, you could return a redirect return redirect(new_view_to_send_email) from your function to a new function that sends the email.

3 Comments

So if I dont return an HttpResponse, my page crashes (I'm using django!)
Yes, it does. You need to either return an httpresponse or redirect to a view that returns an httpresponse. In this case, the redirect function should send your email and then return an httpresponse
After reading that the problem comes from the time it takes your system to send an email, queueing is your best choice. [link](www.celeryproject.org) is a great place to start, and although somewaht complex, it is easy to start using it.
-2

You could use lamda

lambda: return HttpResponse(response),
        send_email(vCode)

3 Comments

return can't be used inside a lambda expression in Python. Even if this was valid, would it make sense for a return here to return from new_user? Probably not.
yeah, this was the problem, you cant execute code after a return statement so lamda does not work! :(
@rabiaasif, it would be helpful if you answered chepner's question above. What are you hoping to accomplish by doing this? You almost certainly have an XY problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.