codex-db-sdk 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.
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codex-db-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Codex DB Python SDK
|
|
5
|
+
Author: Your Name
|
|
6
|
+
Author-email: Your Name <your.email@example.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/evertonmj/codex
|
|
9
|
+
Requires-Python: >=3.7
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Dynamic: author
|
|
12
|
+
Dynamic: requires-python
|
|
13
|
+
|
|
14
|
+
# CodexDB Python SDK
|
|
15
|
+
|
|
16
|
+
Python SDK for CodexDB. Simple wrapper for `codex-cli` as an external process.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install via pip (from local directory):
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
pip install .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or, for development:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage Example
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from codex_sdk import CodexClient
|
|
36
|
+
|
|
37
|
+
client = CodexClient(file='test.db')
|
|
38
|
+
client.set('user:1', {'name': 'Alice', 'age': 30})
|
|
39
|
+
print(client.get('user:1'))
|
|
40
|
+
print(client.keys())
|
|
41
|
+
client.delete('user:1')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Requirements
|
|
45
|
+
|
|
46
|
+
- Python 3.7+
|
|
47
|
+
- `codex-cli` binary available in your PATH
|
|
48
|
+
|
|
49
|
+
## Publishing to PyPI
|
|
50
|
+
|
|
51
|
+
To publish this package to PyPI:
|
|
52
|
+
|
|
53
|
+
1. Install build and twine:
|
|
54
|
+
```sh
|
|
55
|
+
pip install build twine
|
|
56
|
+
```
|
|
57
|
+
2. Build the package:
|
|
58
|
+
```sh
|
|
59
|
+
python -m build
|
|
60
|
+
```
|
|
61
|
+
3. Upload to PyPI:
|
|
62
|
+
```sh
|
|
63
|
+
twine upload dist/*
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For test uploads, use `https://test.pypi.org/legacy/` with twine's `--repository testpypi` option.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
codex_sdk/__init__.py,sha256=JNBnV25-TS76EYAgLbBoIE6x9yS0zC2P_gacMAduQxc,50
|
|
2
|
+
codex_sdk/codex_sdk.py,sha256=Rt6iITq_j-jU5i0ZSzf3mxdArw8zER-tx0FqckV20oo,1805
|
|
3
|
+
codex_db_sdk-0.1.0.dist-info/METADATA,sha256=ECb-mVupHFg4wUqdkorhMYmk3Ul17fFNgBJDLCDs3tE,1193
|
|
4
|
+
codex_db_sdk-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
codex_db_sdk-0.1.0.dist-info/top_level.txt,sha256=jTG0iUnUWgyVsPWOCnjzSsYCUjyr3R8e9WH6Ce5oEEc,10
|
|
6
|
+
codex_db_sdk-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
codex_sdk
|
codex_sdk/__init__.py
ADDED
codex_sdk/codex_sdk.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import shutil
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CodexClient:
|
|
7
|
+
def __init__(self, file, cli_path='codex-cli', ledger=False, encryption_key=None):
|
|
8
|
+
if not file:
|
|
9
|
+
raise ValueError('file is required')
|
|
10
|
+
|
|
11
|
+
if shutil.which(cli_path) is None:
|
|
12
|
+
raise FileNotFoundError(f"codex-cli not found at '{cli_path}' in PATH")
|
|
13
|
+
|
|
14
|
+
self.cli_path = cli_path
|
|
15
|
+
self.file = file
|
|
16
|
+
self.ledger = ledger
|
|
17
|
+
self.env = None
|
|
18
|
+
|
|
19
|
+
if encryption_key is not None:
|
|
20
|
+
self.env = dict(**__import__('os').environ)
|
|
21
|
+
self.env['CODEX_KEY'] = encryption_key
|
|
22
|
+
|
|
23
|
+
def _base_args(self):
|
|
24
|
+
args = ['--file', self.file]
|
|
25
|
+
if self.ledger:
|
|
26
|
+
args.append('--ledger')
|
|
27
|
+
return args
|
|
28
|
+
|
|
29
|
+
def _run(self, *cmd_args):
|
|
30
|
+
args = [self.cli_path, *self._base_args(), *cmd_args]
|
|
31
|
+
cp = subprocess.run(args, capture_output=True, text=True, env=self.env)
|
|
32
|
+
if cp.returncode != 0:
|
|
33
|
+
raise RuntimeError(cp.stderr.strip() or cp.stdout.strip() or f'codex-cli failed ({cp.returncode})')
|
|
34
|
+
return cp.stdout.strip()
|
|
35
|
+
|
|
36
|
+
def set(self, key, value):
|
|
37
|
+
payload = json.dumps(value, ensure_ascii=False)
|
|
38
|
+
self._run('set', key, payload)
|
|
39
|
+
return True
|
|
40
|
+
|
|
41
|
+
def get(self, key):
|
|
42
|
+
raw = self._run('get', key)
|
|
43
|
+
if raw == 'null' or raw == '':
|
|
44
|
+
return None
|
|
45
|
+
return json.loads(raw)
|
|
46
|
+
|
|
47
|
+
def delete(self, key):
|
|
48
|
+
self._run('delete', key)
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
def keys(self):
|
|
52
|
+
raw = self._run('keys')
|
|
53
|
+
if not raw:
|
|
54
|
+
return []
|
|
55
|
+
return [k for k in raw.split('\n') if k]
|
|
56
|
+
|
|
57
|
+
def has(self, key):
|
|
58
|
+
raw = self._run('has', key)
|
|
59
|
+
return raw.strip().lower() == 'true'
|
|
60
|
+
|
|
61
|
+
def clear(self):
|
|
62
|
+
self._run('clear')
|
|
63
|
+
return True
|