maxapi-python 2.1.2__py3-none-any.whl → 2.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maxapi_python-2.1.2.dist-info → maxapi_python-2.2.0.dist-info}/METADATA +3 -11
- {maxapi_python-2.1.2.dist-info → maxapi_python-2.2.0.dist-info}/RECORD +66 -60
- pymax/__init__.py +18 -3
- pymax/api/auth/payloads.py +7 -0
- pymax/api/auth/service.py +33 -30
- pymax/api/binding.py +57 -0
- pymax/api/chats/service.py +34 -47
- pymax/api/messages/enums.py +1 -0
- pymax/api/messages/payloads.py +16 -1
- pymax/api/messages/service.py +85 -33
- pymax/api/models.py +4 -6
- pymax/api/response.py +2 -2
- pymax/api/self/service.py +17 -26
- pymax/api/session/payloads.py +2 -9
- pymax/api/session/service.py +1 -3
- pymax/api/uploads/payloads.py +3 -9
- pymax/api/uploads/service.py +33 -99
- pymax/api/users/service.py +8 -16
- pymax/app.py +20 -4
- pymax/auth/qr.py +3 -9
- pymax/auth/sms.py +23 -11
- pymax/base.py +38 -1
- pymax/client.py +3 -5
- pymax/client_web.py +1 -2
- pymax/config.py +42 -3
- pymax/connection/connection.py +48 -19
- pymax/connection/readers/tcp.py +1 -3
- pymax/dispatch/dispatcher.py +36 -18
- pymax/dispatch/enums.py +4 -0
- pymax/dispatch/mapping.py +34 -11
- pymax/dispatch/resolvers.py +18 -0
- pymax/dispatch/router.py +34 -0
- pymax/files/photo.py +4 -2
- pymax/formatting/markdown.py +22 -13
- pymax/infra/chat.py +12 -0
- pymax/infra/message.py +74 -3
- pymax/logging.py +35 -3
- pymax/protocol/tcp/compression.py +1 -3
- pymax/protocol/tcp/framing.py +1 -3
- pymax/protocol/tcp/payload.py +22 -42
- pymax/protocol/tcp/protocol.py +2 -8
- pymax/protocol/ws/protocol.py +3 -9
- pymax/session/protocol.py +2 -6
- pymax/session/store.py +8 -24
- pymax/telemetry/navigation.py +1 -3
- pymax/telemetry/service.py +5 -17
- pymax/transport/tcp.py +1 -3
- pymax/types/domain/attachments/__init__.py +1 -0
- pymax/types/domain/attachments/audio.py +4 -4
- pymax/types/domain/attachments/enums.py +1 -0
- pymax/types/domain/attachments/unknown.py +35 -0
- pymax/types/domain/attachments/video.py +2 -2
- pymax/types/domain/auth.py +24 -2
- pymax/types/domain/chat.py +38 -1
- pymax/types/domain/element.py +3 -3
- pymax/types/domain/message.py +34 -2
- pymax/types/domain/presence.py +3 -3
- pymax/types/domain/sync.py +5 -21
- pymax/types/events/__init__.py +4 -0
- pymax/types/events/mark.py +23 -0
- pymax/types/events/message.py +57 -5
- pymax/types/events/presence.py +15 -0
- pymax/types/events/reaction.py +21 -0
- pymax/types/events/typing.py +14 -0
- {maxapi_python-2.1.2.dist-info → maxapi_python-2.2.0.dist-info}/WHEEL +0 -0
- {maxapi_python-2.1.2.dist-info → maxapi_python-2.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maxapi-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Python wrapper для API мессенджера Max
|
|
5
5
|
Project-URL: Homepage, https://github.com/MaxApiTeam/PyMax
|
|
6
6
|
Project-URL: Repository, https://github.com/MaxApiTeam/PyMax
|
|
7
7
|
Project-URL: Issues, https://github.com/MaxApiTeam/PyMax/issues
|
|
8
|
-
Project-URL: Documentation, https://
|
|
8
|
+
Project-URL: Documentation, https://docs.pymax.org
|
|
9
9
|
Author-email: ink <inkdev@proton.me>
|
|
10
10
|
License-Expression: MIT
|
|
11
11
|
License-File: LICENSE
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
24
|
Classifier: Typing :: Typed
|
|
24
25
|
Requires-Python: >=3.10
|
|
25
26
|
Requires-Dist: aiofiles>=25.1.0
|
|
@@ -30,15 +31,6 @@ Requires-Dist: pydantic>=2.10.0
|
|
|
30
31
|
Requires-Dist: python-socks[asyncio]>=2.8.1
|
|
31
32
|
Requires-Dist: qrcode>=8.2
|
|
32
33
|
Requires-Dist: websockets>=16.0
|
|
33
|
-
Provides-Extra: docs
|
|
34
|
-
Requires-Dist: furo>=2025.12.19; extra == 'docs'
|
|
35
|
-
Requires-Dist: sphinx-copybutton>=0.5.2; extra == 'docs'
|
|
36
|
-
Requires-Dist: sphinx>=8.1.3; extra == 'docs'
|
|
37
|
-
Provides-Extra: test
|
|
38
|
-
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'test'
|
|
39
|
-
Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
|
|
40
|
-
Requires-Dist: pytest-timeout>=2.1.0; extra == 'test'
|
|
41
|
-
Requires-Dist: pytest>=8.0.0; extra == 'test'
|
|
42
34
|
Description-Content-Type: text/markdown
|
|
43
35
|
|
|
44
36
|
# PyMax
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
pymax/__init__.py,sha256=
|
|
2
|
-
pymax/app.py,sha256=
|
|
3
|
-
pymax/base.py,sha256=
|
|
4
|
-
pymax/client.py,sha256=
|
|
5
|
-
pymax/client_web.py,sha256=
|
|
6
|
-
pymax/config.py,sha256=
|
|
1
|
+
pymax/__init__.py,sha256=57UYiquQpEkanZR7Y4wQTzYnfd9KyvZTsNxDKb6dM9g,1500
|
|
2
|
+
pymax/app.py,sha256=3OwH2pT4Wv-ocAhEFZNo2DleZRnC8VNUmQQprRGAG58,10265
|
|
3
|
+
pymax/base.py,sha256=23kcR8rFjxfAqDJhOaxyOpS-TQrOSpLQlldzmx21sD0,8679
|
|
4
|
+
pymax/client.py,sha256=ePDxR6wEeHJbk23wI_PkOVFQuyy5tQyckV-OmKEwz5U,3985
|
|
5
|
+
pymax/client_web.py,sha256=VASqNmMvAfdpIaR6cpdtjv3UN4GoqWkiDOXdn7QmZQ0,3025
|
|
6
|
+
pymax/config.py,sha256=1dttAfxjcuWVrr939iYLDowQknvl_eOhNpJP8ugnWTg,10047
|
|
7
7
|
pymax/exceptions.py,sha256=8pxjZsfgrMPrZfE3zedIbabqP75diEr2_6Xg3PGjiSQ,963
|
|
8
|
-
pymax/logging.py,sha256=
|
|
8
|
+
pymax/logging.py,sha256=j2-7guTR8otCrSk0w7NL2y-d_gJoNUS5Fh9NtsdEgIg,4632
|
|
9
9
|
pymax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
pymax/routers.py,sha256=UvIEWcBF1VPBmUFrubBQ7uo3DZylf4qdbnQGDkUYjyE,225
|
|
11
11
|
pymax/api/__init__.py,sha256=oWC09vGaP6S7_nnTJ4y5PbTkbA4U29DhafpwIqD2QGI,356
|
|
12
|
+
pymax/api/binding.py,sha256=q63tSMxwh8cX28r2JwK3_TyxsV8zThflMaQiMb0vx8M,1613
|
|
12
13
|
pymax/api/facade.py,sha256=WapwUPspVxA8JMYRvWGKtaKs9rUvIJLTMaXods6julo,899
|
|
13
|
-
pymax/api/models.py,sha256=
|
|
14
|
-
pymax/api/response.py,sha256=
|
|
14
|
+
pymax/api/models.py,sha256=Vc0y9__za1aju3zgHW4aS6lMr1SyZi7q0lrQhfviFUA,344
|
|
15
|
+
pymax/api/response.py,sha256=7rXgqtaGeDd60FGMxlLwqARzgFIawX8OkMqA9TL8HRE,2591
|
|
15
16
|
pymax/api/auth/__init__.py,sha256=m6yw6RPrq10iNkSI8z59n3OXTnAw8VfxIALnhVztL2g,33
|
|
16
17
|
pymax/api/auth/enums.py,sha256=QFtOBnD-qmoROzu2pfgWD6swMOdapOgumsEOHEulsog,661
|
|
17
|
-
pymax/api/auth/payloads.py,sha256=
|
|
18
|
-
pymax/api/auth/service.py,sha256=
|
|
18
|
+
pymax/api/auth/payloads.py,sha256=B6ggwAKOg2b_SI4lSpbAc50BPWCPLL474NLP_aRY-u0,3167
|
|
19
|
+
pymax/api/auth/service.py,sha256=qdZW3qvDRTukc1jtjxsw_qbeo3fPQa9ccgRRLRXCd0o,12130
|
|
19
20
|
pymax/api/auth/types.py,sha256=VrYR7rIZOrW45yKnQmC5MSe9kxgXmqPzh9VG_y1tSEs,200
|
|
20
21
|
pymax/api/bots/__init__.py,sha256=4P7rM-XeeDOElEktov1Vbfo8nzjJgmyA4_pQl4WvzRQ,33
|
|
21
22
|
pymax/api/bots/payloads.py,sha256=aXriolCN_YvBvDZO_MPmD-fkrIVJIpVDXkOkOZVes_c,166
|
|
@@ -23,62 +24,62 @@ pymax/api/bots/service.py,sha256=ziqVlQUMFHjQydMDFyWcQMIATboQTvIdGtJhf-AK9tA,847
|
|
|
23
24
|
pymax/api/chats/__init__.py,sha256=UMp3uKdB3tZlnWckndgF3jaU-3-49OJE18z2d0OlmIU,155
|
|
24
25
|
pymax/api/chats/enums.py,sha256=FdByRiHYX9Xs7RyNabKqxGugNs9tJ3VBXwTb_43XGC8,627
|
|
25
26
|
pymax/api/chats/payloads.py,sha256=Y4S2x60i3txeA75GV_pGJ3ov7pLMp4GjGuhoqlRI2ow,2824
|
|
26
|
-
pymax/api/chats/service.py,sha256=
|
|
27
|
+
pymax/api/chats/service.py,sha256=l6yReFxIj9Pfn96wOW3n60MRHRp4rq9nM569fs2gfvU,11535
|
|
27
28
|
pymax/api/messages/__init__.py,sha256=fw_uF6tgSbkxvqaSVE65wU0KWsu47u1CtR0Y4BbD-K0,36
|
|
28
|
-
pymax/api/messages/enums.py,sha256=
|
|
29
|
-
pymax/api/messages/payloads.py,sha256=
|
|
30
|
-
pymax/api/messages/service.py,sha256=
|
|
29
|
+
pymax/api/messages/enums.py,sha256=tp5S2Q97a-FILcqpRhQiIRKdj0P_KSEBiCqWmb05dHs,368
|
|
30
|
+
pymax/api/messages/payloads.py,sha256=wqseGNfqWYKeoRJhdzrRV855IboChaYU1dJLPGZg71I,2257
|
|
31
|
+
pymax/api/messages/service.py,sha256=Zur05Rklq2LrssIWLE5tThAXPXK9b7MsvFW8BklSoHU,12422
|
|
31
32
|
pymax/api/self/__init__.py,sha256=TfbqL4xLb5IMhbW8mlAK-AwVFqqPWMADogKZeWtkw0A,79
|
|
32
33
|
pymax/api/self/enums.py,sha256=iKEqPy44LyQKvAPfyhpkSXgmWWohxry73F0CVgtekwY,180
|
|
33
34
|
pymax/api/self/payloads.py,sha256=-SFqkNxC5ZLKnLty_Gyz_b_P3X1esu_7Urb4HjrQxM4,774
|
|
34
|
-
pymax/api/self/service.py,sha256=
|
|
35
|
+
pymax/api/self/service.py,sha256=ViA7h3o3HHJlOdbH0Fk3vjW2mcoEHWSzlXC11TwJT9s,4896
|
|
35
36
|
pymax/api/session/__init__.py,sha256=zo-rCKBVBsFK-810T-Le4VbAYKt109cQ6elf0UkgiNk,36
|
|
36
37
|
pymax/api/session/enums.py,sha256=InBdwAu_filqW3rMfGrOkHgmFfqgB1ytjnCcxDq29xc,236
|
|
37
|
-
pymax/api/session/payloads.py,sha256=
|
|
38
|
-
pymax/api/session/service.py,sha256=
|
|
38
|
+
pymax/api/session/payloads.py,sha256=KJBoP_XfL2lJbXvR3tzWf2WaLn73L2LiEuqP0cdJ6u0,2258
|
|
39
|
+
pymax/api/session/service.py,sha256=eVJt3GFwynsIWDEPFVVA1vOixajHve0g4NZTi4PHpXE,1980
|
|
39
40
|
pymax/api/uploads/__init__.py,sha256=E7INNsBeMStze2VWMADX4mrswsQeJb85C71sSuiOpv0,35
|
|
40
41
|
pymax/api/uploads/models.py,sha256=c2Yunnl9nRkDZuItXGKlY0Oi5DjnB4f5bcruQ49ARZk,934
|
|
41
|
-
pymax/api/uploads/payloads.py,sha256=
|
|
42
|
-
pymax/api/uploads/service.py,sha256=
|
|
42
|
+
pymax/api/uploads/payloads.py,sha256=OqsfFJIRe2io7mltHPbDPORT8U5t27H6pvqrdNKPRHY,652
|
|
43
|
+
pymax/api/uploads/service.py,sha256=83VrmMGZG4QPnKfSdVrWoIOvER4CvegrbZ2ddxmGsq8,18551
|
|
43
44
|
pymax/api/users/__init__.py,sha256=CDakgSKwVAkX-kNoDmIo2JsFPsS7Nx3j2vIMwQnPRck,82
|
|
44
45
|
pymax/api/users/enums.py,sha256=m3d225sjWkBIRF5NNi3ChnyZ6BgKUEbPYoYwVjpifZ4,205
|
|
45
46
|
pymax/api/users/payloads.py,sha256=VoXXctQDl7WXt5zqoRKzdONqmris5Cxf7-6Hy_Gcd-A,288
|
|
46
|
-
pymax/api/users/service.py,sha256=
|
|
47
|
+
pymax/api/users/service.py,sha256=q-juReMH8Fz5a4eOEvxkpIknRHiKrlowRSByeB9nrkQ,4144
|
|
47
48
|
pymax/auth/__init__.py,sha256=KgghKg0CPcJzX_D14TvxuDzhNmoVoFGjv414NouJVgk,512
|
|
48
49
|
pymax/auth/base.py,sha256=v492FMUmSKft6oJRmCdIr33sy50Z0kqBwu5t7cVLQe4,1222
|
|
49
50
|
pymax/auth/email.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
51
|
pymax/auth/models.py,sha256=2SbjOJev1-B1bFEFM0NJPNX4wBTc4JbVDDouRHoAYc0,91
|
|
51
52
|
pymax/auth/providers.py,sha256=B3EaS-iKxrZffcxiBKjoA1TsytwybHUunjZUtbjiiVE,4148
|
|
52
|
-
pymax/auth/qr.py,sha256=
|
|
53
|
+
pymax/auth/qr.py,sha256=Kkj5_2UEfdqgov76TIIdobCvJxltv8A1CPVunDlQa-w,4203
|
|
53
54
|
pymax/auth/service.py,sha256=cUZxs5UW9ysSaJ-UXSOz0ug3fDo1eN0xAjO7VP1MdTU,619
|
|
54
|
-
pymax/auth/sms.py,sha256
|
|
55
|
+
pymax/auth/sms.py,sha256=-Y9iW4kZmi2IMsH9pylNS96U-37Kj_1pkUab0xNmp9w,4909
|
|
55
56
|
pymax/connection/__init__.py,sha256=YTboFk9AfYkRUw2Hf4oxn63LTGV475fxp_oel1j4gas,42
|
|
56
|
-
pymax/connection/connection.py,sha256=
|
|
57
|
+
pymax/connection/connection.py,sha256=qawPaTUUgOwo4GMbtT2LfTxtjhxvxXMUwWaDhjag2iQ,7870
|
|
57
58
|
pymax/connection/pending.py,sha256=qezxL019d1E6oiCmSgCSfojLj7sxR1BEGgcKBWSFhok,1328
|
|
58
59
|
pymax/connection/readers/__init__.py,sha256=9g5ZbcWiHxW1kAi2ckiNqejoGHwoDwFd4WvtYQSyRzU,52
|
|
59
60
|
pymax/connection/readers/base.py,sha256=FlvyMUFoZ4FORAh0vBU6_I0BnrQ9_1twpUIKz-Vkj58,126
|
|
60
|
-
pymax/connection/readers/tcp.py,sha256=
|
|
61
|
+
pymax/connection/readers/tcp.py,sha256=62nqlllE0gjQQQYVfjBt0arAJ8tEHH_SMZOOjtXNYdw,1073
|
|
61
62
|
pymax/connection/readers/ws.py,sha256=IjeH5CoXvBWde46tZLx6uKONkjhCU6NeC79x3Swfw8E,368
|
|
62
63
|
pymax/dispatch/__init__.py,sha256=bvHjlw2ltujMAiegW-Sv2fSGKUnkmtPcYINUZ-Ty8qo,189
|
|
63
|
-
pymax/dispatch/dispatcher.py,sha256=
|
|
64
|
-
pymax/dispatch/enums.py,sha256=
|
|
65
|
-
pymax/dispatch/mapping.py,sha256=
|
|
66
|
-
pymax/dispatch/resolvers.py,sha256=
|
|
67
|
-
pymax/dispatch/router.py,sha256=
|
|
64
|
+
pymax/dispatch/dispatcher.py,sha256=OPEyFKLYfUs2xRjjNH_EvMCMJYLhJaPu5szZwEFATgk,7865
|
|
65
|
+
pymax/dispatch/enums.py,sha256=_gPWDdBpCCgkfRcAqz-zIMptavV7SRxArpRtW3MudPA,420
|
|
66
|
+
pymax/dispatch/mapping.py,sha256=wO9BPl3meCWE7AA0XdC0iGt-4zuGVozcCqnleCTFdI0,3303
|
|
67
|
+
pymax/dispatch/resolvers.py,sha256=FZvjYxQwy5CnTl6QwdfRRodK9cGrAn6MuXTZqcsJkPE,1987
|
|
68
|
+
pymax/dispatch/router.py,sha256=thwbOgulhgFpgdP76r5ZAttGNLo3FKaXIGNWQmCrWSg,7967
|
|
68
69
|
pymax/files/__init__.py,sha256=TR0N6YXX4IHBsXQo8uiK68C-Xg3LSj48d4Zsv71CWZE,126
|
|
69
70
|
pymax/files/base.py,sha256=0aksCGxmrvqEKJdhRWcuPZJfEn7RWcl5tn5gn63q1os,2689
|
|
70
71
|
pymax/files/file.py,sha256=JSkuKx0fdGxzcsyMajWTosFzTlfgZYvQbh-RDp9OZyQ,2337
|
|
71
|
-
pymax/files/photo.py,sha256=
|
|
72
|
+
pymax/files/photo.py,sha256=jvHihuyghDljY9PLh3ymJfoj5KksIRBWIK3z9Dmgjuk,3604
|
|
72
73
|
pymax/files/static.py,sha256=U_KfM0rbGMEWcsBnWIhIXzzk46hHYQ7KJnrGnfDLoMs,142
|
|
73
74
|
pymax/files/video.py,sha256=fGXgSY5zH-voYPVjbDBnkGI1TeP-KOSq3DZEDFNnn68,2153
|
|
74
75
|
pymax/formatting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
|
-
pymax/formatting/markdown.py,sha256=
|
|
76
|
+
pymax/formatting/markdown.py,sha256=xHF2XEGjiyJHN7WUZI312a2EkBZRxw38e1y-QQ-8dr8,6637
|
|
76
77
|
pymax/infra/__init__.py,sha256=lKq6cehhB87HltV53TD0kr0p7ekWlZlrKTpaYiq0XFw,28
|
|
77
78
|
pymax/infra/auth.py,sha256=YuYH_NWNz8UfPyko6bv_cIzXDIvFeivDrxZCIpGoANU,3648
|
|
78
79
|
pymax/infra/base.py,sha256=sOo40Qkp14bE6CxVKppJhy3e0F5VhFPhnL3iBs8y5dA,368
|
|
79
80
|
pymax/infra/bots.py,sha256=IJs4ErFxjbMeiHfQgpDiDhtEu9ws-lIp8fb8I96szy8,1202
|
|
80
|
-
pymax/infra/chat.py,sha256=
|
|
81
|
-
pymax/infra/message.py,sha256=
|
|
81
|
+
pymax/infra/chat.py,sha256=tMyzCEhOWmGqMXRLmV0_jPrKQXyowkHxzUwyVEdlztc,13134
|
|
82
|
+
pymax/infra/message.py,sha256=pZga2B_PUoQMGhJuGRbtvU7XUpOeibjDvFPbJptn1Fk,10886
|
|
82
83
|
pymax/infra/protocol.py,sha256=I2WrAeAgATuNSdK2gvHU-MhhxdRBfSMGMovF5HPFsQw,208
|
|
83
84
|
pymax/infra/self.py,sha256=h2GnzcCF2-FeY9-qBjtHjrSCx7elc4RjuCXPaewDkgg,4828
|
|
84
85
|
pymax/infra/user.py,sha256=nv9jkWpWvCWETHZsyUMmm5FWkzLTJT2SHXZ7SglZE8M,4331
|
|
@@ -87,61 +88,66 @@ pymax/protocol/base.py,sha256=_bisk1BU_GSMSPIqfnizSCgm_qBrdbB5cJw6foAa2tc,294
|
|
|
87
88
|
pymax/protocol/enums.py,sha256=9y4kn9y2pKinaT_twdeW5MXVH3O-sJF6h0v5KbC9VkA,4376
|
|
88
89
|
pymax/protocol/models.py,sha256=kno-09OoPoLKBMixS9nrDkCbxcIwvU37RlZgaq5MfVo,584
|
|
89
90
|
pymax/protocol/tcp/__init__.py,sha256=ivIZZ-UoT_MiRIUWTLiyeKSBOzf9XztSprHPHgoWNuI,34
|
|
90
|
-
pymax/protocol/tcp/compression.py,sha256=
|
|
91
|
-
pymax/protocol/tcp/framing.py,sha256=
|
|
92
|
-
pymax/protocol/tcp/payload.py,sha256=
|
|
93
|
-
pymax/protocol/tcp/protocol.py,sha256
|
|
91
|
+
pymax/protocol/tcp/compression.py,sha256=sa9xe3cjAYXsJCPPxGc6iRyctFaT15VcqQ0fiC8vk4A,3014
|
|
92
|
+
pymax/protocol/tcp/framing.py,sha256=qH2zNsJLfg5J2wNTcp1hPqsrWhZHajK-Ja7pdB_Gji0,1630
|
|
93
|
+
pymax/protocol/tcp/payload.py,sha256=86-NJ5MVvxpgD2ffQqJGaSbDhVBFhaNOH91-k1IQJk8,3515
|
|
94
|
+
pymax/protocol/tcp/protocol.py,sha256=-8JQe5rhXXtBMNeCWM8XJXmlnL-0lNSEUCP6LU2zU7c,2244
|
|
94
95
|
pymax/protocol/ws/__init__.py,sha256=oQK0h28B6gGItf7eHanWy_XsgUA_L9Lclnuz9ZQL9YI,33
|
|
95
|
-
pymax/protocol/ws/protocol.py,sha256=
|
|
96
|
+
pymax/protocol/ws/protocol.py,sha256=z6zzBQTlJfzwOmLsJYoYQ2L1AYpY5wYMJyPir_zfNBQ,913
|
|
96
97
|
pymax/session/__init__.py,sha256=natjnLjPjTvkfvSYtoiPxzmU44XJi0MpjWiOPD-On4g,100
|
|
97
98
|
pymax/session/models.py,sha256=jvnTHfjCX1p5TcANfWZ0vUJlciuqumatwdrgYiKm4kY,250
|
|
98
|
-
pymax/session/protocol.py,sha256=
|
|
99
|
-
pymax/session/store.py,sha256=
|
|
99
|
+
pymax/session/protocol.py,sha256=8ibp-HiaJaGmx23v7GeL0GFsvLPZZqWOuIOJnanqoCM,612
|
|
100
|
+
pymax/session/store.py,sha256=FkhrG0J2ueU2Z4PxJQxFPOcunKnpVavnAaJgPb2bx-E,7770
|
|
100
101
|
pymax/telemetry/__init__.py,sha256=6mP5y-iTbVIlqpSWIKWCTz2fFNBwkAEYwS4PFbyv9xM,71
|
|
101
|
-
pymax/telemetry/navigation.py,sha256=
|
|
102
|
+
pymax/telemetry/navigation.py,sha256=vlP7d863s9aIBpt9SPpjEbTXLoq3uqpuhD-VWj0w9hI,5441
|
|
102
103
|
pymax/telemetry/payloads.py,sha256=MCKYGpQ4Tvx_8LH86Et0yevea2Th2z3b7a9pfmrQRys,3959
|
|
103
|
-
pymax/telemetry/service.py,sha256=
|
|
104
|
+
pymax/telemetry/service.py,sha256=rlFQAlMFnNZjw631bPHRSLWMkrIvyji47SYnGRJ0Apk,6952
|
|
104
105
|
pymax/transport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
105
106
|
pymax/transport/base.py,sha256=0D3srQ36F0s23pIjqd6YzRGKK9wCmXKr3wfe2XYYlos,448
|
|
106
|
-
pymax/transport/tcp.py,sha256=
|
|
107
|
+
pymax/transport/tcp.py,sha256=Nl-voifBze4TGB25xjf93XxU77zvFL8rsPCjBpXYd_4,3083
|
|
107
108
|
pymax/transport/websocket.py,sha256=0ezkSoENWKV00EATIizGx16-ihCnaTC76zzGnwbS_3c,1504
|
|
108
109
|
pymax/types/__init__.py,sha256=y77mfDRgxmfcamobi0rj2d3PsxhH0zxyvKPhL2iUdS8,44
|
|
109
110
|
pymax/types/domain/__init__.py,sha256=R4iJv0b5gnNVG3MrerVlGVzPvNR-n36QZFukEX64fn4,470
|
|
110
|
-
pymax/types/domain/auth.py,sha256=
|
|
111
|
+
pymax/types/domain/auth.py,sha256=RmEXFS7TAgtFhnfXaiJH5XDb__2MUVgQ_Noavo9hFRY,6019
|
|
111
112
|
pymax/types/domain/base.py,sha256=Q32PcKR3gtrISySowR3zPyl9KeQCoUL6lfyTR3ulMzo,623
|
|
112
113
|
pymax/types/domain/bots.py,sha256=dErZZbvspznU6yUupzCs4R55pEWgoeps7NEhZFrb-Uo,333
|
|
113
|
-
pymax/types/domain/chat.py,sha256=
|
|
114
|
-
pymax/types/domain/element.py,sha256=
|
|
114
|
+
pymax/types/domain/chat.py,sha256=QYuE0jN7wKpjJm3BfDY8KHO_S-4XPN5FRQrtWEZjmkk,19781
|
|
115
|
+
pymax/types/domain/element.py,sha256=Hks0MulMcPAhbpuUmJa5c2d9Emwy3garh1k6bd4QHKA,655
|
|
115
116
|
pymax/types/domain/enums.py,sha256=eGMWnlv0mYJ8K-0FsC_wp4Co2M6YWyKI1Lx90MJ6s4g,412
|
|
116
117
|
pymax/types/domain/error.py,sha256=WZoDAXf5vt8O4VYy7iEHLGBfH6hZQZ1fVkTz9rVCTN0,584
|
|
117
118
|
pymax/types/domain/folder.py,sha256=Z9pXMzOTfxuhUfrJpLjl5LPnVXqqFsBVfKBQm4IbGWM,2225
|
|
118
119
|
pymax/types/domain/login.py,sha256=FBKpRhNPv6Zdjo6Wfl-lK8JpzpMx7zh84f1qrq6Z0og,1301
|
|
119
120
|
pymax/types/domain/member.py,sha256=8gUNn4fBS_S2ap45A40lRlrDXYFMoq0Kx-dh57hMWQc,490
|
|
120
|
-
pymax/types/domain/message.py,sha256=
|
|
121
|
+
pymax/types/domain/message.py,sha256=UF88nXBTubAKKQKP4qR_qtHOMS8uRdXCCTm8jtsu0wA,15678
|
|
121
122
|
pymax/types/domain/name.py,sha256=qMIshIqgWkVuROxmiCRhwfJf8XtmhSBoEU6nXs_gEh0,523
|
|
122
|
-
pymax/types/domain/presence.py,sha256=
|
|
123
|
+
pymax/types/domain/presence.py,sha256=lKvkK0uYwY0gTSEEkaVdI-tEpWjxLOtH7gp2dy5Uh-0,534
|
|
123
124
|
pymax/types/domain/profile.py,sha256=taN5PjlKp4EDypVhDx89vmBDpSKh-kT-ISpu1tR2cY8,471
|
|
124
125
|
pymax/types/domain/session.py,sha256=T0b0qjI65kNQOCgx3nIkaIqynD4eGKyqnscbIlPFVnQ,2002
|
|
125
|
-
pymax/types/domain/sync.py,sha256=
|
|
126
|
+
pymax/types/domain/sync.py,sha256=lBDWo4ACLq2ov5XBccfnI8s_dsGEA7O4mIJVBSUpyrc,3248
|
|
126
127
|
pymax/types/domain/user.py,sha256=NjJfQtkRBrsmB-JGg2nsXWLvgqu3q5YKx2BALkoDrOI,5120
|
|
127
|
-
pymax/types/domain/attachments/__init__.py,sha256=
|
|
128
|
-
pymax/types/domain/attachments/audio.py,sha256=
|
|
128
|
+
pymax/types/domain/attachments/__init__.py,sha256=ZVSb7sSAwabSB8A8BWF_JbooPOMIP1r6gF_NUASgGGk,471
|
|
129
|
+
pymax/types/domain/attachments/audio.py,sha256=I_Qq1qQ9bXsEzWwxEbQbkiY8CEjSKqGqinDFYY_5DY8,1117
|
|
129
130
|
pymax/types/domain/attachments/call.py,sha256=RV-BFutymZFinzUiRdaIryqx6ubku2v6y6brc-qsHOQ,818
|
|
130
131
|
pymax/types/domain/attachments/contact.py,sha256=EO-B0klgUMITL05fBgFXi99i8VzxBj3D2pLB0JBWy_M,996
|
|
131
132
|
pymax/types/domain/attachments/control.py,sha256=1Zr0pM1ODZgYRX3CDw7yGzqEgb6R_JjRSQOSI_FDpDE,502
|
|
132
|
-
pymax/types/domain/attachments/enums.py,sha256=
|
|
133
|
+
pymax/types/domain/attachments/enums.py,sha256=JYX5xoefm0BmRqVjOZs0-xQpI9bddphps_wZX34tK14,643
|
|
133
134
|
pymax/types/domain/attachments/file.py,sha256=3lqsPIkg75-AmcaEbXwc1eiQHIv9JpWzMc0z4u2MupE,1595
|
|
134
135
|
pymax/types/domain/attachments/photo.py,sha256=8q79OuQ0V8t-s9pZM8ClAmgJI71m-bgES4Bd5ZSNVI0,1413
|
|
135
136
|
pymax/types/domain/attachments/share.py,sha256=BHJIVjTC99wfbUn8wSN4j0aSNlEpojzv87uwbmhPPt0,924
|
|
136
137
|
pymax/types/domain/attachments/sticker.py,sha256=2CFqoUAuUjA6nclRXZUCBO2mKZd24BaBY3wz2XoR7kE,1530
|
|
137
|
-
pymax/types/domain/attachments/
|
|
138
|
+
pymax/types/domain/attachments/unknown.py,sha256=oThuTVkzkdmpCftRoa42b1jyy-QbBbfgyc0ocX0jeS8,917
|
|
139
|
+
pymax/types/domain/attachments/video.py,sha256=82stz0MYkypJOP0JAwNGPEV783ODMJabYxRzTqGxmuE,2909
|
|
138
140
|
pymax/types/domain/attachments/keyboards/__init__.py,sha256=1X5UGBe5E_DO7e4p8_JmJEocHLzXOezutieRuQsVpRA,45
|
|
139
141
|
pymax/types/domain/attachments/keyboards/inline.py,sha256=3RNubcqx7RZ1f6zfJ7JaNFCPx5mnmJ5vYsL1i7lSMAM,577
|
|
140
|
-
pymax/types/events/__init__.py,sha256=
|
|
142
|
+
pymax/types/events/__init__.py,sha256=2kW0ttQvU1xhMSYhOZs3kua3JDfMdeSr-vM81o87_w0,257
|
|
141
143
|
pymax/types/events/file.py,sha256=XhpXn0Vt9OODkx1OkGb9jfQwc1uNgz1NTn_j9FZnQ8s,102
|
|
142
|
-
pymax/types/events/
|
|
144
|
+
pymax/types/events/mark.py,sha256=5o3QP3VH9NJBVonBJNf88pzXkS9lLYaDFyju6yczAow,894
|
|
145
|
+
pymax/types/events/message.py,sha256=o2ql3y1DzM-OKg72LR5dr4aCelGksBypIevTEmG-0K4,3249
|
|
146
|
+
pymax/types/events/presence.py,sha256=77Cy352CdfIkbH6ZfLijHffF8gcMz-AZk5OCeESQeDY,451
|
|
147
|
+
pymax/types/events/reaction.py,sha256=7kauScAH8O-K79xS6Q3b6Vi0KwRl4lGCKGeAMAH9sEU,672
|
|
148
|
+
pymax/types/events/typing.py,sha256=vDMgqYE0jz8dN2YfqsNaJLB8k7pMd6kaDEdR_KrLk5g,376
|
|
143
149
|
pymax/types/events/video.py,sha256=swBHYadmDS0SjLXGqVqRYsuMoVZ6MjD2aYR2fbM-AJc,104
|
|
144
|
-
maxapi_python-2.
|
|
145
|
-
maxapi_python-2.
|
|
146
|
-
maxapi_python-2.
|
|
147
|
-
maxapi_python-2.
|
|
150
|
+
maxapi_python-2.2.0.dist-info/METADATA,sha256=TU_EpqMK4HYj7DC-m9UbjhUeDSq2n0WsomqomY5wbD4,7276
|
|
151
|
+
maxapi_python-2.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
152
|
+
maxapi_python-2.2.0.dist-info/licenses/LICENSE,sha256=hOR249ItqMdcly1A0amqEWRNRTq4Gv5NJtmQ3A5qK4E,1070
|
|
153
|
+
maxapi_python-2.2.0.dist-info/RECORD,,
|
pymax/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "2.
|
|
1
|
+
__version__ = "2.2.0"
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
from .auth import (
|
|
@@ -14,13 +14,23 @@ from .auth import (
|
|
|
14
14
|
)
|
|
15
15
|
from .client import Client
|
|
16
16
|
from .client_web import WebClient
|
|
17
|
-
from .config import ExtraConfig
|
|
17
|
+
from .config import ExtraConfig, RegistrationConfig
|
|
18
18
|
from .dispatch import EventType, Router
|
|
19
19
|
from .exceptions import ApiError, PyMaxError, UploadError
|
|
20
20
|
from .files import File, Photo, Video
|
|
21
21
|
from .logging import configure_logging
|
|
22
22
|
from .routers import ClientRouter, WebRouter
|
|
23
|
-
from .types import
|
|
23
|
+
from .types import (
|
|
24
|
+
Chat,
|
|
25
|
+
Message,
|
|
26
|
+
MessageDeleteEvent,
|
|
27
|
+
MessageReadEvent,
|
|
28
|
+
PresenceEvent,
|
|
29
|
+
Profile,
|
|
30
|
+
ReactionUpdateEvent,
|
|
31
|
+
TypingEvent,
|
|
32
|
+
User,
|
|
33
|
+
)
|
|
24
34
|
from .types.domain.sync import SyncOverrides, SyncState
|
|
25
35
|
|
|
26
36
|
__all__ = (
|
|
@@ -37,17 +47,22 @@ __all__ = (
|
|
|
37
47
|
"File",
|
|
38
48
|
"Message",
|
|
39
49
|
"MessageDeleteEvent",
|
|
50
|
+
"MessageReadEvent",
|
|
40
51
|
"PasswordProvider",
|
|
41
52
|
"Photo",
|
|
53
|
+
"PresenceEvent",
|
|
42
54
|
"Profile",
|
|
43
55
|
"PyMaxError",
|
|
44
56
|
"QrAuthFlow",
|
|
45
57
|
"QrHandler",
|
|
58
|
+
"ReactionUpdateEvent",
|
|
59
|
+
"RegistrationConfig",
|
|
46
60
|
"Router",
|
|
47
61
|
"SmsAuthFlow",
|
|
48
62
|
"SmsCodeProvider",
|
|
49
63
|
"SyncOverrides",
|
|
50
64
|
"SyncState",
|
|
65
|
+
"TypingEvent",
|
|
51
66
|
"UploadError",
|
|
52
67
|
"User",
|
|
53
68
|
"Video",
|
pymax/api/auth/payloads.py
CHANGED
|
@@ -131,3 +131,10 @@ class RemoveTwoFactorPayload(CamelModel):
|
|
|
131
131
|
|
|
132
132
|
class ApproveQrLoginPayload(CamelModel):
|
|
133
133
|
qr_link: str
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class ConfirmRegistrationPayload(CamelModel):
|
|
137
|
+
first_name: str
|
|
138
|
+
last_name: str | None = None
|
|
139
|
+
token: str
|
|
140
|
+
token_type: AuthType = AuthType.REGISTER
|
pymax/api/auth/service.py
CHANGED
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
from pymax.api.binding import bind_api_model
|
|
5
6
|
from pymax.api.response import (
|
|
6
7
|
payload_item,
|
|
7
8
|
payload_keys,
|
|
@@ -16,6 +17,7 @@ from pymax.types.domain.auth import (
|
|
|
16
17
|
CheckCodeResponse,
|
|
17
18
|
CheckPasswordResponse,
|
|
18
19
|
CheckQrResponse,
|
|
20
|
+
ConfirmRegistrationResponse,
|
|
19
21
|
RequestQrResponse,
|
|
20
22
|
StartAuthResponse,
|
|
21
23
|
)
|
|
@@ -27,6 +29,7 @@ from .payloads import (
|
|
|
27
29
|
CheckPasswordChallengePayload,
|
|
28
30
|
CheckQrPayload,
|
|
29
31
|
ConfirmQrPayload,
|
|
32
|
+
ConfirmRegistrationPayload,
|
|
30
33
|
CreateAuthTrackPayload,
|
|
31
34
|
MobileUserAgentPayload,
|
|
32
35
|
RemoveTwoFactorPayload,
|
|
@@ -56,18 +59,14 @@ class AuthService:
|
|
|
56
59
|
async def request_code(self, phone: str) -> StartAuthResponse:
|
|
57
60
|
logger.info("requesting sms code phone_set=%s", bool(phone))
|
|
58
61
|
frame = RequestCodePayload(phone=phone)
|
|
59
|
-
response = await self.app.invoke(
|
|
60
|
-
Opcode.AUTH_REQUEST, frame.to_payload()
|
|
61
|
-
)
|
|
62
|
+
response = await self.app.invoke(Opcode.AUTH_REQUEST, frame.to_payload())
|
|
62
63
|
logger.debug(
|
|
63
64
|
"sms code request accepted payload_keys=%s",
|
|
64
65
|
payload_keys(response),
|
|
65
66
|
)
|
|
66
67
|
return require_payload_model(response, StartAuthResponse)
|
|
67
68
|
|
|
68
|
-
async def send_code(
|
|
69
|
-
self, token: str, verify_code: str
|
|
70
|
-
) -> CheckCodeResponse:
|
|
69
|
+
async def send_code(self, token: str, verify_code: str) -> CheckCodeResponse:
|
|
71
70
|
logger.info(
|
|
72
71
|
"sending sms code token_set=%s code_set=%s",
|
|
73
72
|
bool(token),
|
|
@@ -128,7 +127,10 @@ class AuthService:
|
|
|
128
127
|
|
|
129
128
|
logger.debug("login response payload_keys=%s", payload_keys(response))
|
|
130
129
|
|
|
131
|
-
login_response =
|
|
130
|
+
login_response = bind_api_model(
|
|
131
|
+
self.app,
|
|
132
|
+
require_payload_model(response, LoginResponse),
|
|
133
|
+
)
|
|
132
134
|
await self._update_session(login_response)
|
|
133
135
|
return login_response
|
|
134
136
|
|
|
@@ -149,7 +151,10 @@ class AuthService:
|
|
|
149
151
|
|
|
150
152
|
logger.debug("login response payload_keys=%s", payload_keys(response))
|
|
151
153
|
|
|
152
|
-
login_response =
|
|
154
|
+
login_response = bind_api_model(
|
|
155
|
+
self.app,
|
|
156
|
+
require_payload_model(response, LoginResponse),
|
|
157
|
+
)
|
|
153
158
|
await self._update_session(login_response)
|
|
154
159
|
return login_response
|
|
155
160
|
|
|
@@ -161,18 +166,14 @@ class AuthService:
|
|
|
161
166
|
async def check_qr(self, track_id: str) -> CheckQrResponse:
|
|
162
167
|
frame = CheckQrPayload(track_id=track_id)
|
|
163
168
|
|
|
164
|
-
response = await self.app.invoke(
|
|
165
|
-
Opcode.GET_QR_STATUS, frame.to_payload()
|
|
166
|
-
)
|
|
169
|
+
response = await self.app.invoke(Opcode.GET_QR_STATUS, frame.to_payload())
|
|
167
170
|
|
|
168
171
|
return require_payload_model(response, CheckQrResponse)
|
|
169
172
|
|
|
170
173
|
async def confirm_qr(self, track_id: str) -> CheckCodeResponse:
|
|
171
174
|
frame = ConfirmQrPayload(track_id=track_id)
|
|
172
175
|
|
|
173
|
-
response = await self.app.invoke(
|
|
174
|
-
Opcode.LOGIN_BY_QR, frame.to_payload()
|
|
175
|
-
)
|
|
176
|
+
response = await self.app.invoke(Opcode.LOGIN_BY_QR, frame.to_payload())
|
|
176
177
|
|
|
177
178
|
return require_payload_model(response, CheckCodeResponse)
|
|
178
179
|
|
|
@@ -195,15 +196,11 @@ class AuthService:
|
|
|
195
196
|
logger.debug("creating auth track")
|
|
196
197
|
frame = CreateAuthTrackPayload()
|
|
197
198
|
|
|
198
|
-
response = await self.app.invoke(
|
|
199
|
-
Opcode.AUTH_CREATE_TRACK, frame.to_payload()
|
|
200
|
-
)
|
|
199
|
+
response = await self.app.invoke(Opcode.AUTH_CREATE_TRACK, frame.to_payload())
|
|
201
200
|
|
|
202
201
|
return payload_item(response, "trackId", str)
|
|
203
202
|
|
|
204
|
-
async def _set_email(
|
|
205
|
-
self, track_id: str, email: str, provider: EmailCodeProvider
|
|
206
|
-
) -> bool:
|
|
203
|
+
async def _set_email(self, track_id: str, email: str, provider: EmailCodeProvider) -> bool:
|
|
207
204
|
logger.info("setting 2fa email email_set=%s", bool(email))
|
|
208
205
|
|
|
209
206
|
frame = RequestEmailCodePayload(
|
|
@@ -242,9 +239,7 @@ class AuthService:
|
|
|
242
239
|
track_id=track_id,
|
|
243
240
|
password=password,
|
|
244
241
|
)
|
|
245
|
-
await self.app.invoke(
|
|
246
|
-
Opcode.AUTH_VALIDATE_PASSWORD, frame.to_payload()
|
|
247
|
-
)
|
|
242
|
+
await self.app.invoke(Opcode.AUTH_VALIDATE_PASSWORD, frame.to_payload())
|
|
248
243
|
|
|
249
244
|
return True
|
|
250
245
|
|
|
@@ -344,14 +339,9 @@ class AuthService:
|
|
|
344
339
|
if not self.app.me or not self.app.me.profile_options:
|
|
345
340
|
return False
|
|
346
341
|
|
|
347
|
-
return
|
|
348
|
-
ProfileOptions.SECOND_FACTOR_PASSWORD_ENABLED
|
|
349
|
-
in self.app.me.profile_options
|
|
350
|
-
)
|
|
342
|
+
return ProfileOptions.SECOND_FACTOR_PASSWORD_ENABLED in self.app.me.profile_options
|
|
351
343
|
|
|
352
|
-
async def change_password(
|
|
353
|
-
self, password_old: str, password_new: str
|
|
354
|
-
) -> bool:
|
|
344
|
+
async def change_password(self, password_old: str, password_new: str) -> bool:
|
|
355
345
|
track_id = await self._get_track_id()
|
|
356
346
|
|
|
357
347
|
if not track_id:
|
|
@@ -374,3 +364,16 @@ class AuthService:
|
|
|
374
364
|
await self.app.invoke(Opcode.AUTH_SET_2FA, frame.to_payload())
|
|
375
365
|
logger.info("2fa password set successfully")
|
|
376
366
|
return True
|
|
367
|
+
|
|
368
|
+
async def confirm_registration(
|
|
369
|
+
self, first_name: str, last_name: str | None, token: str
|
|
370
|
+
) -> ConfirmRegistrationResponse:
|
|
371
|
+
frame = ConfirmRegistrationPayload(
|
|
372
|
+
first_name=first_name,
|
|
373
|
+
last_name=last_name,
|
|
374
|
+
token=token,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
response = await self.app.invoke(Opcode.AUTH_CONFIRM, frame.to_payload())
|
|
378
|
+
|
|
379
|
+
return require_payload_model(response, ConfirmRegistrationResponse)
|
pymax/api/binding.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable, Mapping
|
|
4
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from pymax.types.domain import Chat, Message, User
|
|
9
|
+
from pymax.types.events import MessageDeleteEvent
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pymax.app import App
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
T = TypeVar("T")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def bind_api_model(app: App, value: T) -> T:
|
|
19
|
+
_bind_api_value(app, value, set())
|
|
20
|
+
return value
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def bind_api_models(app: App, values: Iterable[T]) -> list[T]:
|
|
24
|
+
return [bind_api_model(app, value) for value in values]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _bind_api_value(app: App, value: Any, seen: set[int]) -> None:
|
|
28
|
+
if value is None or isinstance(value, (str, bytes)):
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
value_id = id(value)
|
|
32
|
+
if value_id in seen:
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
seen.add(value_id)
|
|
36
|
+
|
|
37
|
+
if isinstance(value, Message):
|
|
38
|
+
value.bind(app.api.messages)
|
|
39
|
+
elif isinstance(value, Chat):
|
|
40
|
+
value.bind(app.api.messages, app.api.chats)
|
|
41
|
+
elif isinstance(value, User):
|
|
42
|
+
value.bind(app.api.users)
|
|
43
|
+
elif isinstance(value, MessageDeleteEvent):
|
|
44
|
+
value.bind(app.api.messages)
|
|
45
|
+
|
|
46
|
+
if isinstance(value, BaseModel):
|
|
47
|
+
for field_name in value.__class__.model_fields:
|
|
48
|
+
_bind_api_value(app, getattr(value, field_name, None), seen)
|
|
49
|
+
|
|
50
|
+
for extra_value in (value.model_extra or {}).values():
|
|
51
|
+
_bind_api_value(app, extra_value, seen)
|
|
52
|
+
elif isinstance(value, Mapping):
|
|
53
|
+
for item in value.values():
|
|
54
|
+
_bind_api_value(app, item, seen)
|
|
55
|
+
elif isinstance(value, Iterable):
|
|
56
|
+
for item in value:
|
|
57
|
+
_bind_api_value(app, item, seen)
|