Skip to content

Commit

Permalink
Merge pull request #7 from PoofyEnigma/dev
Browse files Browse the repository at this point in the history
release 0.1.1
  • Loading branch information
PoofyEnigma committed Jan 23, 2024
2 parents 3040683 + de902e2 commit 485772f
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 201 deletions.
214 changes: 107 additions & 107 deletions DECISION_LOG.md
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.
34 changes: 17 additions & 17 deletions demos/trap_bot/Dockerfile
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"]

6 changes: 3 additions & 3 deletions demos/trap_bot/README.md
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>`
90 changes: 45 additions & 45 deletions demos/trap_bot/app.py
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())
4 changes: 1 addition & 3 deletions demos/trap_bot/requirements.txt
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
Loading

0 comments on commit 485772f

Please sign in to comment.