-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from PoofyEnigma/dev
release 0.1.1
- Loading branch information
Showing
6 changed files
with
199 additions
and
201 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,107 +1,107 @@ | ||
# Templatize Result object to avoid returning a tuple | ||
Opted for returning a tuple where applicable vs. wrapping inside a generic object. | ||
|
||
Embracing Tuples seems more of a python style while Generics are a C++/Java/C# style of coding. | ||
There is less referencing calling when using tuples. | ||
|
||
|
||
**Tuple** | ||
```python | ||
|
||
class Thing: | ||
def __int__(self): | ||
self.a = 0 | ||
self.b = 0 | ||
self.c = 0 | ||
|
||
class Api: | ||
def __init__(self): | ||
pass | ||
|
||
def call1(self) -> tuple[response, Thing]: | ||
r = s.get('http://...') | ||
return r, Thing() | ||
|
||
def call2(self, data)-> response: | ||
return s.post('', data) | ||
|
||
api = Api() | ||
response, data = api.call1() | ||
print(data.id) | ||
print(data.maxLimitDate) | ||
response = api.call2() | ||
``` | ||
|
||
**Tuple** | ||
```python | ||
from typing import TypeVar, Generic, List | ||
|
||
T = TypeVar('T') | ||
|
||
class ApiResponse(Generic[T]): | ||
def __init__(self): | ||
self.data: T = None | ||
self.response = None | ||
|
||
class Thing: | ||
def __int__(self): | ||
self.a = 0 | ||
self.b = 0 | ||
self.c = 0 | ||
|
||
class Api: | ||
def __init__(self): | ||
pass | ||
|
||
def call1(self) -> ApiResponse[Thing]: | ||
r = ApiResponse() | ||
r.data = 2 | ||
r.response = s.get('http://...') | ||
return r | ||
|
||
def call2(self, data)-> ApiResponse: | ||
return s.post('', data) | ||
|
||
api = Api() | ||
response = api.call1() | ||
print(response.data.a) | ||
print(response.data.b) | ||
print(response.data.c) | ||
response = api.call2({}) | ||
``` | ||
|
||
|
||
# async | ||
Should the api calls in ChasterAPI be async? | ||
|
||
As of right now, I'm opting for no. Async can be useful but it requires explicitly embracing async in the code which also | ||
requires addition syntax to get something operational. It is assumed the average use case for this SDK will not be for | ||
high performance operations that need to have off over millisecond. Likely such as service will be rate limited by Chaster | ||
very quickly. Admittedly more research into Chaster's rate limiting needs to occur. The addition syntax needs for async | ||
will create developed more difficult for writing chaster bots. | ||
|
||
# Circuit Breaker | ||
https://github.com/danielfm/pybreaker. Opted against. | ||
https://stackoverflow.com/questions/15431044/can-i-set-max-retries-for-requests-request requests library already does this? | ||
|
||
# Cancellation Tokens | ||
https://github.com/pomponchik/cantok. Opted against. Would be needed if async and circuit breakers were adapted. | ||
|
||
# connection pool, thread safety of SDK | ||
I am not sure if these will be necessary. I would not recommend parallel execute to Chaster's servers until more information | ||
is acquired. | ||
|
||
# measuring I/O | ||
Going back on to the usecase for the sdk as mainly a toolset for writting chaster bots, providing metric tooling will | ||
likely not be necessary. Should a user want to do so, we could allow for custom request hooks functions to be brought into | ||
the ChasterAPI constructor that would allow the user to see to that use case. | ||
|
||
# utilizing W3C Level 2 Tracing Protocol | ||
It is not embraced by Chaster so would only be used locally and would be handy if the chaster bot happened to use another | ||
service that did embrace the protocol. The official python implementation for it seems unnecessarily bulky at the time | ||
of researching and would add many additional code block indents. Decided not to utilize it for now. | ||
|
||
# Pydantic | ||
https://github.com/pydantic/pydantic could be very useful and would maybe remove the internal dump/update calls used by | ||
the API if it works. Chaster APIs responses have some inconsistent quirks that may make that library not as usefull compare | ||
to the dump/update pattern. | ||
# Templatize Result object to avoid returning a tuple | ||
Opted for returning a tuple where applicable vs. wrapping inside a generic object. | ||
|
||
Embracing Tuples seems more of a python style while Generics are a C++/Java/C# style of coding. | ||
There is less referencing calling when using tuples. | ||
|
||
|
||
**Tuple** | ||
```python | ||
|
||
class Thing: | ||
def __int__(self): | ||
self.a = 0 | ||
self.b = 0 | ||
self.c = 0 | ||
|
||
class Api: | ||
def __init__(self): | ||
pass | ||
|
||
def call1(self) -> tuple[response, Thing]: | ||
r = s.get('http://...') | ||
return r, Thing() | ||
|
||
def call2(self, data)-> response: | ||
return s.post('', data) | ||
|
||
api = Api() | ||
response, data = api.call1() | ||
print(data.id) | ||
print(data.maxLimitDate) | ||
response = api.call2() | ||
``` | ||
|
||
**Tuple** | ||
```python | ||
from typing import TypeVar, Generic, List | ||
|
||
T = TypeVar('T') | ||
|
||
class ApiResponse(Generic[T]): | ||
def __init__(self): | ||
self.data: T = None | ||
self.response = None | ||
|
||
class Thing: | ||
def __int__(self): | ||
self.a = 0 | ||
self.b = 0 | ||
self.c = 0 | ||
|
||
class Api: | ||
def __init__(self): | ||
pass | ||
|
||
def call1(self) -> ApiResponse[Thing]: | ||
r = ApiResponse() | ||
r.data = 2 | ||
r.response = s.get('http://...') | ||
return r | ||
|
||
def call2(self, data)-> ApiResponse: | ||
return s.post('', data) | ||
|
||
api = Api() | ||
response = api.call1() | ||
print(response.data.a) | ||
print(response.data.b) | ||
print(response.data.c) | ||
response = api.call2({}) | ||
``` | ||
|
||
|
||
# async | ||
Should the api calls in ChasterAPI be async? | ||
|
||
As of right now, I'm opting for no. Async can be useful but it requires explicitly embracing async in the code which also | ||
requires addition syntax to get something operational. It is assumed the average use case for this SDK will not be for | ||
high performance operations that need to have off over millisecond. Likely such as service will be rate limited by Chaster | ||
very quickly. Admittedly more research into Chaster's rate limiting needs to occur. The addition syntax needs for async | ||
will create developed more difficult for writing chaster bots. | ||
|
||
# Circuit Breaker | ||
https://github.com/danielfm/pybreaker. Opted against. | ||
https://stackoverflow.com/questions/15431044/can-i-set-max-retries-for-requests-request requests library already does this? | ||
|
||
# Cancellation Tokens | ||
https://github.com/pomponchik/cantok. Opted against. Would be needed if async and circuit breakers were adapted. | ||
|
||
# connection pool, thread safety of SDK | ||
I am not sure if these will be necessary. I would not recommend parallel execute to Chaster's servers until more information | ||
is acquired. | ||
|
||
# measuring I/O | ||
Going back on to the usecase for the sdk as mainly a toolset for writting chaster bots, providing metric tooling will | ||
likely not be necessary. Should a user want to do so, we could allow for custom request hooks functions to be brought into | ||
the ChasterAPI constructor that would allow the user to see to that use case. | ||
|
||
# utilizing W3C Level 2 Tracing Protocol | ||
It is not embraced by Chaster so would only be used locally and would be handy if the chaster bot happened to use another | ||
service that did embrace the protocol. The official python implementation for it seems unnecessarily bulky at the time | ||
of researching and would add many additional code block indents. Decided not to utilize it for now. | ||
|
||
# Pydantic | ||
https://github.com/pydantic/pydantic could be very useful and would maybe remove the internal dump/update calls used by | ||
the API if it works. Chaster APIs responses have some inconsistent quirks that may make that library not as usefull compare | ||
to the dump/update pattern. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,17 @@ | ||
|
||
|
||
# syntax=docker/dockerfile:1.4 | ||
FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder | ||
|
||
WORKDIR /trap_bot | ||
|
||
COPY requirements.txt /trap_bot | ||
RUN --mount=type=cache,target=/root/.cache/pip \ | ||
pip3 install -r requirements.txt | ||
|
||
COPY . /trap_bot | ||
|
||
|
||
ENTRYPOINT ["python3"] | ||
CMD ["app.py"] | ||
|
||
|
||
|
||
# syntax=docker/dockerfile:1.4 | ||
FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder | ||
|
||
WORKDIR /trap_bot | ||
|
||
COPY requirements.txt /trap_bot | ||
RUN --mount=type=cache,target=/root/.cache/pip \ | ||
pip3 install -r requirements.txt | ||
|
||
COPY . /trap_bot | ||
|
||
|
||
ENTRYPOINT ["python3"] | ||
CMD ["app.py"] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
`docker build .` | ||
|
||
`sudo docker run -e CHASTER_BEARER_TOKEN=$Env:CHASTER_BEARER_TOKEN -d c0ab713fb3ec ` | ||
`docker build .` | ||
|
||
`docker run -e CHASTER_BEARER_TOKEN=$Env:CHASTER_BEARER_TOKEN -d <img>` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,45 @@ | ||
from chaster import api, extensions | ||
import datetime | ||
import logging | ||
import os | ||
import time | ||
|
||
logging.basicConfig(filename='./log.txt') | ||
logger = logging.getLogger() | ||
logger.setLevel(logging.INFO) | ||
|
||
while True: | ||
try: | ||
logger.warning('starting') | ||
chaster_api = api.ChasterAPI(os.environ.get('CHASTER_BEARER_TOKEN'), user_agent='puphimbo/1.0') | ||
lock_name = 'Bot Trap' | ||
|
||
resp, shared_locks = chaster_api.get_user_shared_locks() | ||
trap_shared_lock = None | ||
for shared_lock in shared_locks: | ||
if shared_lock.name == lock_name: | ||
trap_shared_lock = shared_lock | ||
break | ||
else: | ||
logger.warning('could not find the shared lock') | ||
continue | ||
|
||
# could also use the search function, but post_keyholder_locks_search needs revamped | ||
resp, locked_users_page = chaster_api.post_keyholder_locks_search() | ||
locked_users = locked_users_page.locks | ||
for page in range(2, locked_users_page.pages): | ||
resp, locked_users_page = chaster_api.post_keyholder_locks_search(page=page) | ||
locked_users.extend(locked_users_page.locks) | ||
|
||
for lock in locked_users: | ||
if lock.sharedLock.name == 'Bot Trap': | ||
if lock.displayRemainingTime: | ||
chaster_api.update_lock_settings(lock._id, False, True) | ||
eh = extensions.ExtensionsHandler() | ||
eh.load_defined(lock.extensions) | ||
chaster_api.place_user_into_pillory(lock._id, eh.pillories[0]._id, 'caught!', | ||
datetime.timedelta(hours=2).total_seconds()) | ||
except Exception as e: | ||
logger.error(f'error - {type(e).__name__} {e}') | ||
finally: | ||
time.sleep(datetime.timedelta(minutes=60).total_seconds()) | ||
from chaster import api, extensions | ||
import datetime | ||
import logging | ||
import os | ||
import time | ||
|
||
logging.basicConfig(filename='./log.txt') | ||
logger = logging.getLogger() | ||
logger.setLevel(logging.INFO) | ||
|
||
while True: | ||
try: | ||
logger.warning('starting') | ||
chaster_api = api.ChasterAPI(os.environ.get('CHASTER_BEARER_TOKEN'), user_agent='puphimbo/1.0') | ||
lock_name = 'Bot Trap' | ||
|
||
resp, shared_locks = chaster_api.get_user_shared_locks() | ||
trap_shared_lock = None | ||
for shared_lock in shared_locks: | ||
if shared_lock.name == lock_name: | ||
trap_shared_lock = shared_lock | ||
break | ||
else: | ||
logger.warning('could not find the shared lock') | ||
continue | ||
|
||
# could also use the search function, but post_keyholder_locks_search needs revamped | ||
resp, locked_users_page = chaster_api.find_locked_users() | ||
locked_users = locked_users_page.locks | ||
for page in range(2, locked_users_page.pages): | ||
resp, locked_users_page = chaster_api.find_locked_users(page=page) | ||
locked_users.extend(locked_users_page.locks) | ||
|
||
for lock in locked_users: | ||
if lock.sharedLock.name == 'Bot Trap': | ||
if lock.displayRemainingTime: | ||
chaster_api.update_lock_settings(lock._id, False, True) | ||
eh = extensions.ExtensionsHandler() | ||
eh.load_defined(lock.extensions) | ||
chaster_api.place_user_into_pillory(lock._id, eh.pillories[0]._id, 'caught!', | ||
datetime.timedelta(hours=2).total_seconds()) | ||
except Exception as e: | ||
logger.error(f'error - {type(e).__name__} {e}') | ||
finally: | ||
time.sleep(datetime.timedelta(minutes=60).total_seconds()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
chaster-sdk | ||
requests~=2.31.0 | ||
python-dateutil | ||
chaster-sdk==0.1.1 |
Oops, something went wrong.