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(parser): use str for SES EmailStr when email_validator package is omitted #1259

Closed

Conversation

mgochoa
Copy link
Contributor

@mgochoa mgochoa commented Jun 23, 2022

Issue number: #998

Summary

When email_validator package is not present in the dependencies, pydantic.networks.EmailStr will fail not when imported, but when it's used for typing check. Because inside pydantic.networks.EmailStr, there is a function import_email_validator which will try to import email_validator dinamically.

Changes

In aws_lambda_powertools/utilities/parser/models/ses.py :

has_email_validator = "email_validator" in sys.modules

if has_email_validator:
    from pydantic.networks import EmailStr
else:
    logging.warning("email_validator package is not installed")
    EmailStr = NewType("EmailStr", str)  # type: ignore[no-redef, misc]

It means, now is checking for email_validator package, and defines conditionally which type it should take

User experience

Use could perform:

import pydantic
from aws_lambda_powertools.utilities import batch

without unexpected behavior such as:
ImportError: email-validator is not installed, run 'pip install pydantic[email]'

Checklist

If your change doesn't seem to apply, please leave them unchecked.

Is this a breaking change?

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@pull-request-size pull-request-size bot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Jun 23, 2022
@boring-cyborg
Copy link

boring-cyborg bot commented Jun 23, 2022

Thanks a lot for your first contribution! Please check out our contributing guidelines and don't hesitate to ask whatever you need.

@mgochoa
Copy link
Contributor Author

mgochoa commented Jun 23, 2022

This is my first PR on a Open Source tool, If guidance is available I'm open to take what's necessary to make this PR cleaner, and compliant.

@heitorlessa
Copy link
Contributor

Hey @mgochoa thanks a lot for taking the time to add this guard. More importantly, your first PR 🎉 !

without unexpected behavior such as:

This is actually the intended behaviour because when installing parser it'll install email-validator package. As per the issue you referenced, this only happens for customers not following our recommended installation.

That being said, I can see this will continue to happen so best to add this small fix before we tackle it long-term. I'm making two small adjustments and we should be able to merge :)

@heitorlessa heitorlessa changed the title feature(parser): handle when email_validator package is not present for SES model feat(parser): use str for SES EmailStr when email_validator package is omitted Jun 27, 2022
Copy link
Contributor

@heitorlessa heitorlessa left a comment

Choose a reason for hiding this comment

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

two comments on checking email_validator being installed vs imported and minor optimizations.

if has_email_validator:
from pydantic.networks import EmailStr
else:
logging.warning("email_validator package is not installed")
Copy link
Contributor

Choose a reason for hiding this comment

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

Initialize a logger and change it to debug, so we'll know where it comes from.

logger = logging.getLogger(__name__)

...
logger.debug("email_validator package is not installed; using str instead")

from pydantic.networks import EmailStr
else:
logging.warning("email_validator package is not installed")
EmailStr = NewType("EmailStr", str) # type: ignore[no-redef, misc]
Copy link
Contributor

Choose a reason for hiding this comment

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

NewType has recently been converted to a class which means it'll have a runtime impact. Since we're looking at a string only IF someone didn't follow our recommended install, use a Type Alias instead.

You can also bring this up to save a else branch, for example:

from pydantic import BaseModel 


EmailStr = str

if has_email_validator:
    from pydantic import EmailStr


class Email(BaseModel):
        address: EmailStr


feedback_channel = Email("aws-lambda-powertools-feedback@amazon.com")
print(feedback_channel.address)

from pydantic.types import PositiveInt

from ..types import Literal

has_email_validator = "email_validator" in sys.modules
Copy link
Contributor

@heitorlessa heitorlessa Jun 27, 2022

Choose a reason for hiding this comment

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

I suspect this will always be False because Pydantic is loading it dynamically, and this will only be true afterwards. You'll need to check if the module is actually installed instead of loaded - I can't recall by heart a 3.6+ compatible way in importlib/pkg_resources to do that. I can help look for that after I finish another doc PR this week

from pydantic.types import PositiveInt

from ..types import Literal

has_email_validator = "email_validator" in sys.modules

if has_email_validator:
Copy link
Contributor

Choose a reason for hiding this comment

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

we're gonna need #pragma: nocover too because this will decrease our tests despite being intended behaviour ;-)

@heitorlessa heitorlessa force-pushed the develop branch 3 times, most recently from 42c2896 to 06965bb Compare July 11, 2022 16:49
@github-actions github-actions bot added the feature New feature or functionality label Jul 13, 2022
@heitorlessa heitorlessa force-pushed the develop branch 2 times, most recently from 742ccf5 to b582992 Compare July 13, 2022 11:59
@mgochoa mgochoa requested a review from a team as a code owner July 29, 2022 14:51
@mgochoa mgochoa requested review from am29d and removed request for a team July 29, 2022 14:51
@heitorlessa heitorlessa added the need-more-information Pending information to continue label Aug 2, 2022
@rubenfonseca
Copy link
Contributor

Hi @mgochoa thank you again so much for this PR! Any change you could incorporate the review feedback so we can merge this?

@heitorlessa heitorlessa linked an issue Oct 18, 2022 that may be closed by this pull request
2 tasks
@heitorlessa
Copy link
Contributor

@mgochoa we're going to close this PR and credit you in #1607 for kicking the tires here, as we need to make a V2 release this week.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or functionality need-more-information Pending information to continue size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Maintenance: Remove email-validator dependency for v2
3 participants