maxapi-python 1.1.21__tar.gz → 1.2.2__tar.gz

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.
Files changed (68) hide show
  1. maxapi_python-1.2.2/.github/workflows/tests.yml +153 -0
  2. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.gitignore +1 -1
  3. maxapi_python-1.1.21/README.md → maxapi_python-1.2.2/PKG-INFO +66 -0
  4. maxapi_python-1.1.21/PKG-INFO → maxapi_python-1.2.2/README.md +36 -22
  5. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/examples/example.py +2 -6
  6. maxapi_python-1.2.2/examples/test.py +20 -0
  7. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/pyproject.toml +54 -1
  8. maxapi_python-1.2.2/pytest.ini +26 -0
  9. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/clients.rst +22 -0
  10. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/core.py +14 -152
  11. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/crud.py +1 -1
  12. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/formatting.py +4 -6
  13. maxapi_python-1.2.2/src/pymax/interfaces.py +256 -0
  14. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/auth.py +162 -20
  15. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/socket.py +30 -43
  16. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/websocket.py +7 -16
  17. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/payloads.py +29 -14
  18. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/static/constant.py +2 -2
  19. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/static/enum.py +4 -0
  20. maxapi_python-1.1.21/pytest.ini +0 -6
  21. maxapi_python-1.1.21/src/pymax/interfaces.py +0 -122
  22. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.coderabbit.yaml +0 -0
  23. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.github/FUNDING.yml +0 -0
  24. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  25. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  26. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.github/ISSUE_TEMPLATE/refactor.md +0 -0
  27. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.github/pull_request_template.md +0 -0
  28. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.github/workflows/publish.yml +0 -0
  29. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/.pre-commit-config.yaml +0 -0
  30. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/LICENSE +0 -0
  31. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/assets/icon.svg +0 -0
  32. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/assets/logo.svg +0 -0
  33. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/examples/flt_test.py +0 -0
  34. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/examples/large_file_upload.py +0 -0
  35. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/examples/reg.py +0 -0
  36. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/examples/telegram_bridge.py +0 -0
  37. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/mkdocs.yml +0 -0
  38. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/Makefile +0 -0
  39. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/build.sh +0 -0
  40. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/make.bat +0 -0
  41. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/_static/logo.svg +0 -0
  42. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/conf.py +0 -0
  43. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/decorators.rst +0 -0
  44. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/examples.rst +0 -0
  45. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/guides.rst +0 -0
  46. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/index.rst +0 -0
  47. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/installation.rst +0 -0
  48. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/quickstart.rst +0 -0
  49. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/redocs/source/types.rst +0 -0
  50. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/ruff.toml +0 -0
  51. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/__init__.py +0 -0
  52. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/exceptions.py +0 -0
  53. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/files.py +0 -0
  54. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/filters.py +0 -0
  55. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/formatter.py +0 -0
  56. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/__init__.py +0 -0
  57. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/channel.py +0 -0
  58. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/group.py +0 -0
  59. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/handler.py +0 -0
  60. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/message.py +0 -0
  61. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/scheduler.py +0 -0
  62. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/self.py +0 -0
  63. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/telemetry.py +0 -0
  64. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/user.py +0 -0
  65. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/mixins/utils.py +0 -0
  66. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/models.py +0 -0
  67. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/navigation.py +0 -0
  68. {maxapi_python-1.1.21 → maxapi_python-1.2.2}/src/pymax/types.py +0 -0
@@ -0,0 +1,153 @@
1
+ name: Tests
2
+
3
+ #on:
4
+ # push:
5
+ # branches: [ main, develop ]
6
+ # pull_request:
7
+ # branches: [ main, develop ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ['3.10', '3.11', '3.12', '3.13']
16
+
17
+ steps:
18
+ - name: Checkout repository
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Cache pip packages
27
+ uses: actions/cache@v4
28
+ with:
29
+ path: ~/.cache/pip
30
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
31
+ restore-keys: |
32
+ ${{ runner.os }}-pip-
33
+
34
+ - name: Install runtime + test tools
35
+ run: |
36
+ python -m pip install --upgrade pip
37
+ # Устанавливаем package (runtime deps)
38
+ pip install -e "."
39
+ # Явно ставим инструменты для тестов/линта, чтобы они были доступны в runner
40
+ pip install pytest pytest-asyncio pytest-cov pytest-timeout flake8 mypy
41
+
42
+ - name: Lint with flake8
43
+ run: |
44
+ flake8 src/pymax tests \
45
+ --count \
46
+ --select=E9,F63,F7,F82 \
47
+ --show-source \
48
+ --statistics
49
+ flake8 src/pymax tests \
50
+ --count \
51
+ --exit-zero \
52
+ --max-complexity=10 \
53
+ --max-line-length=79 \
54
+ --statistics
55
+ continue-on-error: true
56
+
57
+ - name: Type check with mypy
58
+ run: |
59
+ mypy src/pymax \
60
+ --ignore-missing-imports \
61
+ --no-error-summary
62
+ continue-on-error: true
63
+
64
+ - name: Run unit tests
65
+ run: |
66
+ pytest -m "not mockserver" \
67
+ --cov=src/pymax \
68
+ --cov-report=xml \
69
+ --cov-report=term-missing
70
+
71
+ - name: Upload coverage to Codecov
72
+ uses: codecov/codecov-action@v4
73
+ with:
74
+ files: coverage.xml
75
+ flags: unittests
76
+ name: codecov-umbrella
77
+ fail_ci_if_error: false
78
+
79
+ - name: Archive pytest cache
80
+ if: always()
81
+ uses: actions/upload-artifact@v4
82
+ with:
83
+ name: pytest-cache-${{ matrix.python-version }}
84
+ path: .pytest_cache/
85
+ retention-days: 5
86
+
87
+ integration-tests:
88
+ runs-on: ubuntu-latest
89
+
90
+ steps:
91
+ - name: Checkout repository (with submodules)
92
+ uses: actions/checkout@v4
93
+ with:
94
+ submodules: recursive
95
+
96
+ - name: Set up Python
97
+ uses: actions/setup-python@v5
98
+ with:
99
+ python-version: '3.13'
100
+
101
+ - name: Install runtime + test tools (integration)
102
+ run: |
103
+ python -m pip install --upgrade pip
104
+ pip install -e "."
105
+ pip install pytest pytest-asyncio pytest-cov pytest-timeout flake8 mypy
106
+
107
+ - name: Set up Go
108
+ uses: actions/setup-go@v5
109
+ with:
110
+ go-version: '1.22'
111
+
112
+ - name: Start MockServer
113
+ run: |
114
+ git clone https://github.com/fresh-milkshake/gomax-prerelease.git
115
+ cd gomax-prerelease/mockserver
116
+ go mod download
117
+ go run cmd/server/main.go &
118
+ sleep 3
119
+
120
+ - name: Run integration tests
121
+ run: |
122
+ pytest -m mockserver -v --tb=short
123
+ continue-on-error: true
124
+ env:
125
+ MOCKSERVER_WS_URL: ws://localhost:8080/
126
+ MOCKSERVER_HTTP_URL: http://localhost:8080
127
+
128
+ code-quality:
129
+ runs-on: ubuntu-latest
130
+
131
+ steps:
132
+ - name: Checkout repository
133
+ uses: actions/checkout@v4
134
+
135
+ - name: Set up Python
136
+ uses: actions/setup-python@v5
137
+ with:
138
+ python-version: '3.13'
139
+
140
+ - name: Install dependencies + quality tools
141
+ run: |
142
+ python -m pip install --upgrade pip
143
+ pip install -e "."
144
+ # black/isort/pylint используются только в этом job
145
+ pip install black isort pylint
146
+
147
+ - name: Check code formatting with black
148
+ run: black --check src/pymax tests
149
+ continue-on-error: true
150
+
151
+ - name: Check import sorting with isort
152
+ run: isort --check-only src/pymax tests
153
+ continue-on-error: true
@@ -116,7 +116,7 @@ cache/
116
116
  # Keep lockfiles and important configs tracked? If you want to track specific lockfiles,
117
117
  # remove them from this .gitignore (for example: remove poetry.lock or uv.lock).
118
118
  tests2/
119
- tests/
119
+ tests
120
120
 
121
121
 
122
122
  # Bad dev's requirements
@@ -1,3 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: maxapi-python
3
+ Version: 1.2.2
4
+ Summary: Python wrapper для API мессенджера Max
5
+ Project-URL: Homepage, https://github.com/ink-developer/PyMax
6
+ Project-URL: Repository, https://github.com/ink-developer/PyMax
7
+ Project-URL: Issues, https://github.com/ink-developer/PyMax/issues
8
+ Author-email: ink <mail@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,max,messenger,websocket,wrapper
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: aiofiles>=24.1.0
16
+ Requires-Dist: aiohttp>=3.12.15
17
+ Requires-Dist: lz4>=4.4.4
18
+ Requires-Dist: msgpack>=1.1.1
19
+ Requires-Dist: qrcode>=8.2
20
+ Requires-Dist: sqlmodel>=0.0.24
21
+ Requires-Dist: websockets>=15.0
22
+ Provides-Extra: test
23
+ Requires-Dist: flake8; extra == 'test'
24
+ Requires-Dist: mypy; extra == 'test'
25
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'test'
26
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
27
+ Requires-Dist: pytest-timeout>=2.1.0; extra == 'test'
28
+ Requires-Dist: pytest>=8.0.0; extra == 'test'
29
+ Description-Content-Type: text/markdown
30
+
1
31
  <p align="center">
2
32
  <img src="assets/logo.svg" alt="PyMax" width="400">
3
33
  </p>
@@ -13,6 +43,7 @@
13
43
  <img src="https://img.shields.io/badge/packaging-uv-D7FF64.svg" alt="Packaging">
14
44
  </p>
15
45
 
46
+
16
47
  ---
17
48
  > ⚠️ **Дисклеймер**
18
49
  >
@@ -53,6 +84,41 @@ uv add -U maxapi-python
53
84
 
54
85
  ## Быстрый старт
55
86
 
87
+ ### Аутентификация (`device_type`)
88
+
89
+ > [!IMPORTANT]
90
+ > Параметр `device_type` в `UserAgentPayload` **критически важен** для выбора способа авторизации:
91
+
92
+ **Вход по номеру телефона (DESKTOP):**
93
+
94
+ ```python
95
+ from pymax import MaxClient
96
+ from pymax.payloads import UserAgentPayload
97
+
98
+ ua = UserAgentPayload(device_type="DESKTOP", app_version="25.12.13")
99
+
100
+ client = MaxClient(
101
+ phone="+79111111111",
102
+ work_dir="cache",
103
+ headers=ua,
104
+ )
105
+ ```
106
+
107
+ **Вход через QR-код (WEB)** — токен совместим с веб-версией Max:
108
+
109
+ ```python
110
+ from pymax import MaxClient
111
+ from pymax.payloads import UserAgentPayload
112
+
113
+ ua = UserAgentPayload(device_type="WEB", app_version="25.12.13")
114
+
115
+ client = MaxClient(
116
+ phone="+7911111111",
117
+ work_dir="cache",
118
+ headers=ua,
119
+ )
120
+ ```
121
+
56
122
  ### Базовый пример использования
57
123
 
58
124
  ```python
@@ -1,25 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: maxapi-python
3
- Version: 1.1.21
4
- Summary: Python wrapper для API мессенджера Max
5
- Project-URL: Homepage, https://github.com/ink-developer/PyMax
6
- Project-URL: Repository, https://github.com/ink-developer/PyMax
7
- Project-URL: Issues, https://github.com/ink-developer/PyMax/issues
8
- Author-email: ink <mail@gmail.com>
9
- License-Expression: MIT
10
- License-File: LICENSE
11
- Keywords: api,max,messenger,websocket,wrapper
12
- Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python :: 3
14
- Requires-Python: >=3.10
15
- Requires-Dist: aiofiles>=24.1.0
16
- Requires-Dist: aiohttp>=3.12.15
17
- Requires-Dist: lz4>=4.4.4
18
- Requires-Dist: msgpack>=1.1.1
19
- Requires-Dist: sqlmodel>=0.0.24
20
- Requires-Dist: websockets>=15.0
21
- Description-Content-Type: text/markdown
22
-
23
1
  <p align="center">
24
2
  <img src="assets/logo.svg" alt="PyMax" width="400">
25
3
  </p>
@@ -35,6 +13,7 @@ Description-Content-Type: text/markdown
35
13
  <img src="https://img.shields.io/badge/packaging-uv-D7FF64.svg" alt="Packaging">
36
14
  </p>
37
15
 
16
+
38
17
  ---
39
18
  > ⚠️ **Дисклеймер**
40
19
  >
@@ -75,6 +54,41 @@ uv add -U maxapi-python
75
54
 
76
55
  ## Быстрый старт
77
56
 
57
+ ### Аутентификация (`device_type`)
58
+
59
+ > [!IMPORTANT]
60
+ > Параметр `device_type` в `UserAgentPayload` **критически важен** для выбора способа авторизации:
61
+
62
+ **Вход по номеру телефона (DESKTOP):**
63
+
64
+ ```python
65
+ from pymax import MaxClient
66
+ from pymax.payloads import UserAgentPayload
67
+
68
+ ua = UserAgentPayload(device_type="DESKTOP", app_version="25.12.13")
69
+
70
+ client = MaxClient(
71
+ phone="+79111111111",
72
+ work_dir="cache",
73
+ headers=ua,
74
+ )
75
+ ```
76
+
77
+ **Вход через QR-код (WEB)** — токен совместим с веб-версией Max:
78
+
79
+ ```python
80
+ from pymax import MaxClient
81
+ from pymax.payloads import UserAgentPayload
82
+
83
+ ua = UserAgentPayload(device_type="WEB", app_version="25.12.13")
84
+
85
+ client = MaxClient(
86
+ phone="+7911111111",
87
+ work_dir="cache",
88
+ headers=ua,
89
+ )
90
+ ```
91
+
78
92
  ### Базовый пример использования
79
93
 
80
94
  ```python
@@ -44,9 +44,7 @@ async def handle_start() -> None:
44
44
  messages = []
45
45
  from_time = int(time() * 1000)
46
46
  while len(messages) < max_messages:
47
- r = await client.fetch_history(
48
- chat_id=chat_id, from_time=from_time, backward=30
49
- )
47
+ r = await client.fetch_history(chat_id=chat_id, from_time=from_time, backward=30)
50
48
  if not r:
51
49
  break
52
50
  from_time = r[0].time
@@ -131,9 +129,7 @@ async def handle_start() -> None:
131
129
 
132
130
  @client.on_message()
133
131
  async def handle_message(message: Message) -> None:
134
- print(
135
- f"New message in chat {message.chat_id} from {message.sender}: {message.text}"
136
- )
132
+ print(f"New message in chat {message.chat_id} from {message.sender}: {message.text}")
137
133
  # if message.link and message.link.message.attaches:
138
134
  # for attach in message.link.message.attaches:
139
135
  # print(f"Link attach type: {attach.type}")
@@ -0,0 +1,20 @@
1
+ import asyncio
2
+
3
+ from pymax import MaxClient
4
+ from pymax.payloads import UserAgentPayload
5
+
6
+ ua = UserAgentPayload(device_type="DESKTOP", app_version="25.12.13")
7
+
8
+ client = MaxClient(
9
+ phone="+79116290861",
10
+ work_dir="cache",
11
+ headers=ua,
12
+ )
13
+
14
+
15
+ @client.on_start
16
+ async def on_start() -> None:
17
+ print(f"MaxClient started as {client.me.names[0].first_name}!")
18
+
19
+
20
+ asyncio.run(client.start())
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "maxapi-python"
3
- version = "1.1.21"
3
+ version = "1.2.2"
4
4
  description = "Python wrapper для API мессенджера Max"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -18,6 +18,7 @@ dependencies = [
18
18
  "lz4>=4.4.4",
19
19
  "aiohttp>=3.12.15",
20
20
  "aiofiles>=24.1.0",
21
+ "qrcode>=8.2",
21
22
  ]
22
23
 
23
24
  [project.urls]
@@ -35,7 +36,25 @@ where = ["src"]
35
36
  [tool.setuptools.package-dir]
36
37
  "" = "src"
37
38
 
39
+ [project.optional-dependencies]
40
+ test = [
41
+ "pytest>=8.0.0",
42
+ "pytest-asyncio>=0.24.0",
43
+ "pytest-cov>=5.0.0",
44
+ "pytest-timeout>=2.1.0",
45
+ "flake8",
46
+ "mypy",
47
+ ]
48
+
38
49
  [dependency-groups]
50
+ test = [
51
+ "pytest>=8.0.0",
52
+ "pytest-asyncio>=0.24.0",
53
+ "pytest-cov>=5.0.0",
54
+ "pytest-timeout>=2.1.0",
55
+ "flake8",
56
+ "mypy",
57
+ ]
39
58
  dev = [
40
59
  "furo>=2025.9.25",
41
60
  "ghp-import>=2.1.0",
@@ -45,6 +64,10 @@ dev = [
45
64
  "pre-commit>=4.3.0",
46
65
  "pydocstring>=0.2.1",
47
66
  "sphinx>=8.1.3",
67
+ "pytest>=8.0.0",
68
+ "pytest-asyncio>=0.24.0",
69
+ "pytest-cov>=5.0.0",
70
+ "pytest-timeout>=2.1.0",
48
71
  ]
49
72
 
50
73
  [tool.hatch.build.targets.wheel]
@@ -73,3 +96,33 @@ profile = "black"
73
96
  line_length = 79
74
97
  multi_line_output = 3
75
98
  include_trailing_comma = true
99
+
100
+ [tool.pytest.ini_options]
101
+ asyncio_mode = "auto"
102
+ testpaths = ["tests"]
103
+ python_files = ["test_*.py"]
104
+ python_classes = ["Test*"]
105
+ python_functions = ["test_*"]
106
+ addopts = "-v --tb=short --strict-markers"
107
+ markers = [
108
+ "asyncio: marker for asyncio tests",
109
+ "mockserver: marker for MockServer integration tests",
110
+ "integration: marker for integration tests",
111
+ "slow: marker for slow tests",
112
+ ]
113
+
114
+ [tool.coverage.run]
115
+ source = ["src/pymax"]
116
+ branch = true
117
+
118
+ [tool.coverage.report]
119
+ exclude_lines = [
120
+ "pragma: no cover",
121
+ "def __repr__",
122
+ "raise AssertionError",
123
+ "raise NotImplementedError",
124
+ "if __name__ == .__main__.:",
125
+ "if TYPE_CHECKING:",
126
+ "class .*\\bProtocol\\):",
127
+ "@(abc\\.)?abstractmethod",
128
+ ]
@@ -0,0 +1,26 @@
1
+ [pytest]
2
+
3
+ asyncio_mode = auto
4
+
5
+ testpaths = tests
6
+
7
+ python_files = test_*.py
8
+ python_classes = Test*
9
+ python_functions = test_*
10
+
11
+ addopts =
12
+ -v
13
+ --tb=short
14
+ --strict-markers
15
+ -ra
16
+ --color=yes
17
+
18
+ markers =
19
+ asyncio: асинхронные тесты
20
+ mockserver: интеграционные тесты с MockServer
21
+ integration: интеграционные тесты
22
+ slow: медленные тесты
23
+ unit: модульные тесты
24
+ skip_ci: пропустить в CI
25
+
26
+ timeout = 30
@@ -20,6 +20,28 @@ MaxClient
20
20
  logger=None, # Пользовательский логгер
21
21
  )
22
22
 
23
+ .. warning::
24
+
25
+ Параметр ``device_type`` в ``UserAgentPayload`` **критически важен** для выбора способа авторизации:
26
+
27
+ **DESKTOP** — вход по номеру телефона:
28
+
29
+ .. code-block:: python
30
+
31
+ from pymax.payloads import UserAgentPayload
32
+
33
+ ua = UserAgentPayload(device_type="DESKTOP", app_version="25.12.13")
34
+ client = MaxClient(phone="+79111111111", headers=ua)
35
+
36
+ **WEB** — вход через QR-код; токен совместим с веб-версией Max:
37
+
38
+ .. code-block:: python
39
+
40
+ from pymax.payloads import UserAgentPayload
41
+
42
+ ua = UserAgentPayload(device_type="WEB", app_version="25.12.13")
43
+ client = MaxClient(phone="+79111111111", headers=ua)
44
+
23
45
  Основные методы:
24
46
 
25
47
  .. code-block:: python