Skip to content

Handling filters with None #371

Closed

Description

@joaquinvanschoren

Passing a None object as a filter argument on listing calls seems to ignore the filter rather than returning no results.
E.g. list_evaluations(setup=setuplist) where setuplist happens to be None will happily download ALL OpenML evaluations (when placed in a paging loop).

Indeed, the code says:

def list_evaluations(function, offset=None, size=None, id=None, task=None,
                     setup=None, flow=None, uploader=None, tag=None):
    if setup is not None:
        api_call += "/setup/%s" % ','.join([str(int(i)) for i in setup])

It would be safer to actually check whether the argument was passed? This can be done with kwargs: https://stackoverflow.com/questions/14749328/python-how-to-check-whether-optional-function-parameter-is-set

What do you think? This actually happened to me by mistake (I assumed all studies have a list of setups - not) and I only noticed after downloading 1.3 million evaluations.
Normally you wouldn't worry too much about stupid user mistakes, but in this case it stresses the server. Maybe adding it just for the listing calls isn't the worst idea.

Activity

  1. added
    Good First IssueIssues suitable for people new to contributing to openml-python!
    on Jan 15, 2019
  2. chouhanaryan commented on Oct 18, 2020

    @chouhanaryan
    Contributor

    Hi, is this still open? Could you point me towards the relevant code? I'd like to contribute, thanks.

  3. PGijsbers commented on Oct 19, 2020

    @PGijsbers
    Collaborator

    Hi @chouhanaryan, thanks for taking an interest! Let me clarify some things with other OpenML members to see how we would like to see this issue addressed.

    @joaquinvanschoren @mfeurer
    I understand that user errors may specify list_evaluations without filters unintentionally (i.e. as in the original post your variable is None when you don't expect it to). I don't think that @joaquinvanschoren's solution would work. When list_evaluations(setups=setuplist) is used with setuplist=None, we still see setups as being explicitly set (to None). The second disadvantage of using kwargs is, as far as I am aware, that intellisense type features as well as type checking are not compatible with it. We could use key-word only arguments to mitigate this, but it does not solve the underlying issue: if setuplists is None then all evaluations are still downloaded.

    I think there are two straight-forward ways to avoid accidentally downloading all evaluations:

    1. Set a numeric default for size (e.g. 10_000, I don't know what's reasonable), or
    2. Check that at least one argument is not None when list_evaluations is called. In case all arguments are None, either set a default size, or raise an exception (users wanting to download all results can still do so by setting size to a high number like 100M).

    I think I would be in favor of option 1, it's straight forward and easy to explain. It will also throttle other (perhaps unexpectedly large) queries.

  4. mfeurer commented on Oct 19, 2020

    @mfeurer
    Collaborator

    Option 1 appears reasonable to me.

  5. PGijsbers commented on Oct 20, 2020

    @PGijsbers
    Collaborator

    @chouhanaryan If you still feel up for the task, then you can get started with changing the default size for list_evaluations. This includes:

    • changing the default value for the parameter
    • updating the documentation of the function (please also add that setting size to None removes a limit to the number of results returned).
    • updating other documentation (e.g. the examples) that use the function if necessary
    • checking the usage in the project (e.g. for PyCharm see Find Usage), and check whether or not the size should be set back to None for those usages. This includes usages in unit tests (i.e. change them where it would fail otherwise, or where it looks reasonable that >10_000 results are expected).

    If you have any questions, feel free to ask!

    @mfeurer I think it makes sense to ask the same for list_evaluations_setups?

  6. mfeurer commented on Oct 20, 2020

    @mfeurer
    Collaborator

    The more I think about this, the less I actually like the fact that we change the behavior of a few listing call while keeping the other listing calls return everything. Therefore, I would prefer to for now restrict this to only list_evaluations until we (hopefully) find a better solution.

  7. PGijsbers commented on Oct 21, 2020

    @PGijsbers
    Collaborator

    Works for me. Though I don't think it is unreasonable to add an (equal) max size to each listing call. Perhaps make it a bit higher (e.g. 100_000) so that only the most demanding calls will need to overwrite it.

  8. mfeurer commented on Oct 21, 2020

    @mfeurer
    Collaborator

    Is there a chance to find out how many elements are online via an API call? If yes, we could emit a warning in case a user requests too few elements.

  9. chouhanaryan commented on Oct 21, 2020

    @chouhanaryan
    Contributor

    Hi! Sorry for the delay. I've been a bit busy. I'll work on this over the weekend.

    Unfortunately I don't use PyCharm so I'm not sure if I can complete the fourth task you mentioned @PGijsbers , but I'll try to find an alternative.

    Thanks!

  10. PGijsbers commented on Oct 21, 2020

    @PGijsbers
    Collaborator

    @mfeurer
    I think the warning can make sense specifically only when we see that NUM results are returned, where NUM is whatever default maximum we decide on. I.e., assuming 10_000 is our default max:

    • list_datasets(size=10) does not omit a warning, despite more results being available
    • list_evaluations(size=1_000_000) does not omit a warning, despite more results being available
    • list_evaluations() does omit a warning, because 10_000 amount of results are returned and size was left at 10_000.

    It would be trivial to check this scenario (len(results)==NUM). The only issue is that we can not detect if size was set to NUM explicitly or by default. I think it's fine to ignore this (and omit a warning even if list_evaluations(size=10_000) is called).

    I am not aware of a call that allows you to see how large the results could be. But I'm not convinced it's worth the trouble to add it. Just state clearly that only 10_000 results (or whatever number we agree on) are returned by default.

    @chouhanaryan Great to hear you're still interested! Most editors allow you to search all files (often ctrl+shift+F), which would also be suitable 👍 Let us know if you run into any issues.

  11. mfeurer commented on Oct 21, 2020

    @mfeurer
    Collaborator

    I am not aware of a call that allows you to see how large the results could be. But I'm not convinced it's worth the trouble to add it. Just state clearly that only 10_000 results (or whatever number we agree on) are returned by default.

    Then I guess we'll go with the easy solution proposed.

  12. PGijsbers commented on Oct 21, 2020

    @PGijsbers
    Collaborator

    Then I guess we'll go with the easy solution proposed.

    To clarify, with or without warning? I don't feel strongly for adding a warning as long as the documentation is clear. But it's not an issue to me to have it added either.

    We could also consider having a release that does not change behavior but issues a FutureWarning indicating the default will change. Personally I don't feel the change is invasive enough to skip a release cycle, but we have no numbers to back this up.

  13. mfeurer commented on Oct 21, 2020

    @mfeurer
    Collaborator

    Sorry, without a warning. I'd also go without a FutureWarning.

  14. PGijsbers commented on Oct 21, 2020

    @PGijsbers
    Collaborator

    @chouhanaryan For clarification, these are the final proposed changes to resolve this issue. The discussion after can be ignored as it did not lead to changes in the requirements.

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

Metadata

Metadata

Assignees

Labels

Good First IssueIssues suitable for people new to contributing to openml-python!

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions