knack-sleuth 0.1.1__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.
- knack_sleuth-0.1.1/PKG-INFO +175 -0
- knack_sleuth-0.1.1/README.md +164 -0
- knack_sleuth-0.1.1/pyproject.toml +30 -0
- knack_sleuth-0.1.1/src/knack_sleuth/__init__.py +30 -0
- knack_sleuth-0.1.1/src/knack_sleuth/cli.py +653 -0
- knack_sleuth-0.1.1/src/knack_sleuth/config.py +24 -0
- knack_sleuth-0.1.1/src/knack_sleuth/models.py +250 -0
- knack_sleuth-0.1.1/src/knack_sleuth/sleuth.py +338 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: knack-sleuth
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Requires-Dist: httpx[http2]>=0.28.1
|
|
6
|
+
Requires-Dist: pydantic>=2.12.3
|
|
7
|
+
Requires-Dist: pydantic-settings>=2.11.0
|
|
8
|
+
Requires-Dist: typer>=0.20.0
|
|
9
|
+
Requires-Python: >=3.13
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# KnackSleuth
|
|
13
|
+
|
|
14
|
+
**Detective work for your Knack applications.** 🕵️
|
|
15
|
+
|
|
16
|
+
KnackSleuth investigates your Knack app metadata to uncover where objects, fields, and connections are used throughout your application. Like a good detective, it traces every lead—from data relationships and view dependencies to hidden references in formulas and filters.
|
|
17
|
+
|
|
18
|
+
Whether you're refactoring a complex app, auditing data dependencies, or trying to understand the ripple effects of a schema change, KnackSleuth does the investigative work so you don't have to.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Download Metadata
|
|
23
|
+
|
|
24
|
+
Download and save your Knack application metadata to a local file:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Download with default filename ({APP_ID}_metadata.json)
|
|
28
|
+
uv run knack-sleuth download-metadata
|
|
29
|
+
|
|
30
|
+
# Specify custom filename
|
|
31
|
+
uv run knack-sleuth download-metadata my_app_backup.json
|
|
32
|
+
|
|
33
|
+
# Force fresh download (ignore cache)
|
|
34
|
+
uv run knack-sleuth download-metadata --refresh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This is useful for:
|
|
38
|
+
- Creating backups of your app structure
|
|
39
|
+
- Working offline with the metadata
|
|
40
|
+
- Sharing app structure with others
|
|
41
|
+
- Version control / tracking changes over time
|
|
42
|
+
|
|
43
|
+
The file is saved as formatted JSON (indented) for easy reading and version control.
|
|
44
|
+
|
|
45
|
+
### Show Object Coupling
|
|
46
|
+
|
|
47
|
+
View the coupling relationships for a specific object - see which objects depend on it and which objects it depends on:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Using object key
|
|
51
|
+
uv run knack-sleuth show-coupling object_12 path/to/knack_export.json
|
|
52
|
+
|
|
53
|
+
# Using object name
|
|
54
|
+
uv run knack-sleuth show-coupling "Events" path/to/knack_export.json
|
|
55
|
+
|
|
56
|
+
# From API
|
|
57
|
+
uv run knack-sleuth show-coupling object_34 --app-id YOUR_APP_ID --api-key YOUR_KEY
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This displays:
|
|
61
|
+
- **Afferent Coupling (Ca)**: Objects that depend on this object (incoming connections with ← arrows)
|
|
62
|
+
- **Efferent Coupling (Ce)**: Objects this object depends on (outgoing connections with → arrows)
|
|
63
|
+
- Connection details: field names, keys, and relationship types
|
|
64
|
+
|
|
65
|
+
Perfect for understanding an object's role in your data model from its perspective.
|
|
66
|
+
|
|
67
|
+
### List All Objects
|
|
68
|
+
|
|
69
|
+
Get an overview of all objects in your Knack application:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Using a local JSON file
|
|
73
|
+
uv run knack-sleuth list-objects path/to/knack_export.json
|
|
74
|
+
|
|
75
|
+
# Fetching from API
|
|
76
|
+
uv run knack-sleuth list-objects --app-id YOUR_APP_ID --api-key YOUR_KEY
|
|
77
|
+
|
|
78
|
+
# Using environment variables
|
|
79
|
+
uv run knack-sleuth list-objects
|
|
80
|
+
|
|
81
|
+
# Sort by row count (largest first)
|
|
82
|
+
uv run knack-sleuth list-objects --sort-by-rows path/to/knack_export.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This displays a table showing:
|
|
86
|
+
- Object key and name
|
|
87
|
+
- Number of rows (records) in each object
|
|
88
|
+
- Number of fields in each object
|
|
89
|
+
- **Ca** (Afferent coupling): Number of inbound connections - how many other objects depend on this one
|
|
90
|
+
- **Ce** (Efferent coupling): Number of outbound connections - how many other objects this one depends on
|
|
91
|
+
- Total connections (Ca + Ce)
|
|
92
|
+
|
|
93
|
+
**Sorting:**
|
|
94
|
+
- Default: Alphabetically by object name
|
|
95
|
+
- `--sort-by-rows`: Sort by row count (largest first) to quickly identify your biggest tables
|
|
96
|
+
|
|
97
|
+
**Coupling Insights:**
|
|
98
|
+
- High Ca, Low Ce = Hub/core objects that many others depend on (stable, reusable)
|
|
99
|
+
- Low Ca, High Ce = Highly coupled objects with many dependencies (potentially fragile)
|
|
100
|
+
- High Ca + High Ce = Central, complex objects (review for potential refactoring)
|
|
101
|
+
|
|
102
|
+
### Search for Object Usages
|
|
103
|
+
|
|
104
|
+
Search for all places where an object is used in your Knack application.
|
|
105
|
+
|
|
106
|
+
#### Using a Local JSON File
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Search by object key
|
|
110
|
+
uv run knack-sleuth search-object object_12 path/to/knack_export.json
|
|
111
|
+
|
|
112
|
+
# Search by object name
|
|
113
|
+
uv run knack-sleuth search-object "College/School" path/to/knack_export.json
|
|
114
|
+
|
|
115
|
+
# Hide field-level usages (show only object-level)
|
|
116
|
+
uv run knack-sleuth search-object object_12 path/to/knack_export.json --no-fields
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### Fetching from Knack API
|
|
120
|
+
|
|
121
|
+
You can fetch metadata directly from the Knack API instead of using a local file:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Using command-line options
|
|
125
|
+
uv run knack-sleuth search-object object_12 --app-id YOUR_APP_ID --api-key YOUR_API_KEY
|
|
126
|
+
|
|
127
|
+
# Using environment variables
|
|
128
|
+
export KNACK_APP_ID=your_app_id
|
|
129
|
+
export KNACK_API_KEY=your_api_key
|
|
130
|
+
uv run knack-sleuth search-object object_12
|
|
131
|
+
|
|
132
|
+
# Or use a .env file in the project root:
|
|
133
|
+
# KNACK_APP_ID=your_app_id
|
|
134
|
+
# KNACK_API_KEY=your_api_key
|
|
135
|
+
uv run knack-sleuth search-object object_12
|
|
136
|
+
|
|
137
|
+
# Force refresh cached data (ignore cache)
|
|
138
|
+
uv run knack-sleuth search-object object_12 --refresh
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Caching Behavior:**
|
|
142
|
+
- API responses are automatically cached to `{APP_ID}_app_metadata_{YYYYMMDDHHMM}.json`
|
|
143
|
+
- Cached data is reused for 24 hours to avoid unnecessary API calls
|
|
144
|
+
- Use `--refresh` to force fetching fresh data from the API
|
|
145
|
+
- Cache files are stored in the current working directory
|
|
146
|
+
|
|
147
|
+
The command will show:
|
|
148
|
+
- **Object-level usages**: Where the object appears in connections, views, and other metadata
|
|
149
|
+
- **Field-level usages**: Where each field is used (columns, sorts, formulas, etc.) - can be disabled with `--no-fields`
|
|
150
|
+
- **Builder Pages to Review**: Direct links to scenes in the Knack builder where this object is used
|
|
151
|
+
|
|
152
|
+
#### Builder Integration
|
|
153
|
+
|
|
154
|
+
The search results include clickable links to the Knack builder pages where the object is used:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Classic builder URLs (default)
|
|
158
|
+
export KNACK_NEXT_GEN_BUILDER=false
|
|
159
|
+
uv run knack-sleuth search-object object_12
|
|
160
|
+
# → https://builder.knack.com/your-account/portal/pages/scene_7
|
|
161
|
+
|
|
162
|
+
# Next-Gen builder URLs
|
|
163
|
+
export KNACK_NEXT_GEN_BUILDER=true
|
|
164
|
+
uv run knack-sleuth search-object object_12
|
|
165
|
+
# → https://builder-next.knack.com/your-account/portal/pages/scene_7
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
### Options
|
|
170
|
+
|
|
171
|
+
- `--app-id TEXT`: Knack application ID (or use `KNACK_APP_ID` env var)
|
|
172
|
+
- `--api-key TEXT`: Knack API key (or use `KNACK_API_KEY` env var)
|
|
173
|
+
- `--refresh`: Force refresh cached API data (ignore 24-hour cache)
|
|
174
|
+
- `--show-fields` / `--no-fields`: Control whether to show field-level usages (default: show)
|
|
175
|
+
- `--help`: Show help message
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# KnackSleuth
|
|
2
|
+
|
|
3
|
+
**Detective work for your Knack applications.** 🕵️
|
|
4
|
+
|
|
5
|
+
KnackSleuth investigates your Knack app metadata to uncover where objects, fields, and connections are used throughout your application. Like a good detective, it traces every lead—from data relationships and view dependencies to hidden references in formulas and filters.
|
|
6
|
+
|
|
7
|
+
Whether you're refactoring a complex app, auditing data dependencies, or trying to understand the ripple effects of a schema change, KnackSleuth does the investigative work so you don't have to.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
### Download Metadata
|
|
12
|
+
|
|
13
|
+
Download and save your Knack application metadata to a local file:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Download with default filename ({APP_ID}_metadata.json)
|
|
17
|
+
uv run knack-sleuth download-metadata
|
|
18
|
+
|
|
19
|
+
# Specify custom filename
|
|
20
|
+
uv run knack-sleuth download-metadata my_app_backup.json
|
|
21
|
+
|
|
22
|
+
# Force fresh download (ignore cache)
|
|
23
|
+
uv run knack-sleuth download-metadata --refresh
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This is useful for:
|
|
27
|
+
- Creating backups of your app structure
|
|
28
|
+
- Working offline with the metadata
|
|
29
|
+
- Sharing app structure with others
|
|
30
|
+
- Version control / tracking changes over time
|
|
31
|
+
|
|
32
|
+
The file is saved as formatted JSON (indented) for easy reading and version control.
|
|
33
|
+
|
|
34
|
+
### Show Object Coupling
|
|
35
|
+
|
|
36
|
+
View the coupling relationships for a specific object - see which objects depend on it and which objects it depends on:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Using object key
|
|
40
|
+
uv run knack-sleuth show-coupling object_12 path/to/knack_export.json
|
|
41
|
+
|
|
42
|
+
# Using object name
|
|
43
|
+
uv run knack-sleuth show-coupling "Events" path/to/knack_export.json
|
|
44
|
+
|
|
45
|
+
# From API
|
|
46
|
+
uv run knack-sleuth show-coupling object_34 --app-id YOUR_APP_ID --api-key YOUR_KEY
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This displays:
|
|
50
|
+
- **Afferent Coupling (Ca)**: Objects that depend on this object (incoming connections with ← arrows)
|
|
51
|
+
- **Efferent Coupling (Ce)**: Objects this object depends on (outgoing connections with → arrows)
|
|
52
|
+
- Connection details: field names, keys, and relationship types
|
|
53
|
+
|
|
54
|
+
Perfect for understanding an object's role in your data model from its perspective.
|
|
55
|
+
|
|
56
|
+
### List All Objects
|
|
57
|
+
|
|
58
|
+
Get an overview of all objects in your Knack application:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Using a local JSON file
|
|
62
|
+
uv run knack-sleuth list-objects path/to/knack_export.json
|
|
63
|
+
|
|
64
|
+
# Fetching from API
|
|
65
|
+
uv run knack-sleuth list-objects --app-id YOUR_APP_ID --api-key YOUR_KEY
|
|
66
|
+
|
|
67
|
+
# Using environment variables
|
|
68
|
+
uv run knack-sleuth list-objects
|
|
69
|
+
|
|
70
|
+
# Sort by row count (largest first)
|
|
71
|
+
uv run knack-sleuth list-objects --sort-by-rows path/to/knack_export.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This displays a table showing:
|
|
75
|
+
- Object key and name
|
|
76
|
+
- Number of rows (records) in each object
|
|
77
|
+
- Number of fields in each object
|
|
78
|
+
- **Ca** (Afferent coupling): Number of inbound connections - how many other objects depend on this one
|
|
79
|
+
- **Ce** (Efferent coupling): Number of outbound connections - how many other objects this one depends on
|
|
80
|
+
- Total connections (Ca + Ce)
|
|
81
|
+
|
|
82
|
+
**Sorting:**
|
|
83
|
+
- Default: Alphabetically by object name
|
|
84
|
+
- `--sort-by-rows`: Sort by row count (largest first) to quickly identify your biggest tables
|
|
85
|
+
|
|
86
|
+
**Coupling Insights:**
|
|
87
|
+
- High Ca, Low Ce = Hub/core objects that many others depend on (stable, reusable)
|
|
88
|
+
- Low Ca, High Ce = Highly coupled objects with many dependencies (potentially fragile)
|
|
89
|
+
- High Ca + High Ce = Central, complex objects (review for potential refactoring)
|
|
90
|
+
|
|
91
|
+
### Search for Object Usages
|
|
92
|
+
|
|
93
|
+
Search for all places where an object is used in your Knack application.
|
|
94
|
+
|
|
95
|
+
#### Using a Local JSON File
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Search by object key
|
|
99
|
+
uv run knack-sleuth search-object object_12 path/to/knack_export.json
|
|
100
|
+
|
|
101
|
+
# Search by object name
|
|
102
|
+
uv run knack-sleuth search-object "College/School" path/to/knack_export.json
|
|
103
|
+
|
|
104
|
+
# Hide field-level usages (show only object-level)
|
|
105
|
+
uv run knack-sleuth search-object object_12 path/to/knack_export.json --no-fields
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### Fetching from Knack API
|
|
109
|
+
|
|
110
|
+
You can fetch metadata directly from the Knack API instead of using a local file:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Using command-line options
|
|
114
|
+
uv run knack-sleuth search-object object_12 --app-id YOUR_APP_ID --api-key YOUR_API_KEY
|
|
115
|
+
|
|
116
|
+
# Using environment variables
|
|
117
|
+
export KNACK_APP_ID=your_app_id
|
|
118
|
+
export KNACK_API_KEY=your_api_key
|
|
119
|
+
uv run knack-sleuth search-object object_12
|
|
120
|
+
|
|
121
|
+
# Or use a .env file in the project root:
|
|
122
|
+
# KNACK_APP_ID=your_app_id
|
|
123
|
+
# KNACK_API_KEY=your_api_key
|
|
124
|
+
uv run knack-sleuth search-object object_12
|
|
125
|
+
|
|
126
|
+
# Force refresh cached data (ignore cache)
|
|
127
|
+
uv run knack-sleuth search-object object_12 --refresh
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Caching Behavior:**
|
|
131
|
+
- API responses are automatically cached to `{APP_ID}_app_metadata_{YYYYMMDDHHMM}.json`
|
|
132
|
+
- Cached data is reused for 24 hours to avoid unnecessary API calls
|
|
133
|
+
- Use `--refresh` to force fetching fresh data from the API
|
|
134
|
+
- Cache files are stored in the current working directory
|
|
135
|
+
|
|
136
|
+
The command will show:
|
|
137
|
+
- **Object-level usages**: Where the object appears in connections, views, and other metadata
|
|
138
|
+
- **Field-level usages**: Where each field is used (columns, sorts, formulas, etc.) - can be disabled with `--no-fields`
|
|
139
|
+
- **Builder Pages to Review**: Direct links to scenes in the Knack builder where this object is used
|
|
140
|
+
|
|
141
|
+
#### Builder Integration
|
|
142
|
+
|
|
143
|
+
The search results include clickable links to the Knack builder pages where the object is used:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Classic builder URLs (default)
|
|
147
|
+
export KNACK_NEXT_GEN_BUILDER=false
|
|
148
|
+
uv run knack-sleuth search-object object_12
|
|
149
|
+
# → https://builder.knack.com/your-account/portal/pages/scene_7
|
|
150
|
+
|
|
151
|
+
# Next-Gen builder URLs
|
|
152
|
+
export KNACK_NEXT_GEN_BUILDER=true
|
|
153
|
+
uv run knack-sleuth search-object object_12
|
|
154
|
+
# → https://builder-next.knack.com/your-account/portal/pages/scene_7
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
### Options
|
|
159
|
+
|
|
160
|
+
- `--app-id TEXT`: Knack application ID (or use `KNACK_APP_ID` env var)
|
|
161
|
+
- `--api-key TEXT`: Knack API key (or use `KNACK_API_KEY` env var)
|
|
162
|
+
- `--refresh`: Force refresh cached API data (ignore 24-hour cache)
|
|
163
|
+
- `--show-fields` / `--no-fields`: Control whether to show field-level usages (default: show)
|
|
164
|
+
- `--help`: Show help message
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "knack-sleuth"
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"httpx[http2]>=0.28.1",
|
|
9
|
+
"pydantic>=2.12.3",
|
|
10
|
+
"pydantic-settings>=2.11.0",
|
|
11
|
+
"typer>=0.20.0",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[project.scripts]
|
|
15
|
+
knack-sleuth = "knack_sleuth.cli:cli"
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["uv_build>=0.9.5,<0.10.0"]
|
|
19
|
+
build-backend = "uv_build"
|
|
20
|
+
|
|
21
|
+
[dependency-groups]
|
|
22
|
+
dev = [
|
|
23
|
+
"bump-my-version>=1.2.4",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
[tool.bumpversion]
|
|
28
|
+
current_version = "0.1.1"
|
|
29
|
+
commit = true
|
|
30
|
+
tag = true
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""KnackSlueth - Find usages of data objects in Knack app metadata."""
|
|
2
|
+
|
|
3
|
+
from knack_sleuth.models import (
|
|
4
|
+
Application,
|
|
5
|
+
Connection,
|
|
6
|
+
Connections,
|
|
7
|
+
HomeScene,
|
|
8
|
+
KnackAppExport,
|
|
9
|
+
KnackField,
|
|
10
|
+
KnackObject,
|
|
11
|
+
Scene,
|
|
12
|
+
View,
|
|
13
|
+
ViewSource,
|
|
14
|
+
)
|
|
15
|
+
from knack_sleuth.sleuth import KnackSleuth, Usage
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"Application",
|
|
19
|
+
"Connection",
|
|
20
|
+
"Connections",
|
|
21
|
+
"HomeScene",
|
|
22
|
+
"KnackAppExport",
|
|
23
|
+
"KnackField",
|
|
24
|
+
"KnackObject",
|
|
25
|
+
"KnackSleuth",
|
|
26
|
+
"Scene",
|
|
27
|
+
"Usage",
|
|
28
|
+
"View",
|
|
29
|
+
"ViewSource",
|
|
30
|
+
]
|