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

Fix #611: ContactSchema now reflects what is stored in database #711

Merged
merged 8 commits into from
Jun 28, 2023
20 changes: 9 additions & 11 deletions ctms/acoustic_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from ctms.background_metrics import BackgroundMetricService
from ctms.config import re_trace_email
from ctms.schemas import ContactSchema, NewsletterSchema
from ctms.schemas import ContactTableSchema, NewsletterSchema

# Start cherry-picked from django.utils.encoding
_PROTECTED_TYPES = (
Expand Down Expand Up @@ -140,7 +140,7 @@ def __init__(

def convert_ctms_to_acoustic(
self,
contact: ContactSchema,
contact: ContactTableSchema,
main_fields: set[str],
newsletters_mapping: dict[str, str],
):
Expand Down Expand Up @@ -240,14 +240,12 @@ def _newsletter_converter(self, acoustic_main_table, contact, newsletters_mappin
}

if newsletter.name in newsletters_mapping:
newsletter_dict = newsletter.dict()
_today = datetime.date.today().isoformat()
newsletter_template["create_timestamp"] = newsletter_dict.get(
"create_timestamp", _today
)
newsletter_template["update_timestamp"] = newsletter_dict.get(
"update_timestamp", _today
)
newsletter_template[
"create_timestamp"
] = newsletter.create_timestamp.date().isoformat()
newsletter_template[
"update_timestamp"
] = newsletter.update_timestamp.date().isoformat()
newsletter_template["newsletter_name"] = newsletter.name
newsletter_template["newsletter_unsub_reason"] = newsletter.unsub_reason
_source = newsletter.source
Expand Down Expand Up @@ -430,7 +428,7 @@ def _insert_update_relational_table(self, table_name, rows):

def attempt_to_upload_ctms_contact(
self,
contact: ContactSchema,
contact: ContactTableSchema,
main_fields: set[str],
newsletters_mapping: dict[str, str],
): # raises AcousticUploadError
Expand Down
6 changes: 3 additions & 3 deletions ctms/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
ContactInSchema,
ContactPatchSchema,
ContactPutSchema,
ContactSchema,
ContactTableSchema,
CTMSBulkResponse,
CTMSResponse,
CTMSSingleResponse,
Expand Down Expand Up @@ -152,10 +152,10 @@ def get_email_or_404(db: Session, email_id) -> Email:
return email


def get_contact_or_404(db: Session, email_id) -> ContactSchema:
def get_contact_or_404(db: Session, email_id) -> ContactTableSchema:
"""Get a contact by email_ID, or raise a 404 exception."""
email = get_email_or_404(db, email_id)
return ContactSchema.from_email(email)
return ContactTableSchema.from_email(email)


def all_ids(
Expand Down
4 changes: 2 additions & 2 deletions ctms/bin/acoustic.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from ctms.database import SessionLocal
from ctms.exception_capture import init_sentry
from ctms.log import configure_logging
from ctms.schemas.contact import ContactSchema
from ctms.schemas.contact import ContactTableSchema


def confirm(msg):
Expand Down Expand Up @@ -258,7 +258,7 @@ def do_dump(dbsession, contacts, output: TextIO):
fieldnames = None
writer = None
for email in contacts:
contact = ContactSchema.from_email(email)
contact = ContactTableSchema.from_email(email)
main_table_row, _, _ = service.convert_ctms_to_acoustic(
contact, main_fields, newsletters_mapping
)
Expand Down
48 changes: 32 additions & 16 deletions ctms/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.orm import Session, joinedload, load_only, selectinload

from ctms.schemas.email import EmailSchema
from ctms.schemas.newsletter import NewsletterTableSchema
from ctms.schemas.waitlist import WaitlistTableSchema

from .auth import hash_password
from .backport_legacy_waitlists import format_legacy_vpn_relay_waitlist_input
from .database import Base
Expand Down Expand Up @@ -37,7 +41,7 @@
ApiClientSchema,
ContactInSchema,
ContactPutSchema,
ContactSchema,
ContactTableSchema,
EmailInSchema,
EmailPutSchema,
FirefoxAccountsInSchema,
Expand Down Expand Up @@ -157,7 +161,7 @@ def get_bulk_contacts(
.all()
)

return [ContactSchema.from_email(email) for email in bulk_contacts]
return [ContactTableSchema.from_email(email) for email in bulk_contacts]


def get_email(db: Session, email_id: UUID4) -> Optional[Email]:
Expand All @@ -168,12 +172,14 @@ def get_email(db: Session, email_id: UUID4) -> Optional[Email]:
)


def get_contact_by_email_id(db: Session, email_id: UUID4) -> Optional[ContactSchema]:
def get_contact_by_email_id(
db: Session, email_id: UUID4
) -> Optional[ContactTableSchema]:
"""Return a Contact object for a given email id"""
email = get_email(db, email_id)
if email is None:
return None
return ContactSchema.from_email(email)
return ContactTableSchema.from_email(email)


def get_contacts_by_any_id(
Expand All @@ -187,7 +193,7 @@ def get_contacts_by_any_id(
amo_user_id: Optional[str] = None,
fxa_id: Optional[str] = None,
fxa_primary_email: Optional[str] = None,
) -> List[ContactSchema]:
) -> List[ContactTableSchema]:
"""
Get all the data for multiple contacts by ID as a list of Contacts.

Expand Down Expand Up @@ -235,7 +241,7 @@ def get_contacts_by_any_id(
fxa_primary_email_insensitive_comparator=fxa_primary_email
)
emails = cast(List[Email], statement.all())
return [ContactSchema.from_email(email) for email in emails]
return [ContactTableSchema.from_email(email) for email in emails]


def _acoustic_sync_retry_query(db: Session):
Expand Down Expand Up @@ -369,7 +375,7 @@ def create_or_update_amo(db: Session, email_id: UUID4, amo: Optional[AddOnsInSch
db.execute(stmt)


def create_email(db: Session, email: EmailInSchema):
def create_email(db: Session, email: EmailInSchema | EmailSchema):
db_email = Email(**email.dict())
db.add(db_email)

Expand Down Expand Up @@ -439,11 +445,14 @@ def create_or_update_mofo(


def create_newsletter(
db: Session, email_id: UUID4, newsletter: NewsletterInSchema
db: Session, email_id: UUID4, newsletter: NewsletterInSchema | NewsletterTableSchema
) -> Optional[Newsletter]:
if newsletter.is_default():
return None
db_newsletter = Newsletter(email_id=email_id, **newsletter.dict())
# This is called from API input data with `NewsletterInSchema`, and from tests fixtures
# with `NewsletterTableSchema`
# Unlike `NewsletterTableSchema`, `NewsletterInSchema` has no `email_id` field.
leplatrem marked this conversation as resolved.
Show resolved Hide resolved
db_newsletter = Newsletter(**{"email_id": email_id, **newsletter.dict()})
db.add(db_newsletter)
return db_newsletter

Expand Down Expand Up @@ -473,15 +482,19 @@ def create_or_update_newsletters(


def create_waitlist(
db: Session, email_id: UUID4, waitlist: WaitlistInSchema
db: Session, email_id: UUID4, waitlist: WaitlistInSchema | WaitlistTableSchema
) -> Optional[Waitlist]:
if waitlist.is_default():
return None
if not isinstance(waitlist, WaitlistInSchema):
# Sample data are used as both input (`WaitlistInSchema`) and internal (`WaitlistSchema`)
# representations.
waitlist = WaitlistInSchema(**waitlist.dict())
db_waitlist = Waitlist(email_id=email_id, **waitlist.orm_dict())

# This is called from API input data with `WaitlistInSchema`, and from tests fixtures
# with `WaitlistTableSchema`
# Unlike `WaitlistTableSchema`, `WaitlistInSchema` has no `email_id`, `subscribed` fields.
leplatrem marked this conversation as resolved.
Show resolved Hide resolved
attrs = {"email_id": email_id, **waitlist.dict()}
if "subscribed" in attrs:
del attrs["subscribed"]

db_waitlist = Waitlist(**attrs)
db.add(db_waitlist)
return db_waitlist

Expand Down Expand Up @@ -517,7 +530,10 @@ def create_or_update_waitlists(


def create_contact(
db: Session, email_id: UUID4, contact: ContactInSchema, metrics: Optional[Dict]
db: Session,
email_id: UUID4,
contact: ContactInSchema | ContactTableSchema,
metrics: Optional[Dict],
):
create_email(db, contact.email)
if contact.amo:
Expand Down
10 changes: 8 additions & 2 deletions ctms/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
ContactInSchema,
ContactPatchSchema,
ContactPutSchema,
ContactSchema,
ContactTableSchema,
CTMSBulkResponse,
CTMSResponse,
CTMSSingleResponse,
Expand All @@ -24,7 +24,12 @@
UpdatedFirefoxAccountsInSchema,
)
from .mofo import MozillaFoundationInSchema, MozillaFoundationSchema
from .newsletter import NewsletterInSchema, NewsletterSchema, UpdatedNewsletterInSchema
from .newsletter import (
NewsletterInSchema,
NewsletterSchema,
NewsletterTableSchema,
UpdatedNewsletterInSchema,
)
from .product import ProductBaseSchema
from .stripe_customer import (
StripeCustomerCreateSchema,
Expand Down Expand Up @@ -68,6 +73,7 @@
VpnWaitlistInSchema,
WaitlistInSchema,
WaitlistSchema,
WaitlistTableSchema,
)
from .web import (
BadRequestResponse,
Expand Down
Loading