lexmount 0.3.1__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.
@@ -0,0 +1,3 @@
1
+ # Lexmount API Configuration
2
+ LEXMOUNT_API_KEY=your-api-key-here
3
+ LEXMOUNT_PROJECT_ID=your-project-id-here
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2025-01-XX
11
+
12
+ ### Added
13
+ - Initial release of Lexmount Python SDK
14
+ - `Lexmount` client for managing browser instances
15
+ - `SessionsResource` for creating and managing browser sessions
16
+ - Support for multiple browser modes (chrome-docker, chrome-light-docker, etc.)
17
+ - Integration with Playwright via CDP WebSocket
18
+ - Environment variable configuration support
19
+ - Basic error handling and timeout management
20
+ - Comprehensive README and API documentation
21
+
22
+ ### Features
23
+ - Create browser sessions with configurable browser modes
24
+ - Retrieve WebSocket URLs for Playwright connection
25
+ - Support for project-level and session-level configuration
26
+ - HTTP client with timeout and error handling
27
+
28
+ [Unreleased]: https://github.com/yourusername/lexmount-python-sdk/compare/v0.1.0...HEAD
29
+ [0.1.0]: https://github.com/yourusername/lexmount-python-sdk/releases/tag/v0.1.0
30
+
lexmount-0.3.1/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lexmount
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,49 @@
1
+ # 核心文档
2
+ include README.md
3
+ include LICENSE
4
+ include CHANGELOG.md
5
+
6
+ # 配置文件
7
+ include requirements.txt
8
+ include .env.example
9
+ include pyproject.toml
10
+
11
+ # 源代码
12
+ recursive-include src *.py
13
+
14
+ # API 文档
15
+ recursive-include doc *.md
16
+
17
+ # 示例代码(可选,如果不想包含可以注释掉)
18
+ recursive-include examples *.py
19
+ prune examples/__pycache__
20
+
21
+ # 排除不需要的文件
22
+ recursive-exclude * __pycache__
23
+ recursive-exclude * *.py[co]
24
+ recursive-exclude * *.pyd
25
+ recursive-exclude * .DS_Store
26
+ recursive-exclude * *.so
27
+ recursive-exclude * *.dylib
28
+
29
+ # 排除开发相关文档(用户安装包时不需要)
30
+ prune summary
31
+
32
+ # 排除开发脚本
33
+ recursive-exclude scripts *
34
+
35
+ # 排除测试和其他开发文件
36
+ exclude .gitignore
37
+ exclude .env
38
+ exclude screenshot.png
39
+ exclude *.png
40
+ exclude *.jpg
41
+ exclude *.jpeg
42
+ prune tests
43
+ prune .git
44
+ prune .github
45
+ prune build
46
+ prune dist
47
+ prune *.egg-info
48
+ exclude INSTALL_FROM_COS.md
49
+
@@ -0,0 +1,534 @@
1
+ Metadata-Version: 2.4
2
+ Name: lexmount
3
+ Version: 0.3.1
4
+ Summary: Python SDK for Lexmount browser automation service
5
+ Author-email: Your Name <your.email@example.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yourusername/lexmount-python-sdk
8
+ Project-URL: Documentation, https://github.com/yourusername/lexmount-python-sdk/blob/main/doc/api.md
9
+ Project-URL: Repository, https://github.com/yourusername/lexmount-python-sdk
10
+ Project-URL: Bug Tracker, https://github.com/yourusername/lexmount-python-sdk/issues
11
+ Keywords: browser,automation,playwright,selenium,cloud,testing
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Operating System :: OS Independent
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: httpx>=0.23.0
28
+ Requires-Dist: python-dotenv>=0.19.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
31
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
32
+ Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
33
+ Requires-Dist: respx>=0.20.0; extra == "dev"
34
+ Requires-Dist: pytest-timeout>=2.1.0; extra == "dev"
35
+ Requires-Dist: black>=22.0.0; extra == "dev"
36
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
37
+ Requires-Dist: mypy>=0.950; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # Lexmount Python SDK
41
+
42
+ [English](#english) | [中文](#中文)
43
+
44
+ ---
45
+
46
+ ## English
47
+
48
+ Python SDK for Lexmount browser automation service.
49
+
50
+ ### ✨ Features
51
+
52
+ - 🚀 **Easy to Use**: Simple and intuitive API design
53
+ - 🔒 **Type-Safe**: Complete type hints for better IDE support
54
+ - 📝 **Well Documented**: Comprehensive docstrings and examples
55
+ - 🛡️ **Production Ready**: Error handling, logging, and retry support
56
+ - 📊 **Session Management**: Create, list, and delete browser sessions
57
+ - 🔍 **Advanced Querying**: Pagination support and status filtering
58
+
59
+ ### 📦 Installation
60
+
61
+ ```bash
62
+ pip install lexmount
63
+ ```
64
+
65
+ **Requirements:**
66
+ - Python 3.8+
67
+ - httpx >= 0.23.0
68
+ - python-dotenv >= 0.19.0
69
+ - playwright (optional, for browser automation)
70
+
71
+ ### 🚀 Quick Start
72
+
73
+ #### Basic Usage
74
+
75
+ ```python
76
+ from lexmount import Lexmount
77
+
78
+ # Initialize client (credentials from environment variables)
79
+ client = Lexmount(
80
+ api_key="your-api-key",
81
+ project_id="your-project-id"
82
+ )
83
+
84
+ # Create a browser session
85
+ session = client.sessions.create()
86
+ print(f"Session ID: {session.id}")
87
+ print(f"Connect URL: {session.connect_url}")
88
+
89
+ # Close session when done
90
+ session.close()
91
+ ```
92
+
93
+ #### Using Context Managers (Recommended)
94
+
95
+ Context managers provide automatic resource cleanup:
96
+
97
+ ```python
98
+ from lexmount import Lexmount
99
+
100
+ # Client and session will be automatically closed
101
+ with Lexmount(api_key="key", project_id="proj") as client:
102
+ with client.sessions.create() as session:
103
+ print(f"Using session: {session.id}")
104
+ # Use session...
105
+ # Automatically closed on exit
106
+ ```
107
+
108
+ #### Integration with Playwright
109
+
110
+ ```python
111
+ from lexmount import Lexmount
112
+ from playwright.sync_api import sync_playwright
113
+
114
+ # Create session
115
+ client = Lexmount(api_key="key", project_id="proj")
116
+ session = client.sessions.create()
117
+
118
+ # Connect with Playwright
119
+ with sync_playwright() as p:
120
+ browser = p.chromium.connect_over_cdp(session.connect_url)
121
+ page = browser.new_page()
122
+
123
+ page.goto("https://example.com")
124
+ print(page.title())
125
+
126
+ browser.close()
127
+
128
+ session.close()
129
+ ```
130
+
131
+ ### 📚 Core Features
132
+
133
+ #### Session Management
134
+
135
+ **Create Session**
136
+
137
+ ```python
138
+ # Basic creation
139
+ session = client.sessions.create()
140
+
141
+ # With specific browser mode
142
+ session = client.sessions.create(browser_mode="normal")
143
+
144
+ # Available browser modes:
145
+ # - "normal": Chrome in Docker container
146
+ # - "light": Lightweight Chrome in Docker
147
+ ```
148
+
149
+ **List Sessions**
150
+
151
+ ```python
152
+ # List all sessions with pagination
153
+ result = client.sessions.list()
154
+ print(f"Total: {result.pagination.total_count}")
155
+ print(f"Active: {result.pagination.active_count}")
156
+
157
+ for session in result.sessions:
158
+ print(f"{session.id}: {session.status}")
159
+
160
+ # Filter by status (server-side filtering)
161
+ active_sessions = client.sessions.list(status="active")
162
+ print(f"Found {len(active_sessions)} active sessions")
163
+ ```
164
+
165
+ **Delete Session**
166
+
167
+ ```python
168
+ # Delete by session ID
169
+ client.sessions.delete(session_id="session-id")
170
+
171
+ # Or use session object
172
+ session.close()
173
+ ```
174
+
175
+ #### Error Handling
176
+
177
+ ```python
178
+ from lexmount import (
179
+ Lexmount,
180
+ AuthenticationError,
181
+ SessionNotFoundError,
182
+ TimeoutError,
183
+ NetworkError,
184
+ APIError
185
+ )
186
+
187
+ try:
188
+ client = Lexmount(api_key="key", project_id="proj")
189
+ session = client.sessions.create()
190
+ except AuthenticationError:
191
+ print("Invalid credentials")
192
+ except TimeoutError:
193
+ print("Request timed out")
194
+ except NetworkError:
195
+ print("Network connection failed")
196
+ except APIError as e:
197
+ print(f"API error: {e.status_code}")
198
+ ```
199
+
200
+ #### Logging
201
+
202
+ ```python
203
+ from lexmount import set_log_level
204
+
205
+ # Enable debug logging
206
+ set_log_level("DEBUG")
207
+
208
+ # Available levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
209
+ client = Lexmount(api_key="key", project_id="proj")
210
+ session = client.sessions.create() # Will log detailed info
211
+ ```
212
+
213
+ ### 📖 API Reference
214
+
215
+ #### Lexmount Client
216
+
217
+ ```python
218
+ Lexmount(
219
+ api_key: str = None, # API key (or LEXMOUNT_API_KEY env var)
220
+ project_id: str = None, # Project ID (or LEXMOUNT_PROJECT_ID env var)
221
+ base_url: str = None, # API URL (or LEXMOUNT_BASE_URL env var)
222
+ timeout: float = 60.0 # Request timeout in seconds
223
+ )
224
+ ```
225
+
226
+ #### Sessions Resource
227
+
228
+ **`sessions.create()`** - Create a new browser session
229
+
230
+ - **Parameters:**
231
+ - `project_id` (str, optional): Override default project ID
232
+ - `browser_mode` (str, optional): Browser mode (default: "normal")
233
+ - **Returns:** `SessionInfo` object
234
+ - **Raises:** `AuthenticationError`, `ValidationError`, `APIError`, `NetworkError`, `TimeoutError`
235
+
236
+ **`sessions.list()`** - List browser sessions with pagination
237
+
238
+ - **Parameters:**
239
+ - `project_id` (str, optional): Override default project ID
240
+ - `status` (str, optional): Filter by status ("active", "closed", or None for all)
241
+ - **Returns:** `SessionListResponse` with sessions and pagination info
242
+ - **Raises:** `AuthenticationError`, `APIError`, `NetworkError`, `TimeoutError`
243
+
244
+ **`sessions.delete()`** - Delete a browser session
245
+
246
+ - **Parameters:**
247
+ - `session_id` (str, required): Session ID to delete
248
+ - `project_id` (str, optional): Override default project ID
249
+ - **Returns:** None
250
+ - **Raises:** `AuthenticationError`, `SessionNotFoundError`, `APIError`
251
+
252
+ #### SessionInfo Object
253
+
254
+ **Attributes:**
255
+ - `id` (str): Session identifier
256
+ - `session_id` (str): Alias for id
257
+ - `status` (str): Session status ("active", "closed")
258
+ - `browser_type` (str): Browser mode used
259
+ - `created_at` (str): ISO 8601 timestamp
260
+ - `connect_url` (str): WebSocket URL for Playwright
261
+ - `ws` (str): Alias for connect_url
262
+ - `container_id` (str): Docker container ID (if applicable)
263
+ - `inspect_url` (str): Chrome DevTools inspection URL
264
+
265
+ **Methods:**
266
+ - `close()`: Close the session and release resources
267
+ - `__enter__()`, `__exit__()`: Context manager support
268
+
269
+ ### 🔧 Configuration
270
+
271
+ #### Environment Variables
272
+
273
+ ```bash
274
+ export LEXMOUNT_API_KEY="your-api-key"
275
+ export LEXMOUNT_PROJECT_ID="your-project-id"
276
+ export LEXMOUNT_BASE_URL="https://api.lexmount.com" # Optional
277
+ ```
278
+
279
+ Or use a `.env` file:
280
+
281
+ ```bash
282
+ LEXMOUNT_API_KEY=your-api-key
283
+ LEXMOUNT_PROJECT_ID=your-project-id
284
+ ```
285
+
286
+ ### 📄 License
287
+
288
+ MIT License
289
+
290
+ ---
291
+
292
+ ## 中文
293
+
294
+ Lexmount 浏览器自动化服务的 Python SDK。
295
+
296
+ ### ✨ 特性
297
+
298
+ - 🚀 **简单易用**:直观的 API 设计
299
+ - 🔒 **类型安全**:完整的类型提示,IDE 支持友好
300
+ - 📝 **文档完善**:详细的文档和示例
301
+ - 🛡️ **生产就绪**:错误处理、日志记录、重试支持
302
+ - 📊 **会话管理**:创建、列表、删除浏览器会话
303
+ - 🔍 **高级查询**:支持分页和状态过滤
304
+
305
+ ### 📦 安装
306
+
307
+ ```bash
308
+ pip install lexmount
309
+ ```
310
+
311
+ **依赖要求:**
312
+ - Python 3.8+
313
+ - httpx >= 0.23.0
314
+ - python-dotenv >= 0.19.0
315
+ - playwright(可选,用于浏览器自动化)
316
+
317
+ ### 🚀 快速开始
318
+
319
+ #### 基础用法
320
+
321
+ ```python
322
+ from lexmount import Lexmount
323
+
324
+ # 初始化客户端(从环境变量读取凭据)
325
+ client = Lexmount(
326
+ api_key="your-api-key",
327
+ project_id="your-project-id"
328
+ )
329
+
330
+ # 创建浏览器会话
331
+ session = client.sessions.create()
332
+ print(f"会话 ID: {session.id}")
333
+ print(f"连接 URL: {session.connect_url}")
334
+
335
+ # 使用完毕后关闭会话
336
+ session.close()
337
+ ```
338
+
339
+ #### 使用上下文管理器(推荐)
340
+
341
+ 上下文管理器提供自动资源清理:
342
+
343
+ ```python
344
+ from lexmount import Lexmount
345
+
346
+ # 客户端和会话会自动关闭
347
+ with Lexmount(api_key="key", project_id="proj") as client:
348
+ with client.sessions.create() as session:
349
+ print(f"使用会话: {session.id}")
350
+ # 使用会话...
351
+ # 退出时自动关闭
352
+ ```
353
+
354
+ #### 与 Playwright 集成
355
+
356
+ ```python
357
+ from lexmount import Lexmount
358
+ from playwright.sync_api import sync_playwright
359
+
360
+ # 创建会话
361
+ client = Lexmount(api_key="key", project_id="proj")
362
+ session = client.sessions.create()
363
+
364
+ # 使用 Playwright 连接
365
+ with sync_playwright() as p:
366
+ browser = p.chromium.connect_over_cdp(session.connect_url)
367
+ page = browser.new_page()
368
+
369
+ page.goto("https://example.com")
370
+ print(page.title())
371
+
372
+ browser.close()
373
+
374
+ session.close()
375
+ ```
376
+
377
+ ### 📚 核心功能
378
+
379
+ #### 会话管理
380
+
381
+ **创建会话**
382
+
383
+ ```python
384
+ # 基础创建
385
+ session = client.sessions.create()
386
+
387
+ # 指定浏览器模式
388
+ session = client.sessions.create(browser_mode="normal")
389
+
390
+ # 可用的浏览器模式:
391
+ # - "normal": Docker 中的 Chrome
392
+ # - "light": Docker 中的轻量级 Chrome
393
+ ```
394
+
395
+ **列出会话**
396
+
397
+ ```python
398
+ # 列出所有会话(带分页信息)
399
+ result = client.sessions.list()
400
+ print(f"总计: {result.pagination.total_count}")
401
+ print(f"活跃: {result.pagination.active_count}")
402
+
403
+ for session in result.sessions:
404
+ print(f"{session.id}: {session.status}")
405
+
406
+ # 按状态过滤(服务端过滤)
407
+ active_sessions = client.sessions.list(status="active")
408
+ print(f"找到 {len(active_sessions)} 个活跃会话")
409
+ ```
410
+
411
+ **删除会话**
412
+
413
+ ```python
414
+ # 通过会话 ID 删除
415
+ client.sessions.delete(session_id="session-id")
416
+
417
+ # 或使用会话对象
418
+ session.close()
419
+ ```
420
+
421
+ #### 错误处理
422
+
423
+ ```python
424
+ from lexmount import (
425
+ Lexmount,
426
+ AuthenticationError,
427
+ SessionNotFoundError,
428
+ TimeoutError,
429
+ NetworkError,
430
+ APIError
431
+ )
432
+
433
+ try:
434
+ client = Lexmount(api_key="key", project_id="proj")
435
+ session = client.sessions.create()
436
+ except AuthenticationError:
437
+ print("认证失败")
438
+ except TimeoutError:
439
+ print("请求超时")
440
+ except NetworkError:
441
+ print("网络连接失败")
442
+ except APIError as e:
443
+ print(f"API 错误: {e.status_code}")
444
+ ```
445
+
446
+ #### 日志配置
447
+
448
+ ```python
449
+ from lexmount import set_log_level
450
+
451
+ # 启用调试日志
452
+ set_log_level("DEBUG")
453
+
454
+ # 可用级别:DEBUG, INFO, WARNING, ERROR, CRITICAL
455
+ client = Lexmount(api_key="key", project_id="proj")
456
+ session = client.sessions.create() # 会输出详细日志
457
+ ```
458
+
459
+ ### 📖 API 参考
460
+
461
+ #### Lexmount 客户端
462
+
463
+ ```python
464
+ Lexmount(
465
+ api_key: str = None, # API 密钥(或 LEXMOUNT_API_KEY 环境变量)
466
+ project_id: str = None, # 项目 ID(或 LEXMOUNT_PROJECT_ID 环境变量)
467
+ base_url: str = None, # API 地址(或 LEXMOUNT_BASE_URL 环境变量)
468
+ timeout: float = 60.0 # 请求超时时间(秒)
469
+ )
470
+ ```
471
+
472
+ #### Sessions 资源
473
+
474
+ **`sessions.create()`** - 创建新的浏览器会话
475
+
476
+ - **参数:**
477
+ - `project_id` (str, 可选): 覆盖默认项目 ID
478
+ - `browser_mode` (str, 可选): 浏览器模式(默认: "normal")
479
+ - **返回:** `SessionInfo` 对象
480
+ - **异常:** `AuthenticationError`, `ValidationError`, `APIError`, `NetworkError`, `TimeoutError`
481
+
482
+ **`sessions.list()`** - 列出浏览器会话(带分页)
483
+
484
+ - **参数:**
485
+ - `project_id` (str, 可选): 覆盖默认项目 ID
486
+ - `status` (str, 可选): 按状态过滤("active"、"closed" 或 None 表示全部)
487
+ - **返回:** `SessionListResponse`,包含会话列表和分页信息
488
+ - **异常:** `AuthenticationError`, `APIError`, `NetworkError`, `TimeoutError`
489
+
490
+ **`sessions.delete()`** - 删除浏览器会话
491
+
492
+ - **参数:**
493
+ - `session_id` (str, 必需): 要删除的会话 ID
494
+ - `project_id` (str, 可选): 覆盖默认项目 ID
495
+ - **返回:** None
496
+ - **异常:** `AuthenticationError`, `SessionNotFoundError`, `APIError`
497
+
498
+ #### SessionInfo 对象
499
+
500
+ **属性:**
501
+ - `id` (str): 会话标识符
502
+ - `session_id` (str): id 的别名
503
+ - `status` (str): 会话状态("active", "closed")
504
+ - `browser_type` (str): 使用的浏览器模式
505
+ - `created_at` (str): ISO 8601 时间戳
506
+ - `connect_url` (str): Playwright 的 WebSocket URL
507
+ - `ws` (str): connect_url 的别名
508
+ - `container_id` (str): Docker 容器 ID(如适用)
509
+ - `inspect_url` (str): Chrome DevTools 检查 URL
510
+
511
+ **方法:**
512
+ - `close()`: 关闭会话并释放资源
513
+ - `__enter__()`, `__exit__()`: 上下文管理器支持
514
+
515
+ ### 🔧 配置
516
+
517
+ #### 环境变量
518
+
519
+ ```bash
520
+ export LEXMOUNT_API_KEY="your-api-key"
521
+ export LEXMOUNT_PROJECT_ID="your-project-id"
522
+ export LEXMOUNT_BASE_URL="https://api.lexmount.com" # 可选
523
+ ```
524
+
525
+ 或使用 `.env` 文件:
526
+
527
+ ```bash
528
+ LEXMOUNT_API_KEY=your-api-key
529
+ LEXMOUNT_PROJECT_ID=your-project-id
530
+ ```
531
+
532
+ ### 📄 许可证
533
+
534
+ MIT License