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

There doesn't seem to be a way of robustly relying on library's types for API responses #1344

Open
matt-dalton opened this issue Jun 10, 2024 · 2 comments

Comments

@matt-dalton
Copy link

Describe the bug

As described in this issue we can use either python dot or dict notation for accessing API response values.

For the types included in the library, dot notation successfully returns the correct types:
Screenshot 2024-06-10 at 16 30 43

whereas using dict notation results in everything you access being set to Any
Screenshot 2024-06-10 at 16 31 36

This is fine, however there's an issue with using dot notation (also mentioned in the other issue) where calling subscription.items results in a crash because it tries to access dict's items() function instead.

This means the types can't be relied upon. It also means there's no way of using the types without people knowing they need to access items in a different way.

Is there a workaround for this? Or a fix?

To Reproduce

  1. Use a python type checking system (we use pyright)
  2. Try and access the plan object from a subscription response using plan = subscription.items.data[0].plan. It will crash, but the plan type will be set correctly
  3. Instead, try accessing using plan = subscription['items']['data'][0]['plan']. It will work, but the types will be wrong.

Expected behavior

At least one of the following should be happen (ideally both):

  • The types should fail when accessing items using dot notation
  • The types should return the correct value when using dict notation

Code snippets

No response

OS

macOS

Language version

python 3.8.10

Library version

stripe-python 7.14.0

API version

2023-10-16

Additional context

No response

@ramya-stripe
Copy link
Contributor

Thanks for reporting @matt-dalton

We are aware of this issue and it is in our backlog to address it.

@kurtbrose
Copy link

what I've done locally for this is:

    # this _technically_ exists, but is inaccessible because it collides with dict.items(), so you have to
    # use the __getitem__ method to access it
    # items: list[StripeSubscriptionItem]  # the items included in this subscription (prices live here)

    def __getitem__(self, item: typing.Literal["items"]) -> StripeList[SubscriptionItem]:
        pass

(This comes up for SubscriptionSchedulePhase too, and possibly other places.)

In our codebase we want to use dot notation for all cases unless we are forced to use []; unfortunately for the more general case this would be much more of a PITA.

   @overload
   def __getitem__(self, item: Literal["items"] -> List[SubscriptionItem]:
      ...
   
   @overload
   def __getitem__(self, item: Literal["customer"] -> str | Customer:
      ...

and so on for each field; maybe this is feasible if these types are all auto generated rather than hand maintained

good luck!

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

No branches or pull requests

3 participants