Skip to content

Change QueryParams(key=None) to not emit a parameter #154

Closed

Description

@StephenBrown2

This one I know is requests behaviour:

Take a dict:

>>> from httpx import QueryParams
>>> params = {"thing_one": 1, "thing_two": [1,2,3], "thing_three": None}
>>> QueryParams(params)
QueryParams('thing_one=1&thing_two=%5B1%2C+2%2C+3%5D&thing_three=None')

Expected:

QueryParams('thing_one=1&thing_two=%5B1%2C+2%2C+3%5D')

Adding if v is not None here will do it.

Activity

  1. sethmlarson commented on Jul 27, 2019

    @sethmlarson
    Contributor

    So there's an issue on the requests tracker where there's no interface for setting query parameters without a value. Cuz you can do {"q": ""} -> q= but there's no way to get just q followed by the next parameter. Requests can't make the change for None to be the interface for that behavior because it'd be a breaking change. Maybe we should look through that thread first before inheriting that interface.

  2. sethmlarson commented on Jul 27, 2019

    @sethmlarson
    Contributor

    Found the issue: psf/requests#2651
    I think None rendering as a valueless param is the best way suggested in that thread.

  3. StephenBrown2 commented on Jul 27, 2019

    @StephenBrown2
    ContributorAuthor

    Rats, I was relying on that behavior as well to remove a param that breaks the API I'm calling if it's provided but not in the right format, but I haven't tried it as a valueless param. I'll have to see if it breaks as a valueless param ?key= on Monday.

  4. changed the title [-]Ignore `None` QueryParams[/-] [+]Change QueryParams(key=None) to not emit a parameter[/+] on Jul 29, 2019
  5. lovelydinosaur commented on Jul 29, 2019

    @lovelydinosaur
    Member

    I think the desired behavior somewhat depends on how strict we want to be about types here, and if we're allowing type coercing of other non-str types.

    I think either of the two following options are reasonable choices:

    • Strictly type check, and only allow str types. Anything else raises a type error.
    • Allow primitive types only - str, int, float, Decimal, bool, None, with None -> "", True -> "true", False -> "false", and perhaps also enforcing isfinite() on floats. Date/Time/DateTime -> ISO formatted could also be okay at a pinch.

    I guess of those two options, the second probably plays more to Python's strengths? We could allow the same subset of types in urlencoded/multipart data too.

  6. StephenBrown2 commented on Jul 29, 2019

    @StephenBrown2
    ContributorAuthor

    I'm using Pydantic to roundtrip my params and standardize on values with custom validators/parsers: https://pydantic-docs.helpmanual.io/#json-serialisation so I'm sure some inspiration could be taken from that.

    I would not be opposed to the latter, especially since query params can imitate form data, they should also allow lists, and explode them since QueryParams is already a multi-dict. This however could be left up to the user.

  7. sethmlarson commented on Jul 29, 2019

    @sethmlarson
    Contributor

    Since I'm no longer on mobile and can type symbols easily I'm proposing:

    • {"q": "1"} -> ?q=1
    • {"q": ""} -> ?q=
    • {"q": None} -> ?q

    There are also instances where the order matters for the parameters, so maybe we need to allow typing.Iterable[typing.Tuple[typing.AnyStr, typing.AnyStr]] in addition to dict?

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions