Alternative way to pass arguments to callback
See original GitHub issueCurrently to pass data between callbacks users need to use request.meta. Example from docs (simplified):
def parse_page1(self, response):
item = MyItem(main_url=response.url)
request = scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
request.meta['item'] = item
return request
def parse_page2(self, response):
item = response.meta['item']
item['other_url'] = response.url
return item
While it works fine, there are some issues:
- it seems understanding request.meta is a common struggle for beginners;
- we’re mixing parameters for Scrapy components with user data.
What about providing an alternative way?
def parse_page1(self, response):
item = MyItem(main_url=response.url)
return scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2,
kwargs={'item': item})
def parse_page2(self, response, item):
item['other_url'] = response.url
return item
Advantages:
- If you’re writing some extraction code without Scrapy (e.g. requests+lxml), then likely parsing functions have arguments. So this change makes code more natural/straightforward.
- Optional arguments or arguments with default values are easier to handle - just provide a default value using Python syntax.
- User state is separated from Scrapy internals better.
- Less code.
- One can see which data callback needs just by looking at callback definition.
- This way it is easier to add extra data to meta without a risk of breaking Scrapy extensions. There should be fewer bugs with missing
meta.copy()
. - In case of missing argument callback will fail earlier.
The implementation could add __kwargs
field to request.meta and pass **meta.get('__kwargs', {})
to the callback. Alternatively, we could put keyword arguments in another dict similar to meta. It will allow to separate them better. Also, rules for passing kwargs may be different from rules for passing meta (e.g. maybe meta should be preserved/copied in some cases, but not kwargs, I’m not sure).
Issue Analytics
- State:
- Created 8 years ago
- Reactions:17
- Comments:20 (11 by maintainers)
Top Results From Across the Web
JavaScript: Passing parameters to a callback function
Just use the bind() function which is primarily used to set the this value. However, we can also use it to pass parameters...
Read more >JavaScript | Passing parameters to a callback function
Approach : In this, The “GFGexample” is the main function and accepts 2 arguments, the “callback” is the second one. The logFact function...
Read more >Passing arguments to callback functions - Js Tips
Another method to do this is using the bind method. For example: var alertText = function(text) { alert(text); }; document.
Read more >Alternative ways to pass a callback to a function in Javascript
One method is about passing callback not before, but after the function execution. We can define an object in the function body, return...
Read more >How to pass a Variable or Argument to a callback function in ...
The assignment is simple. Search user with the name given, update the address of the user and print the user details after the...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hey @MaxValue! I think the original idea still stands, and has some support from Scrapy core developers (unless @dangra changed his opinion, it has +2 which is enough to merge a good implementation). I think it is better to be implemented by having a different Request attribute, not by storing data in meta[‘__kwargs’]. I don’t have time to work on it in near future myself; a pull request is welcome.
hello @jhirniak , there’s no progress as far as I know.
what do you mean by ?
There’s no immediate or short term plan from scrapy “core” devs to implement this feature. Contributions from the community are always welcome.