apihunterx 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- apihunterx-0.1.0/LICENSE +1 -0
- apihunterx-0.1.0/PKG-INFO +7 -0
- apihunterx-0.1.0/README.md +205 -0
- apihunterx-0.1.0/api_hunter/__init__.py +3 -0
- apihunterx-0.1.0/api_hunter/cli.py +54 -0
- apihunterx-0.1.0/api_hunter/detector.py +58 -0
- apihunterx-0.1.0/api_hunter/report.py +49 -0
- apihunterx-0.1.0/api_hunter/scanner.py +46 -0
- apihunterx-0.1.0/apihunterx.egg-info/PKG-INFO +7 -0
- apihunterx-0.1.0/apihunterx.egg-info/SOURCES.txt +13 -0
- apihunterx-0.1.0/apihunterx.egg-info/dependency_links.txt +1 -0
- apihunterx-0.1.0/apihunterx.egg-info/entry_points.txt +2 -0
- apihunterx-0.1.0/apihunterx.egg-info/top_level.txt +4 -0
- apihunterx-0.1.0/pyproject.toml +15 -0
- apihunterx-0.1.0/setup.cfg +4 -0
apihunterx-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TODO: Choose a license for this project.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# API Hunter
|
|
2
|
+
|
|
3
|
+
A lightweight Python CLI tool that scans projects and generates an inventory of APIs, SDKs, URLs, and environment variables used throughout the codebase.
|
|
4
|
+
|
|
5
|
+
Perfect for:
|
|
6
|
+
|
|
7
|
+
* Developers onboarding to new projects
|
|
8
|
+
* DevOps engineers auditing dependencies
|
|
9
|
+
* Security reviews
|
|
10
|
+
* Documentation generation
|
|
11
|
+
* API discovery and inventory management
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
✅ Detect API SDKs
|
|
18
|
+
|
|
19
|
+
* OpenAI
|
|
20
|
+
* AWS (boto3)
|
|
21
|
+
* Anthropic
|
|
22
|
+
* Stripe
|
|
23
|
+
* Discord
|
|
24
|
+
* Tweepy
|
|
25
|
+
* Google Gemini
|
|
26
|
+
* HTTP clients (Requests, HTTPX)
|
|
27
|
+
|
|
28
|
+
✅ Detect API URLs
|
|
29
|
+
|
|
30
|
+
* REST endpoints
|
|
31
|
+
* External service URLs
|
|
32
|
+
* Webhook URLs
|
|
33
|
+
|
|
34
|
+
✅ Detect Environment Variables
|
|
35
|
+
|
|
36
|
+
* `os.getenv()`
|
|
37
|
+
* `os.environ[]`
|
|
38
|
+
|
|
39
|
+
✅ Generate Reports
|
|
40
|
+
|
|
41
|
+
* Human-readable TXT reports
|
|
42
|
+
* Fast project scanning
|
|
43
|
+
* Recursive file discovery
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install api-hunter
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For local development:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/yourusername/api-hunter.git
|
|
57
|
+
|
|
58
|
+
cd api-hunter
|
|
59
|
+
|
|
60
|
+
pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
Scan a project:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
api-hunter scan .
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Scan another directory:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
api-hunter scan D:\projects\my-app
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Alternative execution:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
python -m api_hunter scan .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Example Output
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
==================================================
|
|
91
|
+
API HUNTER REPORT
|
|
92
|
+
==================================================
|
|
93
|
+
|
|
94
|
+
DETECTED SERVICES
|
|
95
|
+
------------------------------
|
|
96
|
+
- OpenAI
|
|
97
|
+
- AWS
|
|
98
|
+
|
|
99
|
+
API URLS
|
|
100
|
+
------------------------------
|
|
101
|
+
- https://api.openai.com/v1/chat/completions
|
|
102
|
+
- https://api.github.com/repos
|
|
103
|
+
|
|
104
|
+
ENVIRONMENT VARIABLES
|
|
105
|
+
------------------------------
|
|
106
|
+
- OPENAI_API_KEY
|
|
107
|
+
- AWS_SECRET_ACCESS_KEY
|
|
108
|
+
|
|
109
|
+
FILES SCANNED: 42
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Supported Detection
|
|
115
|
+
|
|
116
|
+
### SDK Imports
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import openai
|
|
120
|
+
import boto3
|
|
121
|
+
import stripe
|
|
122
|
+
from anthropic import Anthropic
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### URLs
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
url = "https://api.openai.com/v1/chat/completions"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Environment Variables
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
os.getenv("OPENAI_API_KEY")
|
|
135
|
+
|
|
136
|
+
os.environ["AWS_SECRET_ACCESS_KEY"]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Roadmap
|
|
142
|
+
|
|
143
|
+
### Version 0.2
|
|
144
|
+
|
|
145
|
+
* JSON reports
|
|
146
|
+
* Markdown reports
|
|
147
|
+
* Requirements.txt analysis
|
|
148
|
+
* pyproject.toml analysis
|
|
149
|
+
|
|
150
|
+
### Version 0.3
|
|
151
|
+
|
|
152
|
+
* FastAPI route discovery
|
|
153
|
+
* Flask route discovery
|
|
154
|
+
* OpenAPI detection
|
|
155
|
+
* Swagger detection
|
|
156
|
+
|
|
157
|
+
### Version 0.4
|
|
158
|
+
|
|
159
|
+
* Security auditing
|
|
160
|
+
* Hardcoded API key detection
|
|
161
|
+
* Secret exposure warnings
|
|
162
|
+
|
|
163
|
+
### Version 1.0
|
|
164
|
+
|
|
165
|
+
* Multi-language support
|
|
166
|
+
* JavaScript support
|
|
167
|
+
* TypeScript support
|
|
168
|
+
* Dependency graph generation
|
|
169
|
+
* HTML reports
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Why API Hunter?
|
|
174
|
+
|
|
175
|
+
Many projects rely on dozens of external APIs and services but lack proper documentation.
|
|
176
|
+
|
|
177
|
+
API Hunter helps teams quickly understand:
|
|
178
|
+
|
|
179
|
+
* Which APIs are used
|
|
180
|
+
* Which environment variables are required
|
|
181
|
+
* Which external services are connected
|
|
182
|
+
* What dependencies a project relies on
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Contributing
|
|
187
|
+
|
|
188
|
+
Contributions, bug reports, and feature requests are welcome.
|
|
189
|
+
|
|
190
|
+
1. Fork the repository
|
|
191
|
+
2. Create a feature branch
|
|
192
|
+
3. Commit your changes
|
|
193
|
+
4. Submit a pull request
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT License
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Author
|
|
204
|
+
|
|
205
|
+
Samarth Patil
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from .scanner import scan_project
|
|
4
|
+
from .report import generate_txt_report
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
parser = argparse.ArgumentParser(
|
|
9
|
+
prog="api-hunter",
|
|
10
|
+
description="Scan projects for APIs, URLs and env vars"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
subparsers = parser.add_subparsers(
|
|
14
|
+
dest="command"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
scan_parser = subparsers.add_parser(
|
|
18
|
+
"scan",
|
|
19
|
+
help="Scan project"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
scan_parser.add_argument(
|
|
23
|
+
"path",
|
|
24
|
+
help="Project path"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
args = parser.parse_args()
|
|
28
|
+
|
|
29
|
+
if args.command == "scan":
|
|
30
|
+
results = scan_project(args.path)
|
|
31
|
+
|
|
32
|
+
report = generate_txt_report(results)
|
|
33
|
+
|
|
34
|
+
print()
|
|
35
|
+
print("Scan Complete")
|
|
36
|
+
print(f"Report saved to: {report}")
|
|
37
|
+
print()
|
|
38
|
+
|
|
39
|
+
print(
|
|
40
|
+
f"Services Found: {len(results['services'])}"
|
|
41
|
+
)
|
|
42
|
+
print(
|
|
43
|
+
f"URLs Found: {len(results['urls'])}"
|
|
44
|
+
)
|
|
45
|
+
print(
|
|
46
|
+
f"Env Vars Found: {len(results['env_vars'])}"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
else:
|
|
50
|
+
parser.print_help()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
main()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import ast
|
|
3
|
+
|
|
4
|
+
KNOWN_APIS = {
|
|
5
|
+
"openai": "OpenAI",
|
|
6
|
+
"boto3": "AWS",
|
|
7
|
+
"stripe": "Stripe",
|
|
8
|
+
"anthropic": "Anthropic",
|
|
9
|
+
"google.generativeai": "Google Gemini",
|
|
10
|
+
"discord": "Discord",
|
|
11
|
+
"tweepy": "Twitter/X",
|
|
12
|
+
"requests": "HTTP Client",
|
|
13
|
+
"httpx": "HTTP Client",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
URL_REGEX = r"https?://[^\s\"'<>]+"
|
|
17
|
+
|
|
18
|
+
ENV_REGEXES = [
|
|
19
|
+
r'os\.getenv\(["\']([^"\']+)["\']\)',
|
|
20
|
+
r'os\.environ\["([^"]+)"\]',
|
|
21
|
+
r"os\.environ\['([^']+)'\]"
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def detect_imports(content):
|
|
26
|
+
services = set()
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
tree = ast.parse(content)
|
|
30
|
+
|
|
31
|
+
for node in ast.walk(tree):
|
|
32
|
+
if isinstance(node, ast.Import):
|
|
33
|
+
for alias in node.names:
|
|
34
|
+
if alias.name in KNOWN_APIS:
|
|
35
|
+
services.add(KNOWN_APIS[alias.name])
|
|
36
|
+
|
|
37
|
+
elif isinstance(node, ast.ImportFrom):
|
|
38
|
+
if node.module in KNOWN_APIS:
|
|
39
|
+
services.add(KNOWN_APIS[node.module])
|
|
40
|
+
|
|
41
|
+
except Exception:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
return services
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def detect_urls(content):
|
|
48
|
+
return set(re.findall(URL_REGEX, content))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def detect_env_vars(content):
|
|
52
|
+
envs = set()
|
|
53
|
+
|
|
54
|
+
for pattern in ENV_REGEXES:
|
|
55
|
+
matches = re.findall(pattern, content)
|
|
56
|
+
envs.update(matches)
|
|
57
|
+
|
|
58
|
+
return envs
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def generate_txt_report(results, output_file="api_inventory.txt"):
|
|
5
|
+
lines = []
|
|
6
|
+
|
|
7
|
+
lines.append("=" * 50)
|
|
8
|
+
lines.append("API HUNTER REPORT")
|
|
9
|
+
lines.append("=" * 50)
|
|
10
|
+
lines.append("")
|
|
11
|
+
|
|
12
|
+
lines.append("DETECTED SERVICES")
|
|
13
|
+
lines.append("-" * 30)
|
|
14
|
+
|
|
15
|
+
if results["services"]:
|
|
16
|
+
for service in results["services"]:
|
|
17
|
+
lines.append(f"- {service}")
|
|
18
|
+
else:
|
|
19
|
+
lines.append("None Found")
|
|
20
|
+
|
|
21
|
+
lines.append("")
|
|
22
|
+
lines.append("API URLS")
|
|
23
|
+
lines.append("-" * 30)
|
|
24
|
+
|
|
25
|
+
if results["urls"]:
|
|
26
|
+
for url in results["urls"]:
|
|
27
|
+
lines.append(f"- {url}")
|
|
28
|
+
else:
|
|
29
|
+
lines.append("None Found")
|
|
30
|
+
|
|
31
|
+
lines.append("")
|
|
32
|
+
lines.append("ENVIRONMENT VARIABLES")
|
|
33
|
+
lines.append("-" * 30)
|
|
34
|
+
|
|
35
|
+
if results["env_vars"]:
|
|
36
|
+
for env in results["env_vars"]:
|
|
37
|
+
lines.append(f"- {env}")
|
|
38
|
+
else:
|
|
39
|
+
lines.append("None Found")
|
|
40
|
+
|
|
41
|
+
lines.append("")
|
|
42
|
+
lines.append(f"FILES SCANNED: {results['files_scanned']}")
|
|
43
|
+
|
|
44
|
+
Path(output_file).write_text(
|
|
45
|
+
"\n".join(lines),
|
|
46
|
+
encoding="utf-8"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
return output_file
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from .detector import (
|
|
4
|
+
detect_imports,
|
|
5
|
+
detect_urls,
|
|
6
|
+
detect_env_vars
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def scan_project(project_path):
|
|
11
|
+
services = set()
|
|
12
|
+
urls = set()
|
|
13
|
+
env_vars = set()
|
|
14
|
+
|
|
15
|
+
files_scanned = 0
|
|
16
|
+
|
|
17
|
+
for file in Path(project_path).rglob("*.py"):
|
|
18
|
+
files_scanned += 1
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
content = file.read_text(
|
|
22
|
+
encoding="utf-8",
|
|
23
|
+
errors="ignore"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
services.update(
|
|
27
|
+
detect_imports(content)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
urls.update(
|
|
31
|
+
detect_urls(content)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
env_vars.update(
|
|
35
|
+
detect_env_vars(content)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
except Exception:
|
|
39
|
+
continue
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
"services": sorted(services),
|
|
43
|
+
"urls": sorted(urls),
|
|
44
|
+
"env_vars": sorted(env_vars),
|
|
45
|
+
"files_scanned": files_scanned
|
|
46
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
api_hunter/__init__.py
|
|
5
|
+
api_hunter/cli.py
|
|
6
|
+
api_hunter/detector.py
|
|
7
|
+
api_hunter/report.py
|
|
8
|
+
api_hunter/scanner.py
|
|
9
|
+
apihunterx.egg-info/PKG-INFO
|
|
10
|
+
apihunterx.egg-info/SOURCES.txt
|
|
11
|
+
apihunterx.egg-info/dependency_links.txt
|
|
12
|
+
apihunterx.egg-info/entry_points.txt
|
|
13
|
+
apihunterx.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "apihunterx"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Scan projects for APIs, URLs and environment variables"
|
|
9
|
+
requires-python = ">=3.8"
|
|
10
|
+
|
|
11
|
+
[tool.setuptools.packages.find]
|
|
12
|
+
where = ["."]
|
|
13
|
+
|
|
14
|
+
[project.scripts]
|
|
15
|
+
api-hunter = "apihunterx.cli:main"
|