subzeroid / instagrapi

🔥 The fastest and powerful Python library for Instagram Private API 2024
https://hikerapi.com/p/bkXQlaVe
MIT License
4.38k stars 685 forks source link

[BUG]: Input should be a valid string #1702

Open PranavPurwar opened 11 months ago

PranavPurwar commented 11 months ago

Try Instagrapi SaaS with a free trial https://hikerapi.com/p/5GBWznd3

Describe the bug Trying to access direct_threads via instagrapi fails

To Reproduce

from instagrapi import Client

# Get Instagram credentials from environment variables
username = "INSTAGRAM_USERNAME"
password = "INSTAGRAM_PASSWORD"

client = Client()
client.login(username, password)

direct_messages = client.direct_threads()

for i in direct_messages:
    print(i.users)

Traceback

Traceback (most recent call last):
  File "/Users/j/StudioProjects/confess/main.py", line 17, in <module>
    direct_messages = client.direct_threads()
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/j/StudioProjects/confess/env/lib/python3.11/site-packages/instagrapi/mixins/direct.py", line 88, in direct_threads
    threads_chunk, cursor = self.direct_threads_chunk(
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/j/StudioProjects/confess/env/lib/python3.11/site-packages/instagrapi/mixins/direct.py", line 154, in direct_threads_chunk
    threads.append(extract_direct_thread(thread))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/j/StudioProjects/confess/env/lib/python3.11/site-packages/instagrapi/extractors.py", line 273, in extract_direct_thread
    data["messages"].append(extract_direct_message(item))
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/j/StudioProjects/confess/env/lib/python3.11/site-packages/instagrapi/extractors.py", line 333, in extract_direct_message
    return DirectMessage(**data)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/j/StudioProjects/confess/env/lib/python3.11/site-packages/pydantic/main.py", line 164, in __init__
    __pydantic_self__.__pydantic_validator__.validate_python(data, self_instance=__pydantic_self__)
pydantic_core._pydantic_core.ValidationError: 2 validation errors for DirectMessage
user_id
  Input should be a valid string [type=string_type, input_value=43864656452, input_type=int]
    For further information visit https://errors.pydantic.dev/2.5/v/string_type
timestamp
  Input should be a valid datetime, dates after 9999 are not supported as unix timestamps [type=datetime_parsing, input_value=1702655116735355, input_type=int]
    For further information visit https://errors.pydantic.dev/2.5/v/datetime_parsing

Expected behavior The DMs should be parsed properly

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

ardaakman commented 10 months ago

This is a general problem it seems with id fields - There is a couple places this happens with media id, message id, etc. Also happens with datetimes, but it seems somebody else made a pr for this

calmness28 commented 10 months ago

ValidationError: 1 validation error for DirectMessage timestamp Input should be a valid datetime, dates after 9999 are not supported as unix timestamps [type=datetime_parsing, input_value='1704447466682555', input_type=str] For further information visit https://errors.pydantic.dev/2.5/v/datetime_parsing same error, has anyone found the answer?

ardaakman commented 10 months ago

ValidationError: 1 validation error for DirectMessage timestamp Input should be a valid datetime, dates after 9999 are not supported as unix timestamps [type=datetime_parsing, input_value='1704447466682555', input_type=str] For further information visit https://errors.pydantic.dev/2.5/v/datetime_parsing same error, has anyone found the answer?

Yes, you can change the fields in the dictionaries to actual dates using the datetime class, the following way:

def extract_direct_thread(data):
    data["pk"] = data.get("thread_v2_id")
    data["id"] = data.get("thread_id")
    data["messages"] = []
    for item in data["items"]:
        item["thread_id"] = str(data["id"])
        data["messages"].append(extract_direct_message(item))
    data["users"] = [extract_user_short(u) for u in data["users"]]
    if "inviter" in data:
        data["inviter"] = extract_user_short(data["inviter"])
    data["left_users"] = data.get("left_users", [])

    if "last_activity_at" in data:
        if type(data["last_activity_at"]) is not datetime:
            timestamp_int = int(data["last_activity_at"]) / 1000000
            data["last_activity_at"] = datetime.fromtimestamp(timestamp_int)

    return DirectThread(**data)

There is one other place this problem exists, you can do this manually in the code base. I did not create a pr yet, just because this does not feel like a clear defined fix - its more like a hack.

PranavPurwar commented 10 months ago

I edited the types of some properties in types.py to get around it