clerk / clerk-sdk-python

52 stars 13 forks source link

Pydantic failure from #27 persists. #36

Closed soobinbhan closed 2 weeks ago

soobinbhan commented 1 month ago

Issue: Pydantic failure from #27 persists when calling clerk_client.users.list()

pydantic_core._pydantic_core.ValidationError: 9 validation errors for Unmarshaller
body.0.email_addresses.0.verification.Otp.attempts
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.8/v/int_type
body.0.email_addresses.0.verification.Otp.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.8/v/int_type
body.0.email_addresses.0.verification.Admin.strategy
  Input should be 'admin' [type=enum, input_value='from_oauth_microsoft', input_type=str]
    For further information visit https://errors.pydantic.dev/2.8/v/enum
body.0.email_addresses.0.verification.Oauth.strategy
  Input should be 'oauth_google', 'oauth_mock', 'from_oauth_google', 'from_oauth_discord', 'oauth_apple', 'oauth_microsoft' or 'email_link' [type=enum, input_value='from_oauth_microsoft', input_type=str]
    For further information visit https://errors.pydantic.dev/2.8/v/enum
body.0.email_addresses.0.verification.Oauth.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.8/v/int_type
body.1.email_addresses.0.verification.Otp.attempts
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.8/v/int_type
body.1.email_addresses.0.verification.Otp.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.8/v/int_type
body.1.email_addresses.0.verification.Admin.strategy
  Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str]
    For further information visit https://errors.pydantic.dev/2.8/v/enum
body.1.email_addresses.0.verification.Oauth.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.8/v/int_type

https://github.com/clerk/clerk-sdk-python/blob/a6c5d4efe16d30a626ee70ced55082617468254d/src/clerk_backend_api/models/emailaddress.py#L25

Appears that OauthVerificationStrategy needs FROM_OAUTH_MICROSOFT="from_oauth_microsoft"

class OauthVerificationStrategy(str, Enum):
    OAUTH_GOOGLE = "oauth_google"
    OAUTH_MOCK = "oauth_mock"
    FROM_OAUTH_GOOGLE = "from_oauth_google"
    FROM_OAUTH_DISCORD = "from_oauth_discord"
    OAUTH_APPLE = "oauth_apple"
    OAUTH_MICROSOFT = "oauth_microsoft"
    **FROM_OAUTH_MICROSOFT = "from_oauth_microsoft"**
    EMAIL_LINK = "email_link"

I'm not sure why there are other validation failures.

logangingerich commented 1 month ago

Hi @soobinbhan! Apologies for the persisting issue here, we're applying some local fixes but also working on some upstream adjustments that should help address this long term. Would you mind updating to the most recently released version and see if there are any changes, particularly to the OAuth verification strategy? You can see the update to the referenced file here.

soobinbhan commented 1 month ago

@logangingerich Thanks for the update. I'm running into another validation issue:

{ "detail": "User not found: 4 validation errors for Unmarshaller body.email_addresses.0.verification.Otp.attempts Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.8/v/int_type body.email_addresses.0.verification.Otp.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.8/v/int_type body.email_addresses.0.verification.Admin.strategy Input should be 'admin' [type=enum, input_value='from_oauth_microsoft', input_type=str] For further information visit https://errors.pydantic.dev/2.8/v/enum body.email_addresses.0.verification.Oauth.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.8/v/int_type" }

https://github.com/clerk/clerk-sdk-python/blob/485cd2d224b365872e8a3ab71a01804b6157ac1c/src/clerk_backend_api/models/emailaddress.py#L112

Looks like the following line needs to be added:

class VerificationStrategy(str, Enum):
    ADMIN = "admin"
    **FROM_OAUTH_MICROSOFT = "from_oauth_microsoft"**

After adding this line, I can fetch users as expected.

roninio commented 1 month ago

I am getting this also

s = Clerk(bearer_auth=CLERK_API_KEY) res = s.users.get(user_id=user_id)

line 212, in init validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pydantic_core._pydantic_core.ValidationError: 4 validation errors for Unmarshaller body.email_addresses.0.verification.Otp.attempts Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Otp.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Admin.strategy Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str] For further information visit https://errors.pydantic.dev/2.9/v/enum body.email_addresses.0.verification.Oauth.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type pydantic_core._pydantic_core.ValidationError: 4 validation errors for Unmarshaller body.email_addresses.0.verification.Otp.attempts Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Otp.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Admin.strategy Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str] For further information visit https://errors.pydantic.dev/2.9/v/enum body.email_addresses.0.verification.Oauth.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type

roninio commented 1 month ago

seems you need to set.

class OtpTypedDict(TypedDict):
    status: VerificationStatus
    strategy: Strategy
    attempts: None
    expire_at: None

class Otp(BaseModel):
    status: VerificationStatus
    strategy: Strategy
    attempts: None
    expire_at: None
roninio commented 1 month ago

if I do as below: a = res.email_addresses why is it a list of EmailAddress Object?

kingsleyzhong commented 3 weeks ago

I am getting this also

s = Clerk(bearer_auth=CLERK_API_KEY) res = s.users.get(user_id=user_id)

line 212, in init validated_self = self.pydantic_validator.validate_python(data, self_instance=self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pydantic_core._pydantic_core.ValidationError: 4 validation errors for Unmarshaller body.email_addresses.0.verification.Otp.attempts Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Otp.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Admin.strategy Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str] For further information visit https://errors.pydantic.dev/2.9/v/enum body.email_addresses.0.verification.Oauth.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type pydantic_core._pydantic_core.ValidationError: 4 validation errors for Unmarshaller body.email_addresses.0.verification.Otp.attempts Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Otp.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type body.email_addresses.0.verification.Admin.strategy Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str] For further information visit https://errors.pydantic.dev/2.9/v/enum body.email_addresses.0.verification.Oauth.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.9/v/int_type

I'm running into the same issue when calling sdk.users.update_metadata

bllchmbrs commented 3 weeks ago

I am hitting the same issue on s.users.list_async().

asktomi commented 3 weeks ago

I'm getting

body.294.email_addresses.0.verification.Otp.strategy Input should be 'phone_code', 'email_code', 'email_link', 'reset_password_email_code', 'from_oauth_discord', 'from_oauth_google', 'from_oauth_apple', 'from_oauth_microsoft' or 'from_oauth_github' [type=enum, input_value='ticket', input_type=str] For further information visit https://errors.pydantic.dev/2.8/v/enum

body.4.email_addresses.0.verification.Otp.attempts Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.8/v/int_type body.4.email_addresses.0.verification.Otp.expire_at Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType] For further information visit https://errors.pydantic.dev/2.8/v/int_type

At least attempts and expire were Nullable in eversion 0.5.0. I hope you get these fixed soon. users.list and users.list_async are unusable now.

jay-khatri commented 2 weeks ago

got the same issues as above. I used the api docs to build my own query instead, e.g.:

import httpx
...
http_client = httpx.AsyncClient()
...
headers = {
                "Authorization": f"Bearer {os.getenv('CLERK_SECRET_KEY')}",
                "Accept": "application/json"
}
user_response = await http_client.get(f"https://api.clerk.dev/v1/users/{sub}", headers=headers)
targetlucked69 commented 2 weeks ago

are there plans to fix this one? Been 2 weeks 😭

dschuler36 commented 2 weeks ago

Getting the same error. Using clerk-backend-api==1.2.0.

>>> c = Clerk(CLERK_API_KEY)
>>> user_id = 'user_test'
>>> c.users.get(user_id=user_id)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/venvs/clerk-test/lib/python3.12/site-packages/clerk_backend_api/users.py", line 714, in get
    return utils.unmarshal_json(http_res.text, Optional[models.User])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venvs/clerk-test/lib/python3.12/site-packages/clerk_backend_api/utils/serializers.py", line 133, in unmarshal_json
    return unmarshal(from_json(raw), typ)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venvs/clerk-test/lib/python3.12/site-packages/clerk_backend_api/utils/serializers.py", line 143, in unmarshal
    m = unmarshaller(body=val)
        ^^^^^^^^^^^^^^^^^^^^^^
  File "/venvs/clerk-test/lib/python3.12/site-packages/pydantic/main.py", line 212, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 4 validation errors for Unmarshaller
body.email_addresses.0.verification.Otp.attempts
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/int_type
body.email_addresses.0.verification.Otp.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/int_type
body.email_addresses.0.verification.Admin.strategy
  Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str]
    For further information visit https://errors.pydantic.dev/2.9/v/enum
body.email_addresses.0.verification.Oauth.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/int_type
>>> res = c.users.get(user_id=user_id)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/venvs/clerk-test/lib/python3.12/site-packages/clerk_backend_api/users.py", line 714, in get
    return utils.unmarshal_json(http_res.text, Optional[models.User])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venvs/clerk-test/lib/python3.12/site-packages/clerk_backend_api/utils/serializers.py", line 133, in unmarshal_json
    return unmarshal(from_json(raw), typ)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/venvs/clerk-test/lib/python3.12/site-packages/clerk_backend_api/utils/serializers.py", line 143, in unmarshal
    m = unmarshaller(body=val)
        ^^^^^^^^^^^^^^^^^^^^^^
  File "/venvs/clerk-test/lib/python3.12/site-packages/pydantic/main.py", line 212, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 4 validation errors for Unmarshaller
body.email_addresses.0.verification.Otp.attempts
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/int_type
body.email_addresses.0.verification.Otp.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/int_type
body.email_addresses.0.verification.Admin.strategy
  Input should be 'admin' [type=enum, input_value='from_oauth_google', input_type=str]
    For further information visit https://errors.pydantic.dev/2.9/v/enum
body.email_addresses.0.verification.Oauth.expire_at
  Input should be a valid integer [type=int_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/int_type
sergesteban commented 2 weeks ago

same problem here I actually made it work using it as following

clerk = Clerk(bearer_auth=os.getenv('CLERK_SECRET_KEY'))

def get_google_oauth_token(user_id: str):
    # Retrieve the Google OAuth token from Clerk
    response = clerk.users.get_o_auth_access_token(
        user_id=user_id,
        provider="oauth_google"
    )
    return(response[0].token)
async def get_users():
    try:
        http_client = httpx.AsyncClient()
        response = await http_client.get("https://api.clerk.com/v1/users", headers={"Authorization": fBearer {os.getenv('CLERK_SECRET_KEY')}})
        return response.json()

    except Exception as e:
        print(e)
        return []    

i noticed it didnt work with clerk-backend-api = "^1.2.0" neither clerk.users.list_async() clerk.users.list()

dmk commented 2 weeks ago

Same issue here.

speakeasybot commented 2 weeks ago

Thanks for your patience while we worked out the best route for this fix.

The latest version contains a fix for this issue: https://github.com/clerk/clerk-sdk-python/releases/tag/v1.3.1

However, please reopen if you continue to experience the issue after updating.