Skip to content

Commit 97515f0

Browse files
committed
beta update
1 parent f344e0f commit 97515f0

File tree

10 files changed

+104
-22
lines changed

10 files changed

+104
-22
lines changed

src/components/actions/base/action.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class Action:
4747
def __init__(self):
4848
self.name = self.get_name()
4949
self.logs = []
50+
self._raw_data = None
5051

5152
def get_name(self):
5253
return type(self).__name__
@@ -68,6 +69,16 @@ def register(self):
6869
self.objects._actions.append(self)
6970
logger.info(f'ACTION REGISTERED --->\t{str(self)}')
7071

72+
def set_data(self, data):
73+
"""Sets data for action"""
74+
self._raw_data = data
75+
76+
def validate_data(self):
77+
"""Ensures data is valid"""
78+
if not self._raw_data:
79+
raise ValueError('No data provided to action')
80+
return self._raw_data
81+
7182
def run(self, *args, **kwargs):
7283
"""
7384
Runs, logs action

src/components/actions/base/template/action_template.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ def __init__(self):
66
super().__init__()
77

88
def run(self, *args, **kwargs):
9-
super().run(*args, **kwargs)
9+
super().run(*args, **kwargs) # this is required
1010
"""
1111
Custom run method. Add your custom logic here.
1212
"""
1313
print(self.name, '---> action has run!')
14-
15-
16-
template_action = TemplateActionClass()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import datetime
2+
import random
3+
4+
from components.actions.base.action import Action
5+
from components.logs.log_event import LogEvent
6+
7+
8+
class LogAccountBalance(Action):
9+
def __init__(self):
10+
super().__init__()
11+
12+
def run(self, *args, **kwargs):
13+
super().run(*args, **kwargs) # this is required
14+
"""
15+
Custom run method. Add your custom logic here.
16+
"""
17+
data = self.validate_data()
18+
print('Data from webhook:', data)
19+
message = f'Account Balance is: ${random.randint(0, 100)} USD'
20+
timestamp = datetime.datetime.now()
21+
log = LogEvent(self.name, 'account_balance', timestamp, message)
22+
log.write() # remember to write the log!
23+
24+
# kraken = ccxt.kraken({
25+
# 'apiKey': 'YOUR_PUBLIC_API_KEY',
26+
# 'secret': 'YOUR_SECRET_PRIVATE_KEY',
27+
# })
28+
29+
# kraken.load_markets()
30+
# print(kraken.fetch_balance())
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from components.actions.base.action import Action
2+
3+
4+
class TradeCrypto(Action):
5+
def __init__(self):
6+
super().__init__()
7+
8+
def run(self, *args, **kwargs):
9+
super().run(*args, **kwargs)
10+
"""
11+
Custom run method. Add your custom logic here.
12+
"""
13+
data = self.validate_data()
14+
print('Data from webhook:', data)
15+
print('Data is of type:', type(data))
16+
print('Looking for order symbol...')
17+
symbol = data.get('symbol', 'Not found :(')
18+
print('Symbol:', symbol)
19+
print('Looking for order type...')
20+
order_type = data.get('order_type', 'Not found :(')
21+
print('Order type is:', order_type)
22+
print('\n\nUse the data above to make your trade!')
23+
print('\nhttps://github.com/ccxt/ccxt#python-1')
24+
print('CCXT is an example of a library you can use to make trades.\n\n')
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
from components.actions.base.action import Action
22

33

4-
class HandleOrderExample(Action):
4+
class PrintData(Action):
55
def __init__(self):
66
super().__init__()
7-
self.name = 'handle_order_example'
87

98
def run(self, *args, **kwargs):
10-
super(Action).run(*args, **kwargs)
9+
super().run(*args, **kwargs) # this is required
1110
"""
1211
Custom run method. Add your custom logic here.
1312
"""
1413
print(self.name, '---> action has run!')
15-
16-
17-
handle_order_example = HandleOrderExample()
14+
data = self.validate_data() # always get data from webhook by calling this method!
15+
print('Data from webhook:', data)

src/components/events/base/event.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ class Event:
4242

4343
def __init__(self):
4444
self.name = self.get_name()
45-
self.webhook = True
46-
# generate consistent hash using hashlib, based off of name
45+
self.webhook = True # all events are webhooks by default
4746
self.key = f'{self.name}:{md5(f"{self.name + UNIQUE_KEY}".encode()).hexdigest()[:6]}'
4847
self._actions = []
4948
self.logs = [LogEvent().from_line(line) for line in open(LOG_LOCATION, 'r') if line.split(',')[0] == self.name]
@@ -81,4 +80,5 @@ def trigger(self, *args, **kwargs):
8180

8281
self.logs.append(log_event)
8382
for action in self._actions:
84-
action.run(data=data)
83+
action.set_data(data)
84+
action.run()

src/components/logs/log_event.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def __init__(self, parent=None, event_type=None, event_time=None, event_data=Non
88
self.parent = parent
99
self.event_type = event_type
1010
self.event_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
11-
self.event_data = event_data
11+
self.event_data = event_data.replace(',', ' ') if event_data else None
1212

1313
def __str__(self):
1414
return "Event Type: " + self.event_type + " Event Time: " + self.event_time + " Event Data: " + self.event_data

src/settings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# actions
2-
REGISTERED_ACTIONS = ['NewAction']
2+
REGISTERED_ACTIONS = ['PrintData']
33

44
# events
5-
REGISTERED_EVENTS = ['NewEvent']
5+
REGISTERED_EVENTS = ['WebhookReceived']
66

77
# links
8-
REGISTERED_LINKS = [('NewAction', 'NewEvent')]
8+
REGISTERED_LINKS = [('PrintData', 'WebhookReceived')]
99

src/tvwb.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ def create_event(name: str):
130130

131131
@app.command('event:register')
132132
def register_event(name: str):
133+
"""
134+
Registers an event to the events registry. (Adds to settings.py)
135+
"""
133136
logger.info(f'Registering event --->\t{name}')
134137
try:
135138
add_event(name)
@@ -146,5 +149,12 @@ def trigger_event(name: str):
146149
return True
147150

148151

152+
@app.command('shell')
153+
def shell():
154+
cmd = '--help'
155+
while cmd not in ['exit', 'quit', 'q']:
156+
run(f'python3 tvwb.py {cmd}'.split(' '))
157+
cmd = typer.prompt("Enter TVWB command (q) to exit")
158+
149159
if __name__ == "__main__":
150160
app()

src/utils/modify_settings.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,17 @@ def validate_settings():
5050
# make sure all registered actions exist
5151
for action in REGISTERED_ACTIONS:
5252
try:
53-
cls = getattr(importlib.import_module(f'components.actions.{snake_case(action)}', action), action)()
53+
getattr(importlib.import_module(f'components.actions.{snake_case(action)}', action), action)()
5454
except ImportError:
5555
logger.critical(f'Action ({action}) not found')
5656
return False
5757

5858
# make sure all registered events exist
5959
for event in REGISTERED_EVENTS:
60-
cls = getattr(importlib.import_module(f'components.events.{snake_case(event)}', event), event)()
61-
if not cls:
62-
logger.critical(f'Event ({event}) does not exist')
60+
try:
61+
getattr(importlib.import_module(f'components.events.{snake_case(event)}', event), event)()
62+
except ImportError:
63+
logger.critical(f'Event ({event}) not found')
6364
return False
6465

6566
return True
@@ -163,7 +164,18 @@ def delete_action(action_name):
163164

164165
def add_event(event_name):
165166
"""Add event to settings.py"""
166-
build_settings(events=[event_name])
167+
168+
events = []
169+
try:
170+
from settings import REGISTERED_EVENTS
171+
events = REGISTERED_EVENTS + [event_name]
172+
except ImportError:
173+
logger.error('Could not import REGISTERED_EVENTS from settings.py')
174+
175+
# use set to remove duplicates
176+
events = list(set(events))
177+
178+
build_settings(events=events)
167179

168180

169181
def link_action_to_event(action_name, event_name):

0 commit comments

Comments
 (0)