redis-xsync 1.0.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,333 @@
1
+ Metadata-Version: 2.4
2
+ Name: redis-xsync
3
+ Version: 1.0.1
4
+ Summary: Sync/Async unified Redis client with distributed lock and rate limiter
5
+ Author: Jay
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/jaygarage/RedisXsync
8
+ Project-URL: Repository, https://github.com/jaygarage/RedisXsync
9
+ Project-URL: Issues, https://github.com/jaygarage/RedisXsync/issues
10
+ Keywords: redis,async,sync,distributed-lock,redis-xsync,rate-limit
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries
14
+ Classifier: Topic :: System :: Distributed Computing
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: License :: OSI Approved :: MIT License
23
+ Classifier: Operating System :: OS Independent
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ Requires-Dist: pydantic>=2.0
27
+ Requires-Dist: redis>=5.0.0
28
+
29
+ # RedisXsync
30
+
31
+ ![PyPI](https://img.shields.io/pypi/v/redis-xsync) ![Python](https://img.shields.io/pypi/pyversions/redis-xsync) ![License](https://img.shields.io/badge/license-MIT-green)
32
+
33
+ RedisXsync 是一个 **同步 / 异步统一 Redis 客户端**,专为 **分布式锁** 和 **爬虫账号池限流** 场景设计,支持多实例、多
34
+ DB,线程安全和协程安全。
35
+
36
+ ---
37
+
38
+ ## ✨ 核心特性
39
+
40
+ | 特性 | 描述 |
41
+ |-------------|----------------------------------|
42
+ | 同步 / 异步统一接口 | 同一套 API 支持 `with` 和 `async with` |
43
+ | 多实例 / 多 DB | 支持不同 Redis 实例与数据库同时管理 |
44
+ | 分布式锁 | 单键锁、组合锁,阻塞 / 非阻塞模式 |
45
+ | 账号池限流 | 基于 Lua 原子操作的令牌桶限流,可等待可用 token |
46
+ | 线程 & 协程安全 | 避免多线程 / 协程冲突 |
47
+ | 自动连接管理 | Context manager 自动释放连接 |
48
+
49
+ ---
50
+
51
+ ## 🏗 架构概览
52
+
53
+ | RedisXsync |
54
+ |--------------------------|
55
+ | Sync / Async Interfaces |
56
+ | Distributed Lock Manager |
57
+ | Rate Limiter / TokenPool |
58
+
59
+ - 分布式锁:通过单键或多键原子操作保证并发安全
60
+ - 限流/账号池:Lua 脚本保证跨进程/跨机器的原子性,精确到毫秒
61
+
62
+ ---
63
+
64
+ ## 📦 安装
65
+
66
+ ```bash
67
+ pip install redis-xsync
68
+
69
+ ---
70
+
71
+ ## 🚀 快速开始
72
+
73
+ ### 1️⃣ 注册 Redis
74
+
75
+ ​```python
76
+ from redis_xsync import register_redis, resolve_redis, redisXsync
77
+
78
+ redis1 = register_redis(
79
+ label="redis_xsync",
80
+ host="127.0.0.1",
81
+ port=6379,
82
+ db=0,
83
+ password=None,
84
+ decode_responses=True
85
+ )
86
+
87
+ # 通过 label 获取
88
+ redis2 = resolve_redis("redis_xsync")
89
+
90
+
91
+ # 使用方式说明:
92
+ # 1️⃣ 全局默认实例 redisXsync
93
+ # - 在首次调用 register_redis 注册任意 Redis 时,首次注册会自动赋值给 redisXsync,非并发安全
94
+ # - 后续可以直接使用 redisXsync,无需通过 label 获取
95
+ #
96
+ # 2️⃣ 通过 label 显式管理 Redis
97
+ # - register_redis(label=..., ...) 注册 Redis 实例
98
+ # - resolve_redis(label) 根据 label 获取对应 Redis 实例
99
+ #
100
+ # 3️⃣ 独立实例
101
+ # - 可以直接创建 RedisXsync() 实例,不必参与 register_redis 、resolve_redis、 redisXsync 全局管理
102
+ # - 适合临时或隔离使用场景
103
+ ```
104
+
105
+ ## 🔄 同步 / 异步使用
106
+
107
+ ### ✅ 同步
108
+
109
+ ```python
110
+ with redis1(db=1) as r:
111
+ r.setnx("key", "value")
112
+ print(r.get("key"))
113
+ ```
114
+
115
+ ---
116
+
117
+ ### ✅ 异步
118
+
119
+ ```python
120
+ import asyncio
121
+
122
+
123
+ async def main():
124
+ async with redis1(db=1) as r:
125
+ await r.setnx("key", "value")
126
+ print(await r.get("key"))
127
+
128
+
129
+ asyncio.run(main())
130
+ ```
131
+
132
+ ---
133
+
134
+ ## 🔐 分布式锁(支持组合锁)
135
+
136
+ ### 特性
137
+
138
+ * 多 key 原子加锁
139
+ * 所有 key 释放才算解锁
140
+ * 支持阻塞等待
141
+
142
+ ---
143
+
144
+ ### 示例(多线程 + 协程混合)
145
+
146
+ ```python
147
+ import threading
148
+ import asyncio
149
+ from redis_xsync import register_redis
150
+
151
+ cx = 0
152
+ redis = register_redis(label="redis_xsync", host="127.0.0.1", port=6379)
153
+ Lock = redis.AsyncRedisAtomicMultiLock
154
+
155
+
156
+ def sync_worker():
157
+ global cx
158
+ for _ in range(5):
159
+ with Lock("lock_key", db=0, ttl_ms=10, blocking=True):
160
+ with redis(db=2) as r:
161
+ r.setnx("db2", str(cx))
162
+ cx += 1
163
+ print(f"[SYNC] {cx=}")
164
+
165
+
166
+ async def async_worker():
167
+ global cx
168
+ for _ in range(5):
169
+ with Lock("lock_key", db=0, ttl_ms=10, blocking=True):
170
+ async with redis(db=3) as r:
171
+ await r.setnx("db3", str(cx))
172
+ cx += 1
173
+ print(f"[ASYNC] {cx=}")
174
+ await asyncio.sleep(0.2)
175
+
176
+
177
+ # 启动线程
178
+ threading.Thread(target=sync_worker).start()
179
+
180
+ # 启动协程
181
+ asyncio.run(async_worker())
182
+ ```
183
+
184
+ ---
185
+
186
+ ## 🚦 爬虫账号池限流
187
+
188
+ 基于 Redis + Lua,实现**分布式限流 + 自动等待可用账号**
189
+
190
+ 📦 Limited — Redis 容器操作方法对照表
191
+
192
+ | 方法 | 异步 | 阻塞 | 遵循限流 | 数量 | 描述 |
193
+ |-----------------------------------------------------|----|----|------|----|------------------------|
194
+ | `set_available_containers(*containers)` | ✅ | ❌ | ✅ | N | 存储/更新容器配置(生产者) |
195
+ | `ask_available_containers(quantity)` | ✅ | ❌ | ✅ | N | 获取 N 个可用容器,若无返回 `None` |
196
+ | `ask_available_container()` | ✅ | ❌ | ✅ | 1 | 获取单个可用容器,若无返回 `None` |
197
+ | `wait_ask_available_containers(quantity, timeout)` | ✅ | ✅ | ✅ | N | 阻塞等待 N 个可用容器 |
198
+ | `wait_ask_available_container(timeout)` | ✅ | ✅ | ✅ | 1 | 阻塞等待单个可用容器 |
199
+ | `acquire_random_containers(quantity)` | ✅ | ❌ | ❌ | N | 随机获取 N 个容器,忽略限流 |
200
+ | `acquire_random_container()` | ✅ | ❌ | ❌ | 1 | 随机获取单个容器,忽略限流 |
201
+ | `wait_acquire_random_containers(quantity, timeout)` | ✅ | ✅ | ❌ | N | 阻塞等待 N 个随机容器,忽略限流 |
202
+ | `wait_acquire_random_container(timeout)` | ✅ | ✅ | ❌ | 1 | 阻塞等待单个随机容器,忽略限流 |
203
+
204
+ ---
205
+
206
+ ### 写入账号(生产者)
207
+
208
+ ## LimitedModel 说明
209
+
210
+ `LimitedModel` 用于表示受限访问(rate-limited)的容器条目,每条数据包含唯一标识、时间戳、TTL、访问间隔和访问计数等信息。
211
+
212
+ ### 字段说明
213
+
214
+ | 字段 | 类型 | 默认值 | 描述 |
215
+ |-----------------------|-------|-----------|---------------------|
216
+ | `id` | `str` | — | 数据唯一标识符,必须提供 |
217
+ | `ct` | `int` | 当前时间戳(毫秒) | 记录条目的收集时间,无需设置 |
218
+ | `ttl_ms` | `int` | `0` | 条目的生存时间(毫秒),0 表示无限期 |
219
+ | `interval_ms` | `int` | `0` | 访问间隔(毫秒),0 表示不限速 |
220
+ | `next_time_available` | `int` | 当前时间戳(毫秒) | 下次可访问时间,用于限流控制,无需设置 |
221
+ | `containers` | `str` | `None` | 存储容器数据,可为空 |
222
+ | `usage_count` | `int` | `0` | 条目被访问的次数,无需设置 |
223
+ ### 使用说明
224
+
225
+ - `ct` 和 `next_time_available` 都以毫秒为单位,便于高精度限流。
226
+ - `interval_ms > 0` 时,访问条目会更新 `next_time_available` 为当前时间 + 间隔。
227
+ - 每次访问条目时,都会通过 `usage_count` 记录被访问次数,以统计和调度。
228
+ - `ttl_ms` 可配合 Redis 等存储设置过期时间,实现自动清理。
229
+
230
+ ```python
231
+ import random
232
+ from redis_xsync import register_redis
233
+ from redis_xsync.rtypes import LimitedModel
234
+
235
+ redis = register_redis(label="redis_xsync", host="127.0.0.1", port=6379)
236
+ Limited = redis.Limited
237
+
238
+
239
+ async def produce_container():
240
+ async with Limited(redis_key="crawler:identity:flow_limit") as lt:
241
+ for i in range(10):
242
+ token = LimitedModel(
243
+ id=f"user_{i}",
244
+ ttl_ms=random.randint(30000, 60000),
245
+ interval_ms=random.randint(1000, 6000),
246
+ containers="cookies"
247
+ )
248
+ await lt.set_available_containers(token)
249
+ ```
250
+
251
+ ---
252
+
253
+ ### 获取账号(消费者,阻塞等待)
254
+
255
+ ```python
256
+ async def consume_token():
257
+ async with Limited(redis_key="crawler:identity:flow_limit") as lt:
258
+ # 等待可用 token,超时 10 秒
259
+ token = await lt.wait_ask_available_containers(quantity=1, timeout=10)
260
+ print("获取到账号:", token)
261
+ ```
262
+
263
+ ---
264
+
265
+ ### 同步调用
266
+
267
+ ```python
268
+ def consume_sync():
269
+ with Limited(redis_key="crawler:identity:flow_limit") as lt:
270
+ token = lt.wait_ask_available_containers(quantity=1, timeout=10)
271
+ print("获取到账号:", token)
272
+ ```
273
+
274
+ ## ⚡ 说明:
275
+
276
+ - produce_container 写入 token 到 Redis,带过期时间和间隔限流
277
+ - consume_token 或 consume_sync 从 Redis 中获取可用 token,如果当前没有可用,会等待直到 timeout
278
+ - 支持异步和同步,且保证跨进程 / 跨机器原子性
279
+
280
+ ---
281
+
282
+ ## 🧠 设计说明
283
+
284
+ ### 🔐 分布式锁
285
+
286
+ * 基于 Redis 原子操作
287
+ * 支持多 key(组合锁)
288
+ * 防止并发冲突
289
+
290
+ ---
291
+
292
+ ### 🚦 限流模型
293
+
294
+ * 每个 token:
295
+
296
+ * 独立 TTL
297
+ * 独立间隔(interval)
298
+ * Lua 保证原子性
299
+ * 支持多进程 / 多机器共享
300
+
301
+ ---
302
+
303
+ ## ⚠️ 注意事项
304
+
305
+ ### Windows 建议
306
+
307
+ ```python
308
+ import asyncio
309
+
310
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
311
+ ```
312
+
313
+ ---
314
+
315
+ ## 📌 适用场景
316
+
317
+ * 单机非集群
318
+ * 爬虫账号池
319
+ * 接口限流
320
+ * 分布式任务调度
321
+ * 多服务并发控制
322
+
323
+ ---
324
+
325
+ ## 🤝 贡献
326
+
327
+ 欢迎 Issue / PR!
328
+
329
+ ---
330
+
331
+ ## 📄 License
332
+
333
+ MIT License
@@ -0,0 +1,305 @@
1
+ # RedisXsync
2
+
3
+ ![PyPI](https://img.shields.io/pypi/v/redis-xsync) ![Python](https://img.shields.io/pypi/pyversions/redis-xsync) ![License](https://img.shields.io/badge/license-MIT-green)
4
+
5
+ RedisXsync 是一个 **同步 / 异步统一 Redis 客户端**,专为 **分布式锁** 和 **爬虫账号池限流** 场景设计,支持多实例、多
6
+ DB,线程安全和协程安全。
7
+
8
+ ---
9
+
10
+ ## ✨ 核心特性
11
+
12
+ | 特性 | 描述 |
13
+ |-------------|----------------------------------|
14
+ | 同步 / 异步统一接口 | 同一套 API 支持 `with` 和 `async with` |
15
+ | 多实例 / 多 DB | 支持不同 Redis 实例与数据库同时管理 |
16
+ | 分布式锁 | 单键锁、组合锁,阻塞 / 非阻塞模式 |
17
+ | 账号池限流 | 基于 Lua 原子操作的令牌桶限流,可等待可用 token |
18
+ | 线程 & 协程安全 | 避免多线程 / 协程冲突 |
19
+ | 自动连接管理 | Context manager 自动释放连接 |
20
+
21
+ ---
22
+
23
+ ## 🏗 架构概览
24
+
25
+ | RedisXsync |
26
+ |--------------------------|
27
+ | Sync / Async Interfaces |
28
+ | Distributed Lock Manager |
29
+ | Rate Limiter / TokenPool |
30
+
31
+ - 分布式锁:通过单键或多键原子操作保证并发安全
32
+ - 限流/账号池:Lua 脚本保证跨进程/跨机器的原子性,精确到毫秒
33
+
34
+ ---
35
+
36
+ ## 📦 安装
37
+
38
+ ```bash
39
+ pip install redis-xsync
40
+
41
+ ---
42
+
43
+ ## 🚀 快速开始
44
+
45
+ ### 1️⃣ 注册 Redis
46
+
47
+ ​```python
48
+ from redis_xsync import register_redis, resolve_redis, redisXsync
49
+
50
+ redis1 = register_redis(
51
+ label="redis_xsync",
52
+ host="127.0.0.1",
53
+ port=6379,
54
+ db=0,
55
+ password=None,
56
+ decode_responses=True
57
+ )
58
+
59
+ # 通过 label 获取
60
+ redis2 = resolve_redis("redis_xsync")
61
+
62
+
63
+ # 使用方式说明:
64
+ # 1️⃣ 全局默认实例 redisXsync
65
+ # - 在首次调用 register_redis 注册任意 Redis 时,首次注册会自动赋值给 redisXsync,非并发安全
66
+ # - 后续可以直接使用 redisXsync,无需通过 label 获取
67
+ #
68
+ # 2️⃣ 通过 label 显式管理 Redis
69
+ # - register_redis(label=..., ...) 注册 Redis 实例
70
+ # - resolve_redis(label) 根据 label 获取对应 Redis 实例
71
+ #
72
+ # 3️⃣ 独立实例
73
+ # - 可以直接创建 RedisXsync() 实例,不必参与 register_redis 、resolve_redis、 redisXsync 全局管理
74
+ # - 适合临时或隔离使用场景
75
+ ```
76
+
77
+ ## 🔄 同步 / 异步使用
78
+
79
+ ### ✅ 同步
80
+
81
+ ```python
82
+ with redis1(db=1) as r:
83
+ r.setnx("key", "value")
84
+ print(r.get("key"))
85
+ ```
86
+
87
+ ---
88
+
89
+ ### ✅ 异步
90
+
91
+ ```python
92
+ import asyncio
93
+
94
+
95
+ async def main():
96
+ async with redis1(db=1) as r:
97
+ await r.setnx("key", "value")
98
+ print(await r.get("key"))
99
+
100
+
101
+ asyncio.run(main())
102
+ ```
103
+
104
+ ---
105
+
106
+ ## 🔐 分布式锁(支持组合锁)
107
+
108
+ ### 特性
109
+
110
+ * 多 key 原子加锁
111
+ * 所有 key 释放才算解锁
112
+ * 支持阻塞等待
113
+
114
+ ---
115
+
116
+ ### 示例(多线程 + 协程混合)
117
+
118
+ ```python
119
+ import threading
120
+ import asyncio
121
+ from redis_xsync import register_redis
122
+
123
+ cx = 0
124
+ redis = register_redis(label="redis_xsync", host="127.0.0.1", port=6379)
125
+ Lock = redis.AsyncRedisAtomicMultiLock
126
+
127
+
128
+ def sync_worker():
129
+ global cx
130
+ for _ in range(5):
131
+ with Lock("lock_key", db=0, ttl_ms=10, blocking=True):
132
+ with redis(db=2) as r:
133
+ r.setnx("db2", str(cx))
134
+ cx += 1
135
+ print(f"[SYNC] {cx=}")
136
+
137
+
138
+ async def async_worker():
139
+ global cx
140
+ for _ in range(5):
141
+ with Lock("lock_key", db=0, ttl_ms=10, blocking=True):
142
+ async with redis(db=3) as r:
143
+ await r.setnx("db3", str(cx))
144
+ cx += 1
145
+ print(f"[ASYNC] {cx=}")
146
+ await asyncio.sleep(0.2)
147
+
148
+
149
+ # 启动线程
150
+ threading.Thread(target=sync_worker).start()
151
+
152
+ # 启动协程
153
+ asyncio.run(async_worker())
154
+ ```
155
+
156
+ ---
157
+
158
+ ## 🚦 爬虫账号池限流
159
+
160
+ 基于 Redis + Lua,实现**分布式限流 + 自动等待可用账号**
161
+
162
+ 📦 Limited — Redis 容器操作方法对照表
163
+
164
+ | 方法 | 异步 | 阻塞 | 遵循限流 | 数量 | 描述 |
165
+ |-----------------------------------------------------|----|----|------|----|------------------------|
166
+ | `set_available_containers(*containers)` | ✅ | ❌ | ✅ | N | 存储/更新容器配置(生产者) |
167
+ | `ask_available_containers(quantity)` | ✅ | ❌ | ✅ | N | 获取 N 个可用容器,若无返回 `None` |
168
+ | `ask_available_container()` | ✅ | ❌ | ✅ | 1 | 获取单个可用容器,若无返回 `None` |
169
+ | `wait_ask_available_containers(quantity, timeout)` | ✅ | ✅ | ✅ | N | 阻塞等待 N 个可用容器 |
170
+ | `wait_ask_available_container(timeout)` | ✅ | ✅ | ✅ | 1 | 阻塞等待单个可用容器 |
171
+ | `acquire_random_containers(quantity)` | ✅ | ❌ | ❌ | N | 随机获取 N 个容器,忽略限流 |
172
+ | `acquire_random_container()` | ✅ | ❌ | ❌ | 1 | 随机获取单个容器,忽略限流 |
173
+ | `wait_acquire_random_containers(quantity, timeout)` | ✅ | ✅ | ❌ | N | 阻塞等待 N 个随机容器,忽略限流 |
174
+ | `wait_acquire_random_container(timeout)` | ✅ | ✅ | ❌ | 1 | 阻塞等待单个随机容器,忽略限流 |
175
+
176
+ ---
177
+
178
+ ### 写入账号(生产者)
179
+
180
+ ## LimitedModel 说明
181
+
182
+ `LimitedModel` 用于表示受限访问(rate-limited)的容器条目,每条数据包含唯一标识、时间戳、TTL、访问间隔和访问计数等信息。
183
+
184
+ ### 字段说明
185
+
186
+ | 字段 | 类型 | 默认值 | 描述 |
187
+ |-----------------------|-------|-----------|---------------------|
188
+ | `id` | `str` | — | 数据唯一标识符,必须提供 |
189
+ | `ct` | `int` | 当前时间戳(毫秒) | 记录条目的收集时间,无需设置 |
190
+ | `ttl_ms` | `int` | `0` | 条目的生存时间(毫秒),0 表示无限期 |
191
+ | `interval_ms` | `int` | `0` | 访问间隔(毫秒),0 表示不限速 |
192
+ | `next_time_available` | `int` | 当前时间戳(毫秒) | 下次可访问时间,用于限流控制,无需设置 |
193
+ | `containers` | `str` | `None` | 存储容器数据,可为空 |
194
+ | `usage_count` | `int` | `0` | 条目被访问的次数,无需设置 |
195
+ ### 使用说明
196
+
197
+ - `ct` 和 `next_time_available` 都以毫秒为单位,便于高精度限流。
198
+ - `interval_ms > 0` 时,访问条目会更新 `next_time_available` 为当前时间 + 间隔。
199
+ - 每次访问条目时,都会通过 `usage_count` 记录被访问次数,以统计和调度。
200
+ - `ttl_ms` 可配合 Redis 等存储设置过期时间,实现自动清理。
201
+
202
+ ```python
203
+ import random
204
+ from redis_xsync import register_redis
205
+ from redis_xsync.rtypes import LimitedModel
206
+
207
+ redis = register_redis(label="redis_xsync", host="127.0.0.1", port=6379)
208
+ Limited = redis.Limited
209
+
210
+
211
+ async def produce_container():
212
+ async with Limited(redis_key="crawler:identity:flow_limit") as lt:
213
+ for i in range(10):
214
+ token = LimitedModel(
215
+ id=f"user_{i}",
216
+ ttl_ms=random.randint(30000, 60000),
217
+ interval_ms=random.randint(1000, 6000),
218
+ containers="cookies"
219
+ )
220
+ await lt.set_available_containers(token)
221
+ ```
222
+
223
+ ---
224
+
225
+ ### 获取账号(消费者,阻塞等待)
226
+
227
+ ```python
228
+ async def consume_token():
229
+ async with Limited(redis_key="crawler:identity:flow_limit") as lt:
230
+ # 等待可用 token,超时 10 秒
231
+ token = await lt.wait_ask_available_containers(quantity=1, timeout=10)
232
+ print("获取到账号:", token)
233
+ ```
234
+
235
+ ---
236
+
237
+ ### 同步调用
238
+
239
+ ```python
240
+ def consume_sync():
241
+ with Limited(redis_key="crawler:identity:flow_limit") as lt:
242
+ token = lt.wait_ask_available_containers(quantity=1, timeout=10)
243
+ print("获取到账号:", token)
244
+ ```
245
+
246
+ ## ⚡ 说明:
247
+
248
+ - produce_container 写入 token 到 Redis,带过期时间和间隔限流
249
+ - consume_token 或 consume_sync 从 Redis 中获取可用 token,如果当前没有可用,会等待直到 timeout
250
+ - 支持异步和同步,且保证跨进程 / 跨机器原子性
251
+
252
+ ---
253
+
254
+ ## 🧠 设计说明
255
+
256
+ ### 🔐 分布式锁
257
+
258
+ * 基于 Redis 原子操作
259
+ * 支持多 key(组合锁)
260
+ * 防止并发冲突
261
+
262
+ ---
263
+
264
+ ### 🚦 限流模型
265
+
266
+ * 每个 token:
267
+
268
+ * 独立 TTL
269
+ * 独立间隔(interval)
270
+ * Lua 保证原子性
271
+ * 支持多进程 / 多机器共享
272
+
273
+ ---
274
+
275
+ ## ⚠️ 注意事项
276
+
277
+ ### Windows 建议
278
+
279
+ ```python
280
+ import asyncio
281
+
282
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
283
+ ```
284
+
285
+ ---
286
+
287
+ ## 📌 适用场景
288
+
289
+ * 单机非集群
290
+ * 爬虫账号池
291
+ * 接口限流
292
+ * 分布式任务调度
293
+ * 多服务并发控制
294
+
295
+ ---
296
+
297
+ ## 🤝 贡献
298
+
299
+ 欢迎 Issue / PR!
300
+
301
+ ---
302
+
303
+ ## 📄 License
304
+
305
+ MIT License
@@ -0,0 +1,58 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "redis-xsync"
7
+ version = "1.0.1"
8
+ description = "Sync/Async unified Redis client with distributed lock and rate limiter"
9
+ readme = { file = "README.md", content-type = "text/markdown" }
10
+ requires-python = ">=3.8"
11
+
12
+ authors = [
13
+ { name = "Jay" }
14
+ ]
15
+
16
+ license = { text = "MIT" }
17
+
18
+ keywords = [
19
+ "redis",
20
+ "async",
21
+ "sync",
22
+ "distributed-lock",
23
+ "redis-xsync",
24
+ "rate-limit",
25
+ ]
26
+
27
+ dependencies = [
28
+ "pydantic>=2.0",
29
+ "redis>=5.0.0"
30
+ ]
31
+
32
+ classifiers = [
33
+ "Development Status :: 3 - Alpha",
34
+ "Intended Audience :: Developers",
35
+ "Topic :: Software Development :: Libraries",
36
+ "Topic :: System :: Distributed Computing",
37
+ "Programming Language :: Python :: 3",
38
+ "Programming Language :: Python :: 3.8",
39
+ "Programming Language :: Python :: 3.9",
40
+ "Programming Language :: Python :: 3.10",
41
+ "Programming Language :: Python :: 3.11",
42
+ "Programming Language :: Python :: 3.12",
43
+ "Programming Language :: Python :: 3.13",
44
+ "License :: OSI Approved :: MIT License",
45
+ "Operating System :: OS Independent"
46
+ ]
47
+
48
+ [project.urls]
49
+ Homepage = "https://github.com/jaygarage/RedisXsync"
50
+ Repository = "https://github.com/jaygarage/RedisXsync"
51
+ Issues = "https://github.com/jaygarage/RedisXsync/issues"
52
+
53
+ [tool.setuptools.packages.find]
54
+ where = ["."]
55
+ include = ["redis_xsync*"]
56
+
57
+ [tool.setuptools]
58
+ include-package-data = true