omarryhan/aiogoogle

Add argument to request to ignore HTTP code 400

Closed this issue · 7 comments

I am trying to use the package for purchase token validation and invalid tokens return an HTTP code of 400.
androidpublisher v3, purchases.products.get

In my usecase, this is expected and nothing I would want the execution to fail on. I don't think there is a way of allowing a response of 400 right now, so I've been monkey patching the aiogoogle.models.Response.raise_for_status method for now.

Would be great if you could provide this option - happy to do it myself when I find some time as well.

Hey @Gitznik

Why not just catch the HTTP error? e.g.

try:
  response = await as_user(...)
except aiogoogle.excs.HTTPError as e:
  print(e.res)

This is the signature of the error:

class HTTPError(AiogoogleError):
    def __init__(self, msg, req=None, res=None):
        self.req = req
        self.res = res
        super().__init__(msg)

I have several tens of thousands of purchases to validate per day, so I have to generate the tasks dynamically and I don't want the entire process if there is one error.
Or am I misunderstanding how the code works and I can catch the error like you proposed and all other requests would continue?

(See my function attached, I figured out that if I set full_res=True, the raise_for_status call is not made, so this works now for me.)

async def verify_purchase(data_list):
    async with Aiogoogle(
        service_account_creds=creds
    ) as aiogoogle:
        publisher_api = await aiogoogle.discover('androidpublisher', 'v3')
        requests = []
        for data in data_list:
            conf = json.loads(data)
            requests.append(
                publisher_api.purchases.products.get(
                    token=conf['TRANSACTION_ID'],
                    productId=conf['PRODUCT_ID'],
                    packageName=conf['PACKAGE_NAME']
            ))
        validation_result = await aiogoogle.as_service_account(
            *requests,
            full_res=True
        )
    return validation_result

Oh, gotcha. Glad this works for you. I have to say that full_res not calling raise_for_status is more of an implementation detail. However, I'm not planning to change it. If you still want to add an explicit raise_for_status flag, I'm open for it. But then we'll have to bump up a major version, because we'll have to make both full_res=True and full_res=False both call res.raise_for_status, which will break some of our existing users' apps e.g. yours.

Example:

        validation_result = await aiogoogle.as_service_account(
            *requests,
            full_res=True,
            raise_for_status=False  # will default to True
        )

Maybe adding this detail to the documentation of the full_res flag would be a good and quick solution for now as well, so it's easier to find.

If you agree I'll create an MR for it.

Agreed. A lot less invasive this way. A MR would be great, thanks!

Actually, I just found out that that raise_for_status is always called. I was still using the monkey patched version when I was trying this out this afternoon.
This enables me to add the flag though without introducing a breaking change, so I'll try and do the in the next few days. The flag already exists in the send methods, so I think it should just be a matter of handing this flag over from the respective as_xxx methods