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

Cloud Directory should accept None as NextToken #1421

Closed
tuukkamustonen opened this issue Jan 18, 2018 · 8 comments
Closed

Cloud Directory should accept None as NextToken #1421

tuukkamustonen opened this issue Jan 18, 2018 · 8 comments
Labels
closing-soon This issue will automatically close in 4 days unless further comments are made.

Comments

@tuukkamustonen
Copy link

Let's say your listing and index or something, and want to iterate the pages:

next = None
while True:
    resp = client.list_index(
        DirectoryArn='...',
        RangesOnIndexedValues=[...]
        IndexReference={'Selector': '..'},
        NextToken=next
    )
    next = resp.get('NextToken')
    if not next:
        break

The above doesn't work as boto doesn't accept None as NextToken value (it nags about it not being string, iirc). So I would have to:

next = None
while True:
    if next:
        resp = client.list_index(
            DirectoryArn='...',
            RangesOnIndexedValues=[...]
            IndexReference={'Selector': '..'},
            NextToken=next
        )
    else:
        resp = client.list_index(
            DirectoryArn='...',
            RangesOnIndexedValues=[...]
            IndexReference={'Selector': '..'}
            # omit it here
        )

    next = resp.get('NextToken')
    if not next:
        break

Which is pretty annoying. Workaround is to:

next = None
while True:
    params = dict(
        DirectoryArn='...',
        RangesOnIndexedValues=[...]
        IndexReference={'Selector': '..'}
    )
    if next_token:
        params['NextToken'] = next
    resp = client.list_index(**params)

    next = resp.get('NextToken')
    if not next:
        break

Which is pretty ugly, plus you lose auto-completion (which actually doesn't exist due to #1055).

@stealthycoin
Copy link
Contributor

Ideally this is where you would use a paginator to do this for you. It looks like there is no paginator for this operation at the moment but there is an open pull request for it here.

@stealthycoin stealthycoin added the closing-soon This issue will automatically close in 4 days unless further comments are made. label Jan 18, 2018
@tuukkamustonen
Copy link
Author

Thanks for the pointer. Haven't used paginators - will look into it.

However, for those who want to stay at slightly lower-level, couldn't this be supported?

@boltronics
Copy link

Just hit the same problem with https://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2

On an empty string:
botocore.exceptions.ClientError: An error occurred (InvalidArgument) when calling the ListObjectsV2 operation: The continuation token provided is incorrect

On None:
botocore.exceptions.ParamValidationError: Parameter validation failed: Invalid type for parameter ContinuationToken, value: None, type: <type 'NoneType'>, valid types: <type 'basestring'>

@boltronics
Copy link

Even setting the key prefix to None triggers an exception.
botocore.exceptions.ParamValidationError: Parameter validation failed: Invalid type for parameter Prefix, value: None, type: <type 'NoneType'>, valid types: <type 'basestring'>

@JordonPhillips
Copy link
Contributor

The reason why None is that there can be a difference between not passing a value and explicitly specifying None. Unfortunately we cannot change this behavior.

As John mentioned, I would highly recommend using the paginator that got merged in to handle this for you.

@tuukkamustonen
Copy link
Author

tuukkamustonen commented Feb 21, 2018

The reason why None is that there can be a difference between not passing a value and explicitly specifying None. Unfortunately we cannot change this behavior.

Java and JavaScript SDKs accept null as NextToken - I believe they just exclude it from the request. Why should python SDK be any different?

I would highly recommend using the paginator that got merged in to handle this for you.

Yeah, the paginators work nicely! But sometimes you want to do custom stuff, stay lower level, etc.

@rkiyanchuk
Copy link

rkiyanchuk commented Oct 19, 2018

@JordonPhillips Paginators are not provided for all services in boto, so it's not a generic solution.

What is the use case for being able to tell between value not being specified and explicitly set to None? Why would the lower level code care about such difference?

It is common practice in Python to use None specifically in such situations for keyword arguments, as it helps to avoid ugly overly verbose code.

It is also very confusing that some functions allow NextToken to be set to empty string (describe_instances, describe_security_groups) while others don't (describe_flow_logs).

@SamStephens
Copy link

Just want to express my disappointment at this decision. How can there be a difference between not passing a value and explicitly specifying None, when None explicitly represents the "absence of a value", and is designed for exactly this kind of usage? If there is a difference, that should be considered a bug and removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closing-soon This issue will automatically close in 4 days unless further comments are made.
Projects
None yet
Development

No branches or pull requests

6 participants