leap-bundle 0.0.1a1__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.
- leap_bundle-0.0.1a1/.gitignore +203 -0
- leap_bundle-0.0.1a1/PKG-INFO +89 -0
- leap_bundle-0.0.1a1/README.md +61 -0
- leap_bundle-0.0.1a1/package.json +25 -0
- leap_bundle-0.0.1a1/pyproject.toml +103 -0
- leap_bundle-0.0.1a1/src/leap_bundle/__init__.py +1 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/__init__.py +0 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/auth.py +112 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/cancel.py +35 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/config.py +31 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/create.py +87 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/download.py +78 -0
- leap_bundle-0.0.1a1/src/leap_bundle/commands/list.py +73 -0
- leap_bundle-0.0.1a1/src/leap_bundle/main.py +68 -0
- leap_bundle-0.0.1a1/src/leap_bundle/utils/__init__.py +1 -0
- leap_bundle-0.0.1a1/src/leap_bundle/utils/api_client.py +211 -0
- leap_bundle-0.0.1a1/src/leap_bundle/utils/config.py +98 -0
- leap_bundle-0.0.1a1/src/leap_bundle/utils/hash.py +31 -0
- leap_bundle-0.0.1a1/tests/__init__.py +1 -0
- leap_bundle-0.0.1a1/tests/commands/__init__.py +0 -0
- leap_bundle-0.0.1a1/tests/commands/test_auth.py +133 -0
- leap_bundle-0.0.1a1/tests/commands/test_config.py +59 -0
- leap_bundle-0.0.1a1/tests/test_main.py +42 -0
- leap_bundle-0.0.1a1/uv.lock +952 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
#poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
#pdm.lock
|
|
116
|
+
#pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
#pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.envrc
|
|
140
|
+
.venv
|
|
141
|
+
env/
|
|
142
|
+
venv/
|
|
143
|
+
ENV/
|
|
144
|
+
env.bak/
|
|
145
|
+
venv.bak/
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
#.idea/
|
|
177
|
+
|
|
178
|
+
# Abstra
|
|
179
|
+
# Abstra is an AI-powered process automation framework.
|
|
180
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
181
|
+
# Learn more at https://abstra.io/docs
|
|
182
|
+
.abstra/
|
|
183
|
+
|
|
184
|
+
# Visual Studio Code
|
|
185
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
186
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
188
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
189
|
+
# .vscode/
|
|
190
|
+
|
|
191
|
+
# Ruff stuff:
|
|
192
|
+
.ruff_cache/
|
|
193
|
+
|
|
194
|
+
# PyPI configuration file
|
|
195
|
+
.pypirc
|
|
196
|
+
|
|
197
|
+
# Marimo
|
|
198
|
+
marimo/_static/
|
|
199
|
+
marimo/_lsp/
|
|
200
|
+
__marimo__/
|
|
201
|
+
|
|
202
|
+
# Streamlit
|
|
203
|
+
.streamlit/secrets.toml
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: leap-bundle
|
|
3
|
+
Version: 0.0.1a1
|
|
4
|
+
Summary: Command line interface for Liquid Edge AI Platform (LEAP)
|
|
5
|
+
Project-URL: Homepage, https://leap.liquid.ai
|
|
6
|
+
Author-email: Liquid AI <leap@liquid.ai>
|
|
7
|
+
License: LFM Open License v1.0
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: Other/Proprietary License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
19
|
+
Requires-Dist: requests>=2.31.0
|
|
20
|
+
Requires-Dist: rich>=13.0.0
|
|
21
|
+
Requires-Dist: typer>=0.9.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# leap-bundle
|
|
30
|
+
|
|
31
|
+
Command line interface for Liquid Edge AI Platform (LEAP).
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install leap-bundle
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
| Command | Description |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `leap-bundle login <api-token>` | Authenticate with LEAP using API token |
|
|
44
|
+
| `leap-bundle whoami` | Show current authenticated user |
|
|
45
|
+
| `leap-bundle logout` | Logout from LEAP |
|
|
46
|
+
| `leap-bundle config` | Show current configuration |
|
|
47
|
+
| `leap-bundle config --server <url>` | Set server URL (default: https://leap.liquid.ai) |
|
|
48
|
+
| `leap-bundle create` | Submit new bundle request |
|
|
49
|
+
| `leap-bundle list` | List all bundle requests |
|
|
50
|
+
| `leap-bundle list <request-id>` | Show details of a specific request |
|
|
51
|
+
| `leap-bundle cancel <request-id>` | Cancel a bundle request |
|
|
52
|
+
| `leap-bundle download <request-id>` | Download the bundle file for a specific request |
|
|
53
|
+
|
|
54
|
+
## Development
|
|
55
|
+
|
|
56
|
+
This package uses `uv` for dependency management.
|
|
57
|
+
|
|
58
|
+
### Setup
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Install uv if you haven't already
|
|
62
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
63
|
+
|
|
64
|
+
# Install dependencies
|
|
65
|
+
uv sync --dev
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Development Commands
|
|
69
|
+
|
|
70
|
+
| `uv` command | `npm` command | Description |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `uv run ruff check .` | `npm run lint` | Run code linting |
|
|
73
|
+
| `uv run ruff format .` | `npm run format` | Format code using ruff |
|
|
74
|
+
| `uv run mypy .` | `npm run typecheck` | Run type checking with mypy |
|
|
75
|
+
| `uv run pytest` | `npm run test` | Run tests using pytest |
|
|
76
|
+
| | `npm run check` | Run all above checks |
|
|
77
|
+
|
|
78
|
+
### Local Development
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Install the package in virtual environment
|
|
82
|
+
uv pip install -e .
|
|
83
|
+
|
|
84
|
+
# Run the CLI
|
|
85
|
+
uv run leap-bundle --help
|
|
86
|
+
# Or activate the virtual environment and run directly
|
|
87
|
+
source .venv/bin/activate
|
|
88
|
+
leap-bundle --help
|
|
89
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# leap-bundle
|
|
2
|
+
|
|
3
|
+
Command line interface for Liquid Edge AI Platform (LEAP).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install leap-bundle
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
| Command | Description |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `leap-bundle login <api-token>` | Authenticate with LEAP using API token |
|
|
16
|
+
| `leap-bundle whoami` | Show current authenticated user |
|
|
17
|
+
| `leap-bundle logout` | Logout from LEAP |
|
|
18
|
+
| `leap-bundle config` | Show current configuration |
|
|
19
|
+
| `leap-bundle config --server <url>` | Set server URL (default: https://leap.liquid.ai) |
|
|
20
|
+
| `leap-bundle create` | Submit new bundle request |
|
|
21
|
+
| `leap-bundle list` | List all bundle requests |
|
|
22
|
+
| `leap-bundle list <request-id>` | Show details of a specific request |
|
|
23
|
+
| `leap-bundle cancel <request-id>` | Cancel a bundle request |
|
|
24
|
+
| `leap-bundle download <request-id>` | Download the bundle file for a specific request |
|
|
25
|
+
|
|
26
|
+
## Development
|
|
27
|
+
|
|
28
|
+
This package uses `uv` for dependency management.
|
|
29
|
+
|
|
30
|
+
### Setup
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Install uv if you haven't already
|
|
34
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
35
|
+
|
|
36
|
+
# Install dependencies
|
|
37
|
+
uv sync --dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Development Commands
|
|
41
|
+
|
|
42
|
+
| `uv` command | `npm` command | Description |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| `uv run ruff check .` | `npm run lint` | Run code linting |
|
|
45
|
+
| `uv run ruff format .` | `npm run format` | Format code using ruff |
|
|
46
|
+
| `uv run mypy .` | `npm run typecheck` | Run type checking with mypy |
|
|
47
|
+
| `uv run pytest` | `npm run test` | Run tests using pytest |
|
|
48
|
+
| | `npm run check` | Run all above checks |
|
|
49
|
+
|
|
50
|
+
### Local Development
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Install the package in virtual environment
|
|
54
|
+
uv pip install -e .
|
|
55
|
+
|
|
56
|
+
# Run the CLI
|
|
57
|
+
uv run leap-bundle --help
|
|
58
|
+
# Or activate the virtual environment and run directly
|
|
59
|
+
source .venv/bin/activate
|
|
60
|
+
leap-bundle --help
|
|
61
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liquidai/leap-bundle-py",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Command line interface for LEAP platform",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"leap",
|
|
8
|
+
"cli",
|
|
9
|
+
"ai",
|
|
10
|
+
"platform"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "uv build",
|
|
14
|
+
"check": "npm run lint && npm run format:check && npm run typecheck && npm run test",
|
|
15
|
+
"clean": "rm -rf dist/ .coverage htmlcov/ .pytest_cache/ .mypy_cache/ .ruff_cache/",
|
|
16
|
+
"format": "uv run ruff format .",
|
|
17
|
+
"format:check": "uv run ruff format --check .",
|
|
18
|
+
"install:dev": "uv sync --dev",
|
|
19
|
+
"lint": "uv run ruff check .",
|
|
20
|
+
"lint:fix": "uv run ruff check --fix .",
|
|
21
|
+
"test": "uv run pytest",
|
|
22
|
+
"test:cov": "uv run pytest --cov=leap_bundle --cov-report=term-missing",
|
|
23
|
+
"typecheck": "uv run mypy ."
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "leap-bundle"
|
|
7
|
+
version = "0.0.1-alpha.1"
|
|
8
|
+
description = "Command line interface for Liquid Edge AI Platform (LEAP)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "LFM Open License v1.0"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Liquid AI", email = "leap@liquid.ai"},
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: Other/Proprietary License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.8",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
]
|
|
25
|
+
requires-python = ">=3.8"
|
|
26
|
+
dependencies = [
|
|
27
|
+
"typer>=0.9.0",
|
|
28
|
+
"rich>=13.0.0",
|
|
29
|
+
"pyyaml>=6.0.0",
|
|
30
|
+
"requests>=2.31.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = [
|
|
35
|
+
"ruff>=0.1.0",
|
|
36
|
+
"mypy>=1.0.0",
|
|
37
|
+
"pytest>=7.0.0",
|
|
38
|
+
"pytest-cov>=4.0.0",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.scripts]
|
|
42
|
+
leap-bundle = "leap_bundle.main:app"
|
|
43
|
+
|
|
44
|
+
[project.urls]
|
|
45
|
+
Homepage = "https://leap.liquid.ai"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/leap_bundle"]
|
|
49
|
+
|
|
50
|
+
[tool.ruff]
|
|
51
|
+
target-version = "py38"
|
|
52
|
+
line-length = 88
|
|
53
|
+
|
|
54
|
+
[tool.ruff.lint]
|
|
55
|
+
select = [
|
|
56
|
+
"E", # pycodestyle errors
|
|
57
|
+
"W", # pycodestyle warnings
|
|
58
|
+
"F", # pyflakes
|
|
59
|
+
"I", # isort
|
|
60
|
+
"B", # flake8-bugbear
|
|
61
|
+
"C4", # flake8-comprehensions
|
|
62
|
+
"UP", # pyupgrade
|
|
63
|
+
]
|
|
64
|
+
ignore = [
|
|
65
|
+
"E501", # line too long, handled by black
|
|
66
|
+
"B008", # do not perform function calls in argument defaults
|
|
67
|
+
"C901", # too complex
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.ruff.format]
|
|
71
|
+
quote-style = "double"
|
|
72
|
+
indent-style = "space"
|
|
73
|
+
skip-magic-trailing-comma = false
|
|
74
|
+
line-ending = "auto"
|
|
75
|
+
|
|
76
|
+
[tool.mypy]
|
|
77
|
+
python_version = "3.9"
|
|
78
|
+
check_untyped_defs = true
|
|
79
|
+
disallow_any_generics = true
|
|
80
|
+
disallow_incomplete_defs = true
|
|
81
|
+
disallow_untyped_defs = true
|
|
82
|
+
no_implicit_optional = true
|
|
83
|
+
warn_redundant_casts = true
|
|
84
|
+
warn_unused_ignores = true
|
|
85
|
+
warn_return_any = true
|
|
86
|
+
strict_equality = true
|
|
87
|
+
|
|
88
|
+
[tool.pytest.ini_options]
|
|
89
|
+
testpaths = ["tests"]
|
|
90
|
+
python_files = ["test_*.py"]
|
|
91
|
+
python_classes = ["Test*"]
|
|
92
|
+
python_functions = ["test_*"]
|
|
93
|
+
addopts = "--cov=leap_bundle --cov-report=term-missing --cov-report=html"
|
|
94
|
+
|
|
95
|
+
[dependency-groups]
|
|
96
|
+
dev = [
|
|
97
|
+
"mypy>=1.14.1",
|
|
98
|
+
"pytest>=8.3.5",
|
|
99
|
+
"pytest-cov>=5.0.0",
|
|
100
|
+
"ruff>=0.12.3",
|
|
101
|
+
"types-pyyaml>=6.0.12.20241230",
|
|
102
|
+
"types-requests>=2.32.0.20241016",
|
|
103
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.1"
|
|
File without changes
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Authentication commands for LEAP CLI."""
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
import typer
|
|
5
|
+
from rich.console import Console
|
|
6
|
+
|
|
7
|
+
from leap_bundle.utils.config import (
|
|
8
|
+
clear_api_token,
|
|
9
|
+
get_api_token,
|
|
10
|
+
get_server_url,
|
|
11
|
+
is_logged_in,
|
|
12
|
+
set_api_token,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
console = Console()
|
|
16
|
+
app = typer.Typer()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def validate_api_token(token: str) -> bool:
|
|
20
|
+
"""Validate API token with the LEAP platform."""
|
|
21
|
+
try:
|
|
22
|
+
server_url = get_server_url()
|
|
23
|
+
api_url = f"{server_url.rstrip('/')}/api/cli/login"
|
|
24
|
+
response = requests.post(api_url, json={"api_token": token}, timeout=10)
|
|
25
|
+
return response.status_code == 200
|
|
26
|
+
except requests.RequestException as e:
|
|
27
|
+
console.print(f"[red]✗[/red] Failed to validate API token: {e}")
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.command("login")
|
|
32
|
+
def login(
|
|
33
|
+
api_token: str = typer.Argument(..., help="API token for LEAP platform"),
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Login to LEAP platform."""
|
|
36
|
+
if is_logged_in():
|
|
37
|
+
console.print(
|
|
38
|
+
"[yellow]⚠[/yellow] You are already logged in. "
|
|
39
|
+
"Run 'leap-bundle logout' first if you want to change your token."
|
|
40
|
+
)
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
console.print("[blue]ℹ[/blue] Validating API token...")
|
|
44
|
+
if not validate_api_token(api_token):
|
|
45
|
+
console.print(
|
|
46
|
+
"[red]✗[/red] Invalid API token. Please check your token and try again."
|
|
47
|
+
)
|
|
48
|
+
raise typer.Exit(1)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
set_api_token(api_token)
|
|
52
|
+
console.print("[green]✓[/green] Successfully logged in to LEAP platform!")
|
|
53
|
+
except Exception as e:
|
|
54
|
+
console.print(f"[red]✗[/red] Failed to save login credentials: {e}")
|
|
55
|
+
raise typer.Exit(1) from None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@app.command("logout")
|
|
59
|
+
def logout() -> None:
|
|
60
|
+
"""Logout from LEAP platform."""
|
|
61
|
+
if not is_logged_in():
|
|
62
|
+
console.print("[blue]ℹ[/blue] You are not currently logged in.")
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
clear_api_token()
|
|
67
|
+
console.print("[green]✓[/green] Successfully logged out from LEAP platform!")
|
|
68
|
+
except Exception as e:
|
|
69
|
+
console.print(f"[red]✗[/red] Failed to clear login credentials: {e}")
|
|
70
|
+
raise typer.Exit(1) from None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@app.command("whoami")
|
|
74
|
+
def whoami() -> None:
|
|
75
|
+
"""Show current user information."""
|
|
76
|
+
if not is_logged_in():
|
|
77
|
+
console.print(
|
|
78
|
+
"[red]✗[/red] You are not logged in. Run 'leap-bundle login' first."
|
|
79
|
+
)
|
|
80
|
+
raise typer.Exit(1)
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
api_token = get_api_token()
|
|
84
|
+
server_url = get_server_url()
|
|
85
|
+
api_url = f"{server_url.rstrip('/')}/api/cli/whoami"
|
|
86
|
+
|
|
87
|
+
response = requests.get(
|
|
88
|
+
api_url, headers={"Authorization": f"Bearer {api_token}"}, timeout=10
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if response.status_code == 200:
|
|
92
|
+
data = response.json()
|
|
93
|
+
console.print(f"[green]✓[/green] Logged in as: {data['email']}")
|
|
94
|
+
else:
|
|
95
|
+
error_data = (
|
|
96
|
+
response.json()
|
|
97
|
+
if response.headers.get("content-type", "").startswith(
|
|
98
|
+
"application/json"
|
|
99
|
+
)
|
|
100
|
+
else {}
|
|
101
|
+
)
|
|
102
|
+
error_message = error_data.get("error", "Failed to get user information")
|
|
103
|
+
console.print(f"[red]✗[/red] {error_message}")
|
|
104
|
+
raise typer.Exit(1)
|
|
105
|
+
except requests.RequestException as e:
|
|
106
|
+
console.print(f"[red]✗[/red] Failed to connect to server: {e}")
|
|
107
|
+
raise typer.Exit(1) from None
|
|
108
|
+
except typer.Exit:
|
|
109
|
+
raise # Re-raise typer.Exit without handling it
|
|
110
|
+
except Exception as e:
|
|
111
|
+
console.print(f"[red]✗[/red] Unexpected error: {e}")
|
|
112
|
+
raise typer.Exit(1) from None
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Cancel command for bundle requests."""
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
|
|
6
|
+
from leap_bundle.utils.api_client import APIClient
|
|
7
|
+
from leap_bundle.utils.config import is_logged_in
|
|
8
|
+
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def cancel(
|
|
13
|
+
request_id: str = typer.Argument(..., help="Bundle request ID to cancel"),
|
|
14
|
+
) -> None:
|
|
15
|
+
"""Cancel a bundle request."""
|
|
16
|
+
|
|
17
|
+
if not is_logged_in():
|
|
18
|
+
console.print(
|
|
19
|
+
"[red]✗[/red] You must be logged in. Run 'leap-bundle login' first."
|
|
20
|
+
)
|
|
21
|
+
raise typer.Exit(1)
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
client = APIClient()
|
|
25
|
+
console.print(f"[blue]ℹ[/blue] Cancelling bundle request {request_id}...")
|
|
26
|
+
|
|
27
|
+
result = client.cancel_bundle_request(request_id)
|
|
28
|
+
message = result.get("message", "Request cancelled successfully.")
|
|
29
|
+
|
|
30
|
+
console.print(f"[green]✓[/green] {message}")
|
|
31
|
+
|
|
32
|
+
except Exception as e:
|
|
33
|
+
from leap_bundle.utils.api_client import handle_cli_exception
|
|
34
|
+
|
|
35
|
+
handle_cli_exception(e)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Configuration commands for LEAP CLI."""
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
|
|
6
|
+
from leap_bundle.utils.config import get_config_file_path, load_config, set_server_url
|
|
7
|
+
|
|
8
|
+
console = Console()
|
|
9
|
+
app = typer.Typer()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("config")
|
|
13
|
+
def config(
|
|
14
|
+
server: str = typer.Option(None, "--server", help="Set the server URL"),
|
|
15
|
+
) -> None:
|
|
16
|
+
"""Configure LEAP CLI settings."""
|
|
17
|
+
if server:
|
|
18
|
+
set_server_url(server)
|
|
19
|
+
console.print(f"[green]✓[/green] Server URL set to: {server}")
|
|
20
|
+
else:
|
|
21
|
+
config_path = get_config_file_path()
|
|
22
|
+
console.print(f"[blue]ℹ[/blue] Config file location: {config_path}")
|
|
23
|
+
|
|
24
|
+
config_data = load_config()
|
|
25
|
+
if config_data:
|
|
26
|
+
console.print("\n[blue]Current configuration:[/blue]")
|
|
27
|
+
for key, value in config_data.items():
|
|
28
|
+
if key != "api_token":
|
|
29
|
+
console.print(f" {key}: {value}")
|
|
30
|
+
else:
|
|
31
|
+
console.print("\n[yellow]No configuration found.[/yellow]")
|