gravi-cli 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.
@@ -0,0 +1,27 @@
1
+ [tool.bumpversion]
2
+ current_version = "0.1.1"
3
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
4
+ serialize = ["{major}.{minor}.{patch}"]
5
+ search = "{current_version}"
6
+ replace = "{new_version}"
7
+ regex = false
8
+ ignore_missing_version = false
9
+ ignore_missing_files = false
10
+ tag = false
11
+ sign_tags = false
12
+ tag_name = "v{new_version}"
13
+ tag_message = "Bump version: {current_version} → {new_version}"
14
+ allow_dirty = false
15
+ commit = false
16
+ message = "Bump version: {current_version} → {new_version}"
17
+ commit_args = ""
18
+
19
+ [[tool.bumpversion.files]]
20
+ filename = "pyproject.toml"
21
+ search = 'version = "{current_version}"'
22
+ replace = 'version = "{new_version}"'
23
+
24
+ [[tool.bumpversion.files]]
25
+ filename = "gravi_cli/__init__.py"
26
+ search = '__version__ = "{current_version}"'
27
+ replace = '__version__ = "{new_version}"'
@@ -0,0 +1,46 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ venv/
25
+ env/
26
+ ENV/
27
+
28
+ # Testing
29
+ .pytest_cache/
30
+ .coverage
31
+ htmlcov/
32
+ .tox/
33
+
34
+ # IDE
35
+ .vscode/
36
+ .idea/
37
+ *.swp
38
+ *.swo
39
+ *~
40
+
41
+ # OS
42
+ .DS_Store
43
+ Thumbs.db
44
+
45
+ # Config (sensitive)
46
+ config.json
@@ -0,0 +1,31 @@
1
+ Proprietary License
2
+
3
+ Copyright (c) 2025 Gravitate
4
+
5
+ All rights reserved.
6
+
7
+ This software and associated documentation files (the "Software") are proprietary
8
+ and confidential to Gravitate.
9
+
10
+ The source code is made available for inspection and review purposes only.
11
+
12
+ RESTRICTIONS:
13
+
14
+ 1. You may NOT use, copy, modify, merge, publish, distribute, sublicense, and/or
15
+ sell copies of the Software without explicit written permission from Gravitate.
16
+
17
+ 2. You may NOT create derivative works based on the Software.
18
+
19
+ 3. You may NOT reverse engineer, decompile, or disassemble the Software.
20
+
21
+ 4. You may view the source code for informational purposes only.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+
31
+ For licensing inquiries, please contact: Gravitate
@@ -0,0 +1,345 @@
1
+ Metadata-Version: 2.4
2
+ Name: gravi-cli
3
+ Version: 0.1.1
4
+ Summary: CLI tool for Gravitate infrastructure management
5
+ Project-URL: Homepage, https://github.com/gravitate/mom
6
+ Project-URL: Documentation, https://github.com/gravitate/mom/tree/main/cli
7
+ Project-URL: Repository, https://github.com/gravitate/mom
8
+ Author-email: Gravitate Engineering <engineering@gravitate.com>
9
+ License: Proprietary
10
+ License-File: LICENSE
11
+ Keywords: cli,devops,gravitate,infrastructure
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: Other/Proprietary License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: click>=8.1.0
22
+ Requires-Dist: pydantic>=2.0.0
23
+ Requires-Dist: requests>=2.31.0
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
26
+ Requires-Dist: pytest-mock>=3.11.0; extra == 'test'
27
+ Requires-Dist: pytest>=7.4.0; extra == 'test'
28
+ Requires-Dist: responses>=0.24.0; extra == 'test'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Gravi CLI
32
+
33
+ Command-line tool for Gravitate infrastructure management. Provides CLI access to mom infrastructure, allowing developers to authenticate, manage tokens, and access instance configurations and credentials.
34
+
35
+ ## Features
36
+
37
+ - **OAuth-style device authorization** - Secure browser-based authentication
38
+ - **Automatic token refresh** - Tokens auto-renew when <7 days remaining
39
+ - **Token management** - List, revoke, and manage CLI tokens
40
+ - **Instance access** - Get configurations and credentials for Gravitate instances
41
+ - **Python library API** - Use programmatically in scripts and applications
42
+ - **CI/CD support** - Environment variable-based authentication
43
+
44
+ ## Installation
45
+
46
+ ### From Source (Development)
47
+
48
+ Using `uv` (recommended):
49
+
50
+ ```bash
51
+ cd /home/jvogel/src/work/tools/mom/cli
52
+ uv pip install -e ".[test]"
53
+ ```
54
+
55
+ Or with traditional pip:
56
+
57
+ ```bash
58
+ cd /home/jvogel/src/work/tools/mom/cli
59
+ pip install -e ".[test]"
60
+ ```
61
+
62
+ ### From PyPI (Future)
63
+
64
+ ```bash
65
+ pip install gravi-cli
66
+ # or
67
+ uv pip install gravi-cli
68
+ ```
69
+
70
+ ## Quick Start
71
+
72
+ **Note:** If you installed with `uv pip install -e .`, you can run the CLI using `uvx --from . gravi` or just `gravi` if it's in your PATH.
73
+
74
+ ### 1. Login
75
+
76
+ ```bash
77
+ gravi login
78
+ # or with uvx:
79
+ uvx --from . gravi login
80
+ ```
81
+
82
+ This will:
83
+ 1. Open your browser to mom authorization page
84
+ 2. Display a user code (e.g., `ABCD-1234`)
85
+ 3. Wait for you to authorize in the browser
86
+ 4. Save credentials to `~/.config/gravi/config.json`
87
+
88
+ ### 2. Check Status
89
+
90
+ ```bash
91
+ gravi status
92
+ ```
93
+
94
+ Shows:
95
+ - Current user email
96
+ - Mom URL
97
+ - Device name
98
+ - Token ID
99
+ - Token expiry
100
+
101
+ ### 3. Get Instance Configuration
102
+
103
+ ```bash
104
+ # Get config as JSON
105
+ gravi config dev
106
+
107
+ # Get config as environment variables
108
+ gravi config prod --format=env
109
+ ```
110
+
111
+ ### 4. Logout
112
+
113
+ ```bash
114
+ gravi logout
115
+ ```
116
+
117
+ Revokes token on server and clears local credentials.
118
+
119
+ ## CLI Commands
120
+
121
+ ### Authentication
122
+
123
+ ```bash
124
+ gravi login # Authenticate via browser
125
+ gravi logout # Clear credentials and revoke token
126
+ gravi status # Show login status and token expiry
127
+ gravi whoami # Show current user info
128
+ ```
129
+
130
+ ### Token Management
131
+
132
+ ```bash
133
+ gravi tokens list # List all CLI tokens
134
+ gravi tokens revoke <token_id> # Revoke a specific token
135
+ gravi tokens revoke --all # Revoke all tokens
136
+ ```
137
+
138
+ ### Instance Access
139
+
140
+ ```bash
141
+ gravi config <instance_key> # Get instance configuration
142
+ gravi config <instance_key> --format=env # Get as environment variables
143
+ ```
144
+
145
+ ## Python Library API
146
+
147
+ Use gravi_cli programmatically in Python scripts:
148
+
149
+ ```python
150
+ from gravi_cli.api import get_instance_config, get_instance_token
151
+
152
+ # Get database credentials
153
+ config = get_instance_config("prod")
154
+ db_url = config["config"]["database_url"]
155
+
156
+ # Get ServiceNow access token
157
+ token_response = get_instance_token("dev")
158
+ sn_token = token_response["access_token"]
159
+
160
+ # Get mom access token directly
161
+ from gravi_cli.api import get_mom_token
162
+ mom_token = get_mom_token() # Auto-refreshes if needed
163
+ ```
164
+
165
+ ### Example: Database Connection
166
+
167
+ ```python
168
+ from gravi_cli.api import get_instance_config
169
+ import psycopg2
170
+
171
+ # Get prod database credentials
172
+ config = get_instance_config("prod")
173
+ conn = psycopg2.connect(config["config"]["database_url"])
174
+
175
+ # Use database
176
+ cursor = conn.cursor()
177
+ cursor.execute("SELECT * FROM users LIMIT 10")
178
+ ```
179
+
180
+ ### Example: ServiceNow API
181
+
182
+ ```python
183
+ from gravi_cli.api import get_instance_config, get_instance_token
184
+ import requests
185
+
186
+ # Get ServiceNow config and token
187
+ config = get_instance_config("dev")
188
+ token_response = get_instance_token("dev")
189
+
190
+ # Make ServiceNow API call
191
+ response = requests.get(
192
+ f"{config['api_url']}/api/now/table/incident",
193
+ headers={"Authorization": f"Bearer {token_response['access_token']}"}
194
+ )
195
+ incidents = response.json()
196
+ ```
197
+
198
+ ## CI/CD Usage
199
+
200
+ For automated scripts and CI/CD pipelines:
201
+
202
+ ```bash
203
+ # Set refresh token as environment variable
204
+ export GRAVI_REFRESH_TOKEN="your_refresh_token_here"
205
+
206
+ # Commands will automatically use the env var
207
+ gravi config prod
208
+ ```
209
+
210
+ **Getting a CI/CD token:**
211
+ 1. Run `gravi login` on your local machine
212
+ 2. Run `gravi tokens list` to see your token ID
213
+ 3. Copy the refresh token from `~/.config/gravi/config.json`
214
+ 4. Set as `GRAVI_REFRESH_TOKEN` in your CI/CD system
215
+
216
+ **Security Note:** Treat `GRAVI_REFRESH_TOKEN` like a password. Use secret management systems (GitHub Secrets, AWS Secrets Manager, etc.) to store it securely.
217
+
218
+ ## Configuration
219
+
220
+ ### Config File Location
221
+
222
+ `~/.config/gravi/config.json`
223
+
224
+ ### Config File Format
225
+
226
+ ```json
227
+ {
228
+ "version": 1,
229
+ "user_email": "john.doe@gravitate.com",
230
+ "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
231
+ "refresh_token_expires_at": "2025-11-09T10:30:00Z",
232
+ "token_id": "507f1f77bcf86cd799439011",
233
+ "device_name": "John's MacBook"
234
+ }
235
+ ```
236
+
237
+ ### Environment Variables
238
+
239
+ - `GRAVI_MOM_URL` - Override mom API URL (default: `https://mom.gravitate.energy`)
240
+ - `GRAVI_REFRESH_TOKEN` - CI/CD refresh token (bypasses config file)
241
+
242
+ ### File Permissions
243
+
244
+ Config file is automatically set to `0600` (owner read/write only) for security.
245
+
246
+ ## Token Auto-Renewal
247
+
248
+ Refresh tokens are automatically renewed when <7 days remaining:
249
+ - CLI checks expiry on each use
250
+ - If <7 days: requests new 14-day token
251
+ - Config file updated automatically
252
+ - Seamless for users - no re-login needed
253
+
254
+ ## Development
255
+
256
+ ### Setup
257
+
258
+ ```bash
259
+ cd /home/jvogel/src/work/tools/mom/cli
260
+ pip install -e ".[test]"
261
+ ```
262
+
263
+ ### Run Tests
264
+
265
+ ```bash
266
+ # All tests
267
+ pytest
268
+
269
+ # With coverage
270
+ pytest --cov=gravi_cli --cov-report=term-missing
271
+
272
+ # Specific test file
273
+ pytest tests/test_config.py
274
+
275
+ # Verbose
276
+ pytest -v
277
+ ```
278
+
279
+ ### Project Structure
280
+
281
+ ```
282
+ cli/
283
+ ├── gravi_cli/
284
+ │ ├── __init__.py # Package metadata
285
+ │ ├── api.py # Public Python API
286
+ │ ├── auth.py # Token refresh and auth logic
287
+ │ ├── cli.py # CLI commands (Click)
288
+ │ ├── client.py # Mom API client
289
+ │ ├── config.py # Config file management
290
+ │ └── exceptions.py # Custom exceptions
291
+ ├── tests/
292
+ │ ├── conftest.py # Pytest fixtures
293
+ │ ├── test_config.py # Config tests
294
+ │ └── test_client.py # API client tests
295
+ ├── pyproject.toml # Package configuration
296
+ └── README.md # This file
297
+ ```
298
+
299
+ ## Troubleshooting
300
+
301
+ ### "Not logged in" Error
302
+
303
+ ```bash
304
+ gravi login
305
+ ```
306
+
307
+ ### "Token expired" Error
308
+
309
+ Tokens auto-renew, but if expired:
310
+
311
+ ```bash
312
+ gravi login
313
+ ```
314
+
315
+ ### Rate Limiting
316
+
317
+ If you hit rate limits, wait and retry. Rate limits reset every minute.
318
+
319
+ ### Mom URL Override (Development)
320
+
321
+ ```bash
322
+ # Temporary override
323
+ GRAVI_MOM_URL=https://mom.dev gravi login
324
+
325
+ # Or with flag
326
+ gravi login --mom-url=https://mom.dev
327
+ ```
328
+
329
+ ## Security
330
+
331
+ - **Refresh tokens** stored in config file with `0600` permissions
332
+ - **Access tokens** never persisted (in-memory only)
333
+ - **No tokens in CLI arguments** (prevents shell history exposure)
334
+ - **HTTPS only** for all API calls
335
+ - **Audit logging** - All token operations logged in mom
336
+
337
+ ## Support
338
+
339
+ For issues or questions:
340
+ - GitHub Issues: https://github.com/gravitate/mom/issues
341
+ - Internal Slack: #engineering
342
+
343
+ ## License
344
+
345
+ MIT