Skip to content

Commit 6ba20f5

Browse files
committed
feat: add api-polling and openai-client-polling
0 parents  commit 6ba20f5

3 files changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from .api_polling import APIPolling
2+
from .client_polling import ClientPolling
3+
4+
__all__ = [
5+
"APIPolling",
6+
"ClientPolling"
7+
]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (C) 2025 - Present Sepine Tam, Inc. All Rights Reserved
5+
#
6+
# @Author : Sepine Tam (谭淞)
7+
# @Email : sepinetam@gmail.com
8+
# @File : api_polling.py
9+
10+
from typing import List
11+
12+
13+
class APIPolling:
14+
def __init__(self,
15+
api_keys: List[str]):
16+
self.api_polling = api_keys
17+
self._index = 0
18+
19+
def __str__(self):
20+
r = f"API Polling, this polling has {self.polling_length} APIs:\n"
21+
for index in range(self.polling_length):
22+
r += f"index: {index:>3} | API: {self.mask_api_key(self.api_polling[index])}\n"
23+
return r
24+
25+
def __len__(self):
26+
return self.polling_length
27+
28+
@property
29+
def api_key(self):
30+
return self._get_next_api()
31+
32+
@property
33+
def polling_length(self):
34+
return len(self.api_polling)
35+
36+
def _index_plus(self):
37+
self._index += 1
38+
if self._index >= self.polling_length:
39+
self.reset_index(0)
40+
return self._index
41+
42+
def _get_next_api(self):
43+
next_api = self.api_polling[self._index]
44+
self._index_plus()
45+
return next_api
46+
47+
def reset_index(self, index: int = 0):
48+
if index > self.polling_length:
49+
index = 0
50+
self._index = index
51+
52+
@staticmethod
53+
def mask_api_key(api_key: str,
54+
visible: int = 3,
55+
mask_char: str = "*",
56+
mask_len: int = 3):
57+
if not api_key:
58+
return ""
59+
prefix = api_key[:visible]
60+
suffix = api_key[-visible:]
61+
return prefix + (mask_char * mask_len) + suffix
62+
63+
64+
if __name__ == "__main__":
65+
api_list = [
66+
"sk-thisiskey1", "sk-thisiskey2", "sk-thisiskey3",
67+
]
68+
api_polling = APIPolling(api_list)
69+
70+
print(api_polling)
71+
72+
# To show 10 times api
73+
for _ in range(10):
74+
print(api_polling.api_key)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (C) 2025 - Present Sepine Tam, Inc. All Rights Reserved
5+
#
6+
# @Author : Sepine Tam (谭淞)
7+
# @Email : sepinetam@gmail.com
8+
# @File : client_polling.py
9+
10+
from typing import List
11+
12+
from openai import AsyncOpenAI, OpenAI
13+
14+
from .api_polling import APIPolling
15+
16+
17+
class ClientPolling:
18+
def __init__(self,
19+
api_keys: List[str],
20+
*args, **kwargs):
21+
self.api_key_polling = APIPolling(api_keys)
22+
self.openai_kwargs = kwargs.copy()
23+
24+
def __len__(self):
25+
return self.api_key_polling.polling_length
26+
27+
@property
28+
def client(self) -> OpenAI:
29+
client = OpenAI(
30+
api_key=self.api_key_polling.api_key,
31+
**self.openai_kwargs
32+
)
33+
return client
34+
35+
@property
36+
def async_client(self) -> OpenAI:
37+
client = AsyncOpenAI(
38+
api_key=self.api_key_polling.api_key,
39+
**self.openai_kwargs
40+
)
41+
return client
42+

0 commit comments

Comments
 (0)