Skip to content

Commit 1f224dc

Browse files
committed
Merge branch 'python-fix-importlib-recursion-bug' into add-aws-lambda-support-beta
2 parents 3456fac + af204b5 commit 1f224dc

File tree

73 files changed

+3556
-764
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+3556
-764
lines changed

.github/workflows/publish.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ jobs:
2727
echo "Pylint check failed. Please fix the issues."
2828
exit 1
2929
fi
30-
30+
- name: Build and start aikido mock server
31+
run: |
32+
cd end2end/server && docker build -t mock_core .
33+
docker run --name mock_core -d -p 5050:5000 mock_core
3134
- name: Run Black Check
3235
run: |
3336
poetry run black --check --diff aikido_zen/

.github/workflows/test-publish.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ jobs:
2727
echo "Pylint check failed. Please fix the issues."
2828
exit 1
2929
fi
30-
30+
- name: Build and start aikido mock server
31+
run: |
32+
cd end2end/server && docker build -t mock_core .
33+
docker run --name mock_core -d -p 5050:5000 mock_core
3134
- name: Run Black Check
3235
run: |
3336
poetry run black --check --diff aikido_zen/

.github/workflows/unit-test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ jobs:
2222
- name: Add local.aikido.io to /etc/hosts
2323
run: |
2424
sudo echo "127.0.0.1 local.aikido.io" | sudo tee -a /etc/hosts
25+
- name: Build and start aikido mock server
26+
run: |
27+
cd end2end/server && docker build -t mock_core .
28+
docker run --name mock_core -d -p 5050:5000 mock_core
2529
- name: Set up Python ${{ matrix.python-version }}
2630
uses: actions/setup-python@v5
2731
with:

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ benchmark:
4242

4343

4444
# Binaries cache :
45-
BASE_URL = https://github.com/AikidoSec/zen-internals/releases/download/v0.1.45
45+
BASE_URL = https://github.com/AikidoSec/zen-internals/releases/download/v0.1.50
4646
FILES = \
4747
libzen_internals_aarch64-apple-darwin.dylib \
4848
libzen_internals_aarch64-apple-darwin.dylib.sha256sum \

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Zen instruments the following AI SDKs to track which models are used and how man
6060
*[`anthropic`](https://pypi.org/project/anthropic/)
6161
*[`mistralai`](https://pypi.org/project/mistralai) ^1.0.0
6262
*[`boto3`](https://pypi.org/project/boto3) (AWS Bedrock)
63+
*[`groq`](https://pypi.org/project/groq)
6364

6465
Zen is compatible with Python 3.8-3.13 and can run on Windows, Linux, and Mac OS X.
6566

aikido_zen/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
# Re-export functions :
1010
from aikido_zen.lambda_helper import protect_lambda
1111
from aikido_zen.context.users import set_user
12+
from aikido_zen.helpers.check_gevent import check_gevent
1213
from aikido_zen.middleware import should_block_request
14+
from aikido_zen.middleware.set_rate_limit_group import set_rate_limit_group
1315

1416
# Import logger
1517
from aikido_zen.helpers.logging import logger
@@ -35,6 +37,8 @@ def protect(mode="daemon", token=""):
3537
return
3638
if not test_uds_file_access():
3739
return # Unable to start background process
40+
if check_gevent():
41+
return # gevent is not compatible with zen.
3842

3943
if token:
4044
os.environ["AIKIDO_TOKEN"] = token

aikido_zen/background_process/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ def start_background_process():
4949

5050
# Daemon is set to True so that the process kills itself when the main process dies
5151
background_process = Process(
52-
target=AikidoBackgroundProcess, args=(comms.address, comms.key), daemon=True
52+
target=AikidoBackgroundProcess,
53+
args=(comms.address, comms.key),
54+
name="zen-agent-process",
55+
daemon=True,
5356
)
5457
background_process.start()
5558

aikido_zen/background_process/aikido_background_process.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
import multiprocessing.connection as con
6+
import signal
67
import time
78
import sched
89
import traceback
@@ -40,12 +41,14 @@ def __init__(self, address, key):
4041
self.queue = Queue()
4142
self.connection_manager = None
4243
# Start reporting thread :
43-
Thread(target=self.reporting_thread).start()
44+
Thread(target=self.reporting_thread, daemon=True).start()
4445

4546
logger.debug(
4647
"Background process started successfully, with UDS File : %s", address
4748
)
4849

50+
add_exit_handlers()
51+
4952
while True:
5053
conn = listener.accept()
5154
while True:
@@ -106,3 +109,17 @@ def send_to_connection_manager(self, event_scheduler):
106109
blocked=queue_attack_item[2],
107110
stack=queue_attack_item[3],
108111
)
112+
113+
114+
def add_exit_handlers():
115+
"""
116+
We add graceful exit handlers here since the process keeps hanging otherwise.
117+
"""
118+
119+
def exit_gracefully(sig, frame):
120+
sys.exit(0)
121+
122+
signal.signal(signal.SIGINT, exit_gracefully)
123+
signal.signal(signal.SIGTERM, exit_gracefully)
124+
signal.signal(signal.SIGQUIT, exit_gracefully)
125+
signal.signal(signal.SIGHUP, exit_gracefully)

aikido_zen/background_process/api/__init__.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
init.py file for api/ folder. Includes abstract class ReportingApi
33
"""
44

5-
import json
5+
from aikido_zen.background_process.requests.make_request import Response
66
from aikido_zen.helpers.logging import logger
77

88

99
class ReportingApi:
1010
"""This is the super class for the reporting API's"""
1111

12-
def to_api_response(self, res):
12+
@staticmethod
13+
def to_api_response(res: Response):
1314
"""Converts results into an Api response obj"""
1415
status = res.status_code
1516
if status == 429:
@@ -18,10 +19,11 @@ def to_api_response(self, res):
1819
return {"success": False, "error": "invalid_token"}
1920
elif status == 200:
2021
try:
21-
return json.loads(res.text)
22+
return res.json()
2223
except Exception as e:
23-
logger.debug(e)
24-
logger.debug(res.text)
24+
logger.debug(
25+
"Trying to load json, failed: %s (body=%s)", str(e), res.text
26+
)
2527
return {"success": False, "error": "unknown_error"}
2628

2729
def report(self, token, event, timeout_in_sec):

aikido_zen/background_process/api/http_api.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
Exports the HTTP API class
33
"""
44

5-
import requests
5+
import aikido_zen.background_process.requests as requests
66
from aikido_zen.background_process.api import ReportingApi
7+
from aikido_zen.background_process.requests.errors import TimeoutExceeded
78
from aikido_zen.helpers.logging import logger
89

910

@@ -21,11 +22,10 @@ def report(self, token, event, timeout_in_sec):
2122
timeout=timeout_in_sec,
2223
headers=get_headers(token),
2324
)
24-
except requests.exceptions.ConnectionError as e:
25-
logger.error(e)
25+
except TimeoutExceeded as e:
2626
return {"success": False, "error": "timeout"}
2727
except Exception as e:
28-
logger.error(e)
28+
logger.error("Failed to report event : %s(%s)", str(e.__class__), str(e))
2929
return {"success": False, "error": "unknown"}
3030
return self.to_api_response(res)
3131

@@ -47,11 +47,10 @@ def fetch_firewall_lists(self, token):
4747
"Authorization": str(token),
4848
},
4949
)
50-
except requests.exceptions.ConnectionError as e:
51-
logger.error(e)
50+
except TimeoutExceeded as e:
5251
return {"success": False, "error": "timeout"}
5352
except Exception as e:
54-
logger.error(e)
53+
logger.error("Failed to fetch firewall lists: %s", str(e))
5554
return {"success": False, "error": "unknown"}
5655
return self.to_api_response(res)
5756

0 commit comments

Comments
 (0)