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

Feat/generics request #107

Merged
merged 15 commits into from
May 30, 2024
Merged

Conversation

pedroimpulcetto
Copy link
Contributor

@pedroimpulcetto pedroimpulcetto commented May 28, 2024

Implementing Generics type hint to avoid using "Any".

The main purpose of this PR is to avoid using "Any" inside Request.perform()

Now Request class is a Generic class Request(Generic[T]), with that we can mark the perform method to return a specific type.

Example:

For this example
So Request[Email] will return an Email type

request.Request[Email]

And we can make sure the resp variable is an Email

resp = request.Request[Email](
            path=path,
            params=cast(Dict[Any, Any], params),
            verb="post",
        ).perform_with_content()

Because perform_with_content is returning a generic type T

def perform_with_content(self) -> T:
    ...

perform_with_content is a method the wrap perform method to check if the return is not None and we can make sure the return type is a generic T


So after that we can work to include right types to return and fix this issue: #105

@pedroimpulcetto
Copy link
Contributor Author

I would like to implement a new perform method to use and avoid the duplication code to verify if the response is None

To avoid this:

if resp is None:
    raise NoContentError()

I was thinking of having something like this:

@staticmethod
def perform_with_content(
    path: str,
    params: Dict[Any, Any],
    verb: RequestVerb,
) -> T:
    resp = Request[T](
        path=path,
        params=params,
        verb=verb,
    ).perform()
    if resp is None:
        raise NoContentError()
    return resp

Because most of our resources should return content like email, domain, etc... only deleteapikey doesn't need to return content.

With that, we can make sure the response will be of the type expected.

As an example the Emails.send(...) will be:

 @classmethod
    def send(cls, params: SendParams) -> Email:
        """
        Send an email through the Resend Email API.
        see more: https://resend.com/docs/api-reference/emails/send-email

        Args:
            params (SendParams): The email parameters

        Returns:
            Email: The email object that was sent
        """
        path = "/emails"
        resp = request.Request[Email].perform_with_content(
            path=path,
            params=cast(Dict[Any, Any], params),
            verb="post",
        )
        return resp

@pedroimpulcetto pedroimpulcetto marked this pull request as ready for review May 29, 2024 19:32
Copy link
Collaborator

@drish drish left a comment

Choose a reason for hiding this comment

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

this lgtm, thanks @pedroimpulcetto

@drish drish merged commit 1367cfd into resend:main May 30, 2024
10 checks passed
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