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

Add type hints to base and authentication #472

Merged
merged 10 commits into from
May 9, 2023

Conversation

Viicos
Copy link
Contributor

@Viicos Viicos commented Feb 19, 2023

Fixes partially #470.
The goal is not to add complete type hints to the library, but only were it is beneficial. There are some code patterns that break mypy rules (e.g. Liskov substitution principle), and I'm not aiming at doing refactors, so once most of the type hints will be added, I'll write a mypy configuration accordingly.

I'm going for the from __future import annotations import, to improve type hints readability.

Noticed a couple things:

  • This has been introduced two years ago, should it be deprecated now?

    auth0-python/auth0/rest.py

    Lines 108 to 111 in 44d6d0e

    # For backwards compatibility reasons only
    # TODO: Deprecate in the next major so we can prune these arguments. Guidance should be to use RestClient.options.*
    self.telemetry = options.telemetry
    self.timeout = options.timeout

  • Could these methods be transformed into properties/class variables?

    auth0-python/auth0/rest.py

    Lines 113 to 127 in 44d6d0e

    # Returns a hard cap for the maximum number of retries allowed (10)
    def MAX_REQUEST_RETRIES(self):
    return 10
    # Returns the maximum amount of jitter to introduce in milliseconds (100ms)
    def MAX_REQUEST_RETRY_JITTER(self):
    return 100
    # Returns the maximum delay window allowed (1000ms)
    def MAX_REQUEST_RETRY_DELAY(self):
    return 1000
    # Returns the minimum delay window allowed (100ms)
    def MIN_REQUEST_RETRY_DELAY(self):
    return 100

@Viicos Viicos requested a review from a team as a code owner February 19, 2023 11:54
@Viicos Viicos marked this pull request as draft February 19, 2023 11:54
@adamjmcgrath
Copy link
Contributor

Hi @Viicos - thanks for raising these PRs

I've been away and am still catching up, so will take a look at them next week 👍

@adamjmcgrath
Copy link
Contributor

Thanks @Viicos - this PR looks good - just need to fix the build

This has been introduced two years ago, should it be deprecated now?

I should have done it when I did the last major, but I missed it - will have to wait until the next major

Could these methods be transformed into properties/class variables?

Sure, but I'll need to look at this in the next major

@Viicos
Copy link
Contributor Author

Viicos commented Mar 13, 2023

Understandable as this would be a breaking change. I'll continue to add some type hints while still being careful not to overwhelm the code base (I'll rebase this one to get the CI fix from master)

@adamjmcgrath
Copy link
Contributor

Hi @Viicos - is adding type hints a breaking change, I thought since the project was now >=3.7 this could be introduced in a non breaking way?

@Viicos
Copy link
Contributor Author

Viicos commented Mar 13, 2023

Hi @Viicos - is adding type hints a breaking change, I thought since the project was now >=3.7 this could be introduced in a non breaking way?

Hi, sorry I was replying to your answer regarding the second point I asked in this PR description:

Could these methods be transformed into properties/class variables?

Switching to properties would be a breaking change as using RestClient().MAX_REQUEST_RETRIES() would result in a TypeError. Regarding type hints it's not breaking anything indeed if using Python>3.5

@Viicos
Copy link
Contributor Author

Viicos commented Mar 14, 2023

I think I'll probably make another PR regarding the management module for simplicity. The only things left on this one:

  • Fix doc build error
  • Define better return types for authentification classes: To keep things simple, I'll only return the general type, e.g. dict[str, Any] or str and will not make use of TypedDict.

@Viicos
Copy link
Contributor Author

Viicos commented Mar 15, 2023

I still have a few mypy errors to correct, but in the meanwhile I noticed a few optionals that shouldn't be:

  • def _fetch_key(self, key_id=None):
    return self._fetcher.get_key(key_id)

    _fetcher is of type JwksFetcher, and get_key excepts key_id to be a string, not str | None.

  • def create_client_assertion_jwt(
    domain, client_id, client_assertion_signing_key, client_assertion_signing_alg
    ):
    """Creates a JWT for the client_assertion field.
    Args:
    domain (str): The domain of your Auth0 tenant
    client_id (str): Your application's client ID
    client_assertion_signing_key (str, optional): Private key used to sign the client assertion JWT
    client_assertion_signing_alg (str, optional): Algorithm used to sign the client assertion JWT (defaults to 'RS256')
    Returns:
    A JWT signed with the `client_assertion_signing_key`.
    """
    client_assertion_signing_alg = client_assertion_signing_alg or "RS256"
    now = datetime.datetime.utcnow()
    return jwt.encode(
    {
    "iss": client_id,
    "sub": client_id,
    "aud": f"https://{domain}/",
    "iat": now,
    "exp": now + datetime.timedelta(seconds=180),
    "jti": str(uuid.uuid4()),
    },
    client_assertion_signing_key,
    client_assertion_signing_alg,
    )

    jwt.encode excepts client_assertion_signing_key to be a string, not str | None.

  • async def file_post(self, url, data=None, files=None):
    headers = self.base_headers.copy()
    headers.pop("Content-Type", None)
    return await self._request("post", url, data={**data, **files}, headers=headers)

    data and files can't be None here, as {**data, **files} would fail otherwise.

I'll let you decide on these three cases what should be done (e.g. removing the default None values)

@adamjmcgrath
Copy link
Contributor

Thanks for spotting those @Viicos! You can make them all required arguments 👍

@Viicos Viicos changed the title Add type hints Add type hints to base and authentication Mar 19, 2023
@Viicos Viicos mentioned this pull request Mar 19, 2023
@Viicos
Copy link
Contributor Author

Viicos commented Mar 20, 2023

Had to ignore a few mypy error codes to avoid having to refactor some parts, but otherwise looks good. Some API return types have been left to Any, as the openapi docs doesn't specify any return examples

@Viicos
Copy link
Contributor Author

Viicos commented Mar 27, 2023

@adamjmcgrath I think this one is ready. I have a failing test on 3.10 due to this error on docs:

/home/circleci/project/auth0/authentication/token_verifier.py:docstring of auth0.authentication.token_verifier.JwksFetcher.get_key:1: WARNING: py:class reference target not found: RSAPublicKey

Do you happen to know how this can be fixed?

@adamjmcgrath
Copy link
Contributor

Hi @Viicos - it looks like you can ignore this warning in the Sphinx config https://stackoverflow.com/a/30624034

@Viicos Viicos marked this pull request as ready for review April 5, 2023 19:47
@Viicos
Copy link
Contributor Author

Viicos commented Apr 11, 2023

Hi @adamjmcgrath, in case you did not get notified, this one is ready for review/merge

@adamjmcgrath
Copy link
Contributor

Thanks @Viicos - I'll take a look this week

@adamjmcgrath
Copy link
Contributor

lgtm, thanks @Viicos - can you just resolve that conflict and I'll approve and merge 👍

@Viicos
Copy link
Contributor Author

Viicos commented May 5, 2023

@adamjmcgrath If the last edit @b8a4a2c is good, I think this can be merged

Copy link
Contributor

@adamjmcgrath adamjmcgrath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Viicos!

@adamjmcgrath adamjmcgrath merged commit 38f65c2 into auth0:master May 9, 2023
1 check passed
@adamjmcgrath adamjmcgrath mentioned this pull request Jun 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants