Skip to content

Commit aba5d3d

Browse files
committed
🎉 initial commit
0 parents  commit aba5d3d

File tree

14 files changed

+185074
-0
lines changed

14 files changed

+185074
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: pre-commit & security checks
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
precommit:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
17+
18+
- name: Set up Python 3.13
19+
uses: actions/setup-python@v4
20+
with:
21+
python-version: "3.13"
22+
23+
- name: Install pre-commit
24+
run: python -m pip install --upgrade pip && pip install "pre-commit>=2.20.0"
25+
26+
- name: Run pre-commit (all files)
27+
run: pre-commit run --all-files
28+
29+
- name: Install Bandit & Safety
30+
run: |
31+
pip install "bandit==1.8.6" "safety==3.6.2"
32+
33+
- name: Run Bandit (full repo)
34+
run: |
35+
bandit -r . -f json -o bandit-report.json || true
36+
37+
- name: Run Safety (uv.lock)
38+
run: |
39+
if [ -f uv.lock ]; then
40+
# write JSON output; tolerate non-zero exit so job doesn't fail
41+
safety check --file=uv.lock --full-report --json > safety-report.json || true
42+
else
43+
# ensure a file exists so upload-artifact has something to upload
44+
echo '{"notice":"uv.lock not found; skipping safety."}' > safety-report.json
45+
fi
46+
47+
- name: Upload Bandit report
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: bandit-report
51+
path: bandit-report.json
52+
53+
- name: Upload Safety report
54+
uses: actions/upload-artifact@v4
55+
with:
56+
name: safety-report
57+
path: safety-report.json

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Python-generated files
2+
__pycache__/
3+
*.py[oc]
4+
build/
5+
dist/
6+
wheels/
7+
*.egg-info
8+
.ipynb_checkpoints/
9+
10+
# Virtual environments
11+
.venv
12+
13+
# IDE
14+
.idea/
15+
.DS_Store
16+
17+
# Data
18+
data/
19+
20+
# Environment
21+
.env

.pre-commit-config.yaml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/uv-pre-commit # ensure lock file is up to date
3+
rev: 0.8.22
4+
hooks:
5+
- id: uv-lock
6+
7+
- repo: https://github.com/pre-commit/pre-commit-hooks # basic hooks
8+
rev: v6.0.0
9+
hooks:
10+
- id: trailing-whitespace
11+
args: [--markdown-linebreak-ext=md]
12+
- id: end-of-file-fixer
13+
- id: check-yaml
14+
args: [--multi, --unsafe]
15+
- id: check-added-large-files
16+
args: [--maxkb=10000] # 10MB limit for GenAI projects
17+
- id: check-toml
18+
- id: check-json
19+
- id: check-merge-conflict
20+
- id: check-executables-have-shebangs
21+
- id: check-shebang-scripts-are-executable
22+
- id: debug-statements
23+
- id: check-docstring-first
24+
- id: check-case-conflict
25+
- id: check-symlinks
26+
- id: destroyed-symlinks
27+
- id: fix-byte-order-marker
28+
- id: mixed-line-ending
29+
args: [--fix=lf]
30+
31+
- repo: https://github.com/pycqa/isort # Python import sorting
32+
rev: 6.0.1
33+
hooks:
34+
- id: isort
35+
name: isort (python)
36+
args: [--profile, black, --line-length=88]
37+
38+
- repo: https://github.com/charliermarsh/ruff-pre-commit
39+
rev: v0.13.2
40+
hooks:
41+
- id: ruff
42+
name: ruff lint
43+
args: [--fix, --show-files]
44+
stages: [pre-commit]
45+
- id: ruff-format
46+
name: ruff format
47+
stages: [pre-commit]
48+
49+
- repo: https://github.com/RobertCraigie/pyright-python
50+
rev: v1.1.405
51+
hooks:
52+
- id: pyright
53+
stages: [pre-push]
54+
55+
- repo: https://github.com/PyCQA/bandit
56+
rev: 1.8.6
57+
hooks:
58+
- id: bandit
59+
args: [-r, ., -f, json, -o, bandit-report.json]
60+
stages: [pre-push]
61+
require_serial: true
62+
63+
- repo: https://github.com/Yelp/detect-secrets
64+
rev: v1.5.0
65+
hooks:
66+
- id: detect-secrets
67+
name: detect-secrets
68+
entry: detect-secrets-hook
69+
args: [--baseline, .secrets.baseline]
70+
stages: [pre-commit]
71+
pass_filenames: false
72+
73+
# strip notebook outputs to avoid committing large binary outputs
74+
- repo: https://github.com/kynan/nbstripout
75+
rev: 0.8.1
76+
hooks:
77+
- id: nbstripout
78+
files: ^notebooks/.*\.ipynb$
79+
stages: [pre-commit]
80+
81+
- repo: local
82+
hooks:
83+
- id: safety
84+
name: safety (dependency vulnerability scan)
85+
entry: safety check --file=uv.lock --full-report
86+
language: python
87+
types: [python]
88+
additional_dependencies: [safety==3.6.2]
89+
pass_filenames: false
90+
stages: [pre-push]
91+
require_serial: true

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

.secrets.baseline

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
{
2+
"version": "1.5.0",
3+
"plugins_used": [
4+
{
5+
"name": "ArtifactoryDetector"
6+
},
7+
{
8+
"name": "AWSKeyDetector"
9+
},
10+
{
11+
"name": "AzureStorageKeyDetector"
12+
},
13+
{
14+
"name": "Base64HighEntropyString",
15+
"limit": 4.5
16+
},
17+
{
18+
"name": "BasicAuthDetector"
19+
},
20+
{
21+
"name": "CloudantDetector"
22+
},
23+
{
24+
"name": "DiscordBotTokenDetector"
25+
},
26+
{
27+
"name": "GitHubTokenDetector"
28+
},
29+
{
30+
"name": "GitLabTokenDetector"
31+
},
32+
{
33+
"name": "HexHighEntropyString",
34+
"limit": 3.0
35+
},
36+
{
37+
"name": "IbmCloudIamDetector"
38+
},
39+
{
40+
"name": "IbmCosHmacDetector"
41+
},
42+
{
43+
"name": "IPPublicDetector"
44+
},
45+
{
46+
"name": "JwtTokenDetector"
47+
},
48+
{
49+
"name": "KeywordDetector",
50+
"keyword_exclude": ""
51+
},
52+
{
53+
"name": "MailchimpDetector"
54+
},
55+
{
56+
"name": "NpmDetector"
57+
},
58+
{
59+
"name": "OpenAIDetector"
60+
},
61+
{
62+
"name": "PrivateKeyDetector"
63+
},
64+
{
65+
"name": "PypiTokenDetector"
66+
},
67+
{
68+
"name": "SendGridDetector"
69+
},
70+
{
71+
"name": "SlackDetector"
72+
},
73+
{
74+
"name": "SoftlayerDetector"
75+
},
76+
{
77+
"name": "SquareOAuthDetector"
78+
},
79+
{
80+
"name": "StripeDetector"
81+
},
82+
{
83+
"name": "TelegramBotTokenDetector"
84+
},
85+
{
86+
"name": "TwilioKeyDetector"
87+
}
88+
],
89+
"filters_used": [
90+
{
91+
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
92+
},
93+
{
94+
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
95+
"min_level": 2
96+
},
97+
{
98+
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
99+
},
100+
{
101+
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
102+
},
103+
{
104+
"path": "detect_secrets.filters.heuristic.is_lock_file"
105+
},
106+
{
107+
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
108+
},
109+
{
110+
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
111+
},
112+
{
113+
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
114+
},
115+
{
116+
"path": "detect_secrets.filters.heuristic.is_sequential_string"
117+
},
118+
{
119+
"path": "detect_secrets.filters.heuristic.is_swagger_file"
120+
},
121+
{
122+
"path": "detect_secrets.filters.heuristic.is_templated_secret"
123+
},
124+
{
125+
"path": "detect_secrets.filters.regex.should_exclude_file",
126+
"pattern": [
127+
"\\.git/.*|\\.venv/.*|node_modules/.*|\\.ruff_cache/.*"
128+
]
129+
}
130+
],
131+
"results": {
132+
".idea/workspace.xml": [
133+
{
134+
"type": "Base64 High Entropy String",
135+
"filename": ".idea/workspace.xml",
136+
"hashed_secret": "d7193427bec9a2bb7f44cc949fe764b476462edd",
137+
"is_verified": false,
138+
"line_number": 19
139+
}
140+
]
141+
},
142+
"generated_at": "2025-09-28T05:37:21Z"
143+
}

LICENSE

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2025, Tejas Hareshbhai Pancholi
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
3. Neither the name of the copyright holder nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

0 commit comments

Comments
 (0)