mona-cli 0.1.0__py3-none-any.whl
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.
- mona/__init__.py +0 -0
- mona/cli.py +32 -0
- mona/config.py +14 -0
- mona/sync.py +78 -0
- mona/templates/example.toml +25 -0
- mona_cli-0.1.0.dist-info/METADATA +98 -0
- mona_cli-0.1.0.dist-info/RECORD +9 -0
- mona_cli-0.1.0.dist-info/WHEEL +4 -0
- mona_cli-0.1.0.dist-info/entry_points.txt +2 -0
mona/__init__.py
ADDED
|
File without changes
|
mona/cli.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# mona/cli.py
|
|
2
|
+
import click
|
|
3
|
+
from mona.sync import run_sync
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import shutil
|
|
6
|
+
|
|
7
|
+
TEMPLATE_PATH = Path(__file__).parent / "templates" / "example.toml"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@click.group()
|
|
11
|
+
def cli():
|
|
12
|
+
"""Mona – sync your local config to Lisa"""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@cli.command()
|
|
17
|
+
def sync():
|
|
18
|
+
"""Sync config variables across project"""
|
|
19
|
+
click.echo("...")
|
|
20
|
+
run_sync()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@cli.command()
|
|
24
|
+
def init():
|
|
25
|
+
"""Initialize a template"""
|
|
26
|
+
try:
|
|
27
|
+
open("lisa.toml", "x").close()
|
|
28
|
+
except FileExistsError:
|
|
29
|
+
raise SystemExit("lisa.toml already exists")
|
|
30
|
+
shutil.copy(TEMPLATE_PATH, "lisa.toml")
|
|
31
|
+
|
|
32
|
+
click.echo("created lisa.toml")
|
mona/config.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# mona/config.py
|
|
2
|
+
import os
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
|
|
5
|
+
load_dotenv()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
CONFIG_API = os.environ.get("LISA_CONFIG_API")
|
|
9
|
+
SERVER_URL = os.environ.get("LISA_SERVER_URL", "https://lisa-aopa.onrender.com")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def validate():
|
|
13
|
+
if not CONFIG_API:
|
|
14
|
+
raise EnvironmentError("LISA_CONFIG_API is not set in your .env file")
|
mona/sync.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# mona/sync.py
|
|
2
|
+
import tomllib
|
|
3
|
+
import json
|
|
4
|
+
import requests
|
|
5
|
+
from mona.config import CONFIG_API, SERVER_URL, validate
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _infer_type(value) -> str:
|
|
9
|
+
if isinstance(value, bool):
|
|
10
|
+
return "boolean"
|
|
11
|
+
if isinstance(value, int) or isinstance(value, float):
|
|
12
|
+
return "number"
|
|
13
|
+
if isinstance(value, dict):
|
|
14
|
+
return "json"
|
|
15
|
+
return "string"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _serialize_value(value) -> str:
|
|
19
|
+
if isinstance(value, bool):
|
|
20
|
+
return "true" if value else "false"
|
|
21
|
+
if isinstance(value, dict):
|
|
22
|
+
return json.dumps(value)
|
|
23
|
+
return str(value)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _prepare_payload(data: dict) -> dict:
|
|
27
|
+
return {
|
|
28
|
+
key: {
|
|
29
|
+
"value": _serialize_value(val),
|
|
30
|
+
"value_type": _infer_type(val),
|
|
31
|
+
}
|
|
32
|
+
for key, val in data.items()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def run_sync():
|
|
37
|
+
validate()
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
with open("lisa.toml", "rb") as f:
|
|
41
|
+
data = tomllib.load(f)
|
|
42
|
+
except FileNotFoundError:
|
|
43
|
+
raise SystemExit("lisa.toml not found — run `mona init` first")
|
|
44
|
+
|
|
45
|
+
url = f"{SERVER_URL}/sync/{CONFIG_API}"
|
|
46
|
+
response = requests.post(url, json=_prepare_payload(data))
|
|
47
|
+
|
|
48
|
+
if response.status_code != 200:
|
|
49
|
+
raise SystemExit(f"Server error {response.status_code}: {response.text}")
|
|
50
|
+
|
|
51
|
+
_print_diff(response.json())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _print_diff(result: dict):
|
|
55
|
+
added = result.get("added", [])
|
|
56
|
+
updated = result.get("updated", [])
|
|
57
|
+
removed = result.get("deleted", [])
|
|
58
|
+
|
|
59
|
+
if not any([added, updated, removed]):
|
|
60
|
+
print("already in sync, no changes made")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
if added:
|
|
64
|
+
print(f"\n added ({len(added)})")
|
|
65
|
+
for key in added:
|
|
66
|
+
print(f" + {key}")
|
|
67
|
+
|
|
68
|
+
if updated:
|
|
69
|
+
print(f"\n updated ({len(updated)})")
|
|
70
|
+
for key in updated:
|
|
71
|
+
print(f" ~ {key}")
|
|
72
|
+
|
|
73
|
+
if removed:
|
|
74
|
+
print(f"\n removed ({len(removed)})")
|
|
75
|
+
for key in removed:
|
|
76
|
+
print(f" - {key}")
|
|
77
|
+
|
|
78
|
+
print()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# lisa.toml
|
|
2
|
+
# to sync with lisa run 'mona sync'
|
|
3
|
+
# supported types: string, int, float, bool, inline table (json)
|
|
4
|
+
|
|
5
|
+
string_param = "hi"
|
|
6
|
+
float_param = 0.0
|
|
7
|
+
bool_param = true
|
|
8
|
+
|
|
9
|
+
json_param = {
|
|
10
|
+
"key": "value"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
# nested tables resolve to nested json
|
|
14
|
+
# the code below is the same as
|
|
15
|
+
# nested_table = {
|
|
16
|
+
# shallow_level = 1,
|
|
17
|
+
# deeper_nest = {
|
|
18
|
+
# deep_level = 2
|
|
19
|
+
# }
|
|
20
|
+
# }
|
|
21
|
+
# are the same things
|
|
22
|
+
[nested_table]
|
|
23
|
+
shallow_level = "top"
|
|
24
|
+
[deeper_nest]
|
|
25
|
+
deep_level = "deep"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mona-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI tool for syncing local config files to a Lisa remote config server
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
|
+
Requires-Dist: click>=8.3.1
|
|
7
|
+
Requires-Dist: python-dotenv>=1.2.2
|
|
8
|
+
Requires-Dist: requests>=2.32.5
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# Mona cli
|
|
12
|
+
Mona is the cli-interface for configuring your lisa projects
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- Initialize configuration templates for new projects
|
|
19
|
+
- Sync remote config variables with lisa
|
|
20
|
+
- Works with `.env` files via python-dotenv
|
|
21
|
+
- Simple CLI interface built with Click
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Once published to PyPI:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install mona-cli
|
|
31
|
+
````
|
|
32
|
+
|
|
33
|
+
Using uv:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv pip install mona-cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
After installation, the `mona` command is available on the system PATH.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mona --help
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Expected output:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
Usage: mona [OPTIONS] COMMAND [ARGS]...
|
|
53
|
+
|
|
54
|
+
Mona – sync your local config to Lisa
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
--help Show this message and exit.
|
|
58
|
+
|
|
59
|
+
Commands:
|
|
60
|
+
init Initialize a template
|
|
61
|
+
sync Sync config variables across project
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
### mona init
|
|
68
|
+
|
|
69
|
+
Initializes a configuration template in the current project.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
mona init
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### mona sync
|
|
76
|
+
|
|
77
|
+
Synchronizes local configuration values with the Lisa remote configuration server.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
mona sync
|
|
81
|
+
```
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Configuration
|
|
85
|
+
|
|
86
|
+
Mona requires your project config_api\
|
|
87
|
+
To generate a project run
|
|
88
|
+
```bash
|
|
89
|
+
curl -X POST https://lisa-aopa.onrender.com/create/<project_name>
|
|
90
|
+
```
|
|
91
|
+
and copy the returned client and config apis to a safe place as they\
|
|
92
|
+
will not be displayed again
|
|
93
|
+
|
|
94
|
+
```env
|
|
95
|
+
LISA_CONFIG_URL=https://config.example.com
|
|
96
|
+
```
|
|
97
|
+
Environment variables are loaded automatically using python-dotenv.
|
|
98
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
mona/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mona/cli.py,sha256=GNTNvQN-Wj18YCHoIkDQ_6qYwnwyA2NVo6kV0UQurvg,638
|
|
3
|
+
mona/config.py,sha256=6BpBfAmZC8THlHhjkeKwhWmZOYUGrvJtr7K2aHL9qOA,323
|
|
4
|
+
mona/sync.py,sha256=v5YkQx-Xkvwwt795tKNaO3mKBppbGpZoaNjsZcj0Sv0,1903
|
|
5
|
+
mona/templates/example.toml,sha256=4ROx4t0eDwPg_jvGABwN_uFWAPayjMa0FMgY1HsUwwE,465
|
|
6
|
+
mona_cli-0.1.0.dist-info/METADATA,sha256=y1WAErxoEgr6ZYgchPXOJyGYVXjhuGxZkFpigraD3M0,1679
|
|
7
|
+
mona_cli-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
8
|
+
mona_cli-0.1.0.dist-info/entry_points.txt,sha256=at1VJVOQf9WVzx71NHkPTF5_zkXDJhHrTCaTrMDkAF4,38
|
|
9
|
+
mona_cli-0.1.0.dist-info/RECORD,,
|