Python wrapper causes redundant function calls












0















I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().



from requests import get
...

def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)

def main(url):
...
download_file(url)


However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.



def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download


As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.



I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?



PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.










share|improve this question

























  • My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.

    – wim
    Nov 28 '18 at 22:02













  • @wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion

    – babrar
    Nov 28 '18 at 22:03













  • Then I think the MCVE is not good. Whether you want to re-raise or handle error from requests.get is an important high-level question that shouldn't be glossed over.

    – wim
    Nov 28 '18 at 22:05











  • @wim made request.get error checks more abstract

    – babrar
    Nov 28 '18 at 22:21
















0















I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().



from requests import get
...

def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)

def main(url):
...
download_file(url)


However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.



def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download


As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.



I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?



PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.










share|improve this question

























  • My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.

    – wim
    Nov 28 '18 at 22:02













  • @wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion

    – babrar
    Nov 28 '18 at 22:03













  • Then I think the MCVE is not good. Whether you want to re-raise or handle error from requests.get is an important high-level question that shouldn't be glossed over.

    – wim
    Nov 28 '18 at 22:05











  • @wim made request.get error checks more abstract

    – babrar
    Nov 28 '18 at 22:21














0












0








0








I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().



from requests import get
...

def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)

def main(url):
...
download_file(url)


However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.



def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download


As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.



I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?



PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.










share|improve this question
















I have a function that downloads a file from a given url and, is called from a higher level function, i.e. main().



from requests import get
...

def download_file(url):
response = get(url)
...
<error checks on response>
...
# if no error, write response to file
...
file.write(response)

def main(url):
...
download_file(url)


However, I realized that I should place all the error checks for the response object outside the download_file function. So, I tried wrapping the download_file function so that all the error checks happen outside it.



def check_errors(func):
def check_and_download(url):
response = get(url)
...
<error checks on response>
...
return func(url) # <- I have to call response = get(url) again. That's bad
return check_and_download


As you can see, that wrapper causes the response to get called twice. Once outside the func, and once inside it. That's just redundant. I'm trying to figure out a way that will allow me to call response only once and download the file while having the error checks outside the download_file function.



I feel like this should be a common problem for beginners, but couldn't find relevant questions here. Any suggestions on how to properly deal with this?



PS: One approach I took was to modify the download_file function to accept a response object instead or a url, so that the wrapper could pass an error-checked response object to it. However, the problem then is that the download_file function must be called with a response object in main(). Which would require me to check the response object for errors in main() instead of the wrapper.







python-3.x python-requests wrapper urllib3






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 '18 at 22:21







babrar

















asked Nov 28 '18 at 21:58









babrarbabrar

257




257













  • My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.

    – wim
    Nov 28 '18 at 22:02













  • @wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion

    – babrar
    Nov 28 '18 at 22:03













  • Then I think the MCVE is not good. Whether you want to re-raise or handle error from requests.get is an important high-level question that shouldn't be glossed over.

    – wim
    Nov 28 '18 at 22:05











  • @wim made request.get error checks more abstract

    – babrar
    Nov 28 '18 at 22:21



















  • My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.

    – wim
    Nov 28 '18 at 22:02













  • @wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion

    – babrar
    Nov 28 '18 at 22:03













  • Then I think the MCVE is not good. Whether you want to re-raise or handle error from requests.get is an important high-level question that shouldn't be glossed over.

    – wim
    Nov 28 '18 at 22:05











  • @wim made request.get error checks more abstract

    – babrar
    Nov 28 '18 at 22:21

















My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.

– wim
Nov 28 '18 at 22:02







My design advice is: don't catch an exception just to raise another exception. If you can't handle the error, then leaving the original exception and traceback intact is generally more useful.

– wim
Nov 28 '18 at 22:02















@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion

– babrar
Nov 28 '18 at 22:03







@wim I know, I didn't do that in my actual code (wrote a comment). it's just for simplicity while explaining. i'll edit my snippet to remove the confusion

– babrar
Nov 28 '18 at 22:03















Then I think the MCVE is not good. Whether you want to re-raise or handle error from requests.get is an important high-level question that shouldn't be glossed over.

– wim
Nov 28 '18 at 22:05





Then I think the MCVE is not good. Whether you want to re-raise or handle error from requests.get is an important high-level question that shouldn't be glossed over.

– wim
Nov 28 '18 at 22:05













@wim made request.get error checks more abstract

– babrar
Nov 28 '18 at 22:21





@wim made request.get error checks more abstract

– babrar
Nov 28 '18 at 22:21












0






active

oldest

votes












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53528749%2fpython-wrapper-causes-redundant-function-calls%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53528749%2fpython-wrapper-causes-redundant-function-calls%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Lallio

Futebolista

Jornalista