11import base64
22import binascii
33import logging
4- from typing import Any , ClassVar , cast
54from urllib import parse
65
6+ from common_library .pydantic_networks_extension import HttpUrlLegacy
77from cryptography .fernet import Fernet , InvalidToken
88from models_library .invitations import InvitationContent , InvitationInputs
99from models_library .products import ProductName
10- from pydantic import HttpUrl , ValidationError , parse_obj_as
10+ from pydantic import ConfigDict , HttpUrl , TypeAdapter , ValidationError
1111from starlette .datastructures import URL
1212
1313_logger = logging .getLogger (__name__ )
1414
1515
16+ def _to_initial (v : str ):
17+ return v [0 ]
18+
19+
1620class InvalidInvitationCodeError (Exception ):
1721 ...
1822
@@ -23,9 +27,9 @@ class _ContentWithShortNames(InvitationContent):
2327 @classmethod
2428 def serialize (cls , model_obj : InvitationContent ) -> str :
2529 """Exports to json using *short* aliases and values in order to produce shorter codes"""
26- model_w_short_aliases_json : str = cls .construct (
27- ** model_obj .dict (exclude_unset = True )
28- ).json (exclude_unset = True , by_alias = True )
30+ model_w_short_aliases_json : str = cls .model_construct (
31+ ** model_obj .model_dump (exclude_unset = True )
32+ ).model_dump_json (exclude_unset = True , by_alias = True )
2933 # NOTE: json arguments try to minimize the amount of data
3034 # serialized. The CONS is that it relies on models in the code
3135 # that might change over time. This might lead to some datasets in codes
@@ -35,36 +39,18 @@ def serialize(cls, model_obj: InvitationContent) -> str:
3539 @classmethod
3640 def deserialize (cls , raw_json : str ) -> InvitationContent :
3741 """Parses a json string and returns InvitationContent model"""
38- model_w_short_aliases = cls .parse_raw (raw_json )
39- return InvitationContent .construct (
40- ** model_w_short_aliases .dict (exclude_unset = True )
42+ model_w_short_aliases = cls .model_validate_json (raw_json )
43+ return InvitationContent .model_construct (
44+ ** model_w_short_aliases .model_dump (exclude_unset = True )
4145 )
4246
43- class Config :
44- allow_population_by_field_name = True # NOTE: can parse using field names
45- allow_mutation = False
46- anystr_strip_whitespace = True
47+ model_config = ConfigDict (
4748 # NOTE: Can export with alias: short aliases to minimize the size of serialization artifact
48- fields : ClassVar [dict [str , Any ]] = {
49- "issuer" : {
50- "alias" : "i" ,
51- },
52- "guest" : {
53- "alias" : "g" ,
54- },
55- "trial_account_days" : {
56- "alias" : "t" ,
57- },
58- "extra_credits_in_usd" : {
59- "alias" : "e" ,
60- },
61- "product" : {
62- "alias" : "p" ,
63- },
64- "created" : {
65- "alias" : "c" ,
66- },
67- }
49+ alias_generator = _to_initial ,
50+ populate_by_name = True , # NOTE: can parse using field names
51+ frozen = True ,
52+ str_strip_whitespace = True ,
53+ )
6854
6955
7056#
@@ -79,9 +65,9 @@ def _build_link(
7965 r = URL ("/registration" ).include_query_params (invitation = code_url_safe )
8066
8167 # Adds query to fragment
82- base_url = f"{ base_url . rstrip ( '/' ) } /"
68+ base_url = f"{ base_url } /"
8369 url = URL (base_url ).replace (fragment = f"{ r } " )
84- return cast ( HttpUrl , parse_obj_as ( HttpUrl , f"{ url } " ) )
70+ return TypeAdapter ( HttpUrlLegacy ). validate_python ( f"{ url } " )
8571
8672
8773def _fernet_encrypt_as_urlsafe_code (
@@ -124,7 +110,7 @@ def create_invitation_link_and_content(
124110 code = _create_invitation_code (content , secret_key )
125111 # Adds message as the invitation in query
126112 link = _build_link (
127- base_url = base_url ,
113+ base_url = f" { base_url } " ,
128114 code_url_safe = code .decode (),
129115 )
130116 return link , content
0 commit comments