nocville 0.2.0__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.
- nocville-0.2.0/.gitignore +83 -0
- nocville-0.2.0/PKG-INFO +155 -0
- nocville-0.2.0/README.md +128 -0
- nocville-0.2.0/nocville/__init__.py +53 -0
- nocville-0.2.0/nocville/client.py +981 -0
- nocville-0.2.0/pyproject.toml +46 -0
- nocville-0.2.0/tests/test_client.py +152 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
.pnpm-store/
|
|
4
|
+
|
|
5
|
+
# Build outputs
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.next/
|
|
9
|
+
.next-*/
|
|
10
|
+
out/
|
|
11
|
+
|
|
12
|
+
# Environment files
|
|
13
|
+
.env
|
|
14
|
+
.env.local
|
|
15
|
+
.env.*.local
|
|
16
|
+
.env.production
|
|
17
|
+
.env.production.local
|
|
18
|
+
|
|
19
|
+
# IDE
|
|
20
|
+
.idea/
|
|
21
|
+
.vscode/
|
|
22
|
+
*.swp
|
|
23
|
+
*.swo
|
|
24
|
+
.DS_Store
|
|
25
|
+
|
|
26
|
+
# Logs
|
|
27
|
+
*.log
|
|
28
|
+
npm-debug.log*
|
|
29
|
+
pnpm-debug.log*
|
|
30
|
+
|
|
31
|
+
# Testing
|
|
32
|
+
coverage/
|
|
33
|
+
.nyc_output/
|
|
34
|
+
|
|
35
|
+
# TypeScript
|
|
36
|
+
*.tsbuildinfo
|
|
37
|
+
|
|
38
|
+
# Misc
|
|
39
|
+
*.pid
|
|
40
|
+
*.seed
|
|
41
|
+
*.pid.lock
|
|
42
|
+
|
|
43
|
+
# Database
|
|
44
|
+
*.sqlite
|
|
45
|
+
*.db
|
|
46
|
+
|
|
47
|
+
# Python SDKs
|
|
48
|
+
.pytest_cache/
|
|
49
|
+
__pycache__/
|
|
50
|
+
*.py[cod]
|
|
51
|
+
*$py.class
|
|
52
|
+
.Python
|
|
53
|
+
*.egg-info/
|
|
54
|
+
.eggs/
|
|
55
|
+
*.egg
|
|
56
|
+
.venv/
|
|
57
|
+
venv/
|
|
58
|
+
ENV/
|
|
59
|
+
|
|
60
|
+
# C++ SDKs
|
|
61
|
+
*.o
|
|
62
|
+
*.so
|
|
63
|
+
*.dylib
|
|
64
|
+
*.a
|
|
65
|
+
CMakeCache.txt
|
|
66
|
+
CMakeFiles/
|
|
67
|
+
cmake_install.cmake
|
|
68
|
+
Makefile
|
|
69
|
+
|
|
70
|
+
# Claude Code agent worktrees
|
|
71
|
+
.claude/worktrees/
|
|
72
|
+
.claude/settings.local.json
|
|
73
|
+
|
|
74
|
+
# Disposable manual-preview harnesses
|
|
75
|
+
apps/e2e/.local/
|
|
76
|
+
|
|
77
|
+
# Immutable production builds, static asset pool and deploy bookkeeping
|
|
78
|
+
apps/web/.next-releases/
|
|
79
|
+
apps/web/.next-live
|
|
80
|
+
apps/web/.next-live.tmp.*
|
|
81
|
+
apps/web/.next-static/
|
|
82
|
+
.deploy-lock/
|
|
83
|
+
.deploy-last-successful
|
nocville-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: nocville
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Nocville Status Pusher SDK for Python
|
|
5
|
+
Project-URL: Homepage, https://github.com/marshmansf/nocville
|
|
6
|
+
Project-URL: Documentation, https://github.com/marshmansf/nocville
|
|
7
|
+
Project-URL: Repository, https://github.com/marshmansf/nocville
|
|
8
|
+
Author: Nocville Team
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: monitoring,noc,nocville,status
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Requires-Dist: httpx>=0.24.0
|
|
21
|
+
Provides-Extra: async
|
|
22
|
+
Requires-Dist: aiohttp>=3.8.0; extra == 'async'
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.20.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# nocville
|
|
29
|
+
|
|
30
|
+
Python SDK for pushing status updates to Nocville.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install nocville
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For async support:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install nocville[async]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
### Synchronous
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from nocville import NocvilleClient, Status, Mood
|
|
50
|
+
|
|
51
|
+
client = NocvilleClient(
|
|
52
|
+
api_key="your-api-key",
|
|
53
|
+
service_id="my-service",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Push a status update
|
|
57
|
+
response = client.push_status(
|
|
58
|
+
status=Status.HEALTHY,
|
|
59
|
+
mood=Mood.HAPPY,
|
|
60
|
+
message="All systems operational",
|
|
61
|
+
metrics={"cpu": 45, "memory": 60},
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Quick helpers
|
|
65
|
+
client.healthy("Everything is fine")
|
|
66
|
+
client.warning("High memory usage")
|
|
67
|
+
client.critical("Service down!")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Asynchronous
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
import asyncio
|
|
74
|
+
from nocville.client import AsyncNocvilleClient, Status
|
|
75
|
+
|
|
76
|
+
async def main():
|
|
77
|
+
client = AsyncNocvilleClient(
|
|
78
|
+
api_url="https://your-nocville-server.com",
|
|
79
|
+
api_key="your-api-key",
|
|
80
|
+
service_id="my-service",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
response = await client.push_status(
|
|
84
|
+
status=Status.HEALTHY,
|
|
85
|
+
message="All systems operational",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
asyncio.run(main())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
| Option | Type | Default | Description |
|
|
94
|
+
| ------------- | ----- | ---------------------- | ------------------------------------------- |
|
|
95
|
+
| `api_key` | str | required | Team API key for authentication |
|
|
96
|
+
| `api_url` | str | `https://nocville.com` | Nocville API URL (override for development) |
|
|
97
|
+
| `service_id` | str | required | The service ID this client represents |
|
|
98
|
+
| `timeout` | float | 5.0 | Request timeout in seconds |
|
|
99
|
+
| `retries` | int | 3 | Number of retry attempts on failure |
|
|
100
|
+
| `retry_delay` | float | 1.0 | Base delay between retries in seconds |
|
|
101
|
+
| `debug` | bool | False | Enable debug logging |
|
|
102
|
+
|
|
103
|
+
## Status Values
|
|
104
|
+
|
|
105
|
+
- `Status.HEALTHY` - Service is operating normally
|
|
106
|
+
- `Status.WARNING` - Service has non-critical issues
|
|
107
|
+
- `Status.CRITICAL` - Service has critical issues
|
|
108
|
+
- `Status.UNKNOWN` - Service status cannot be determined
|
|
109
|
+
|
|
110
|
+
## Mood Values
|
|
111
|
+
|
|
112
|
+
- `Mood.HAPPY` - NPC appears happy
|
|
113
|
+
- `Mood.CONCERNED` - NPC appears concerned
|
|
114
|
+
- `Mood.STRESSED` - NPC appears stressed
|
|
115
|
+
- `Mood.IDLE` - NPC appears neutral
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT
|
|
120
|
+
|
|
121
|
+
## Maps, AI coworkers and shutdown
|
|
122
|
+
|
|
123
|
+
Both clients accept `map="Ops"` (map name or ID) and the same keyword-only status fields:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from nocville import NocvilleClient, BehaviorHints, CompanionSpec
|
|
127
|
+
|
|
128
|
+
client = NocvilleClient(api_key="your-api-key", service_id="build-agent", map="Ops")
|
|
129
|
+
behavior: BehaviorHints = {"activity": "busy", "busy": "seek-desk"}
|
|
130
|
+
companion: CompanionSpec = {
|
|
131
|
+
"screenType": "desk-sign",
|
|
132
|
+
"placement": "on-desk",
|
|
133
|
+
"size": {"w": 3, "h": 1},
|
|
134
|
+
"label": "checkout-api",
|
|
135
|
+
}
|
|
136
|
+
try:
|
|
137
|
+
client.push_status(
|
|
138
|
+
"healthy", name="Claude", message="Running tests",
|
|
139
|
+
behavior=behavior, companion=companion,
|
|
140
|
+
appearance={"family": "claude"},
|
|
141
|
+
agent_stats={"added": 12, "removed": 3},
|
|
142
|
+
)
|
|
143
|
+
finally:
|
|
144
|
+
client.shutdown()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`agent_stats` becomes `agentStats` on the wire. Behavior and companion dictionaries use
|
|
148
|
+
API camelCase keys. `offline=True` immediately removes the NPC. `shutdown()` stops and
|
|
149
|
+
drains heartbeats before sending an unknown/idle/offline sentinel, and returns a
|
|
150
|
+
`PushResponse`; use `await client.shutdown()` for `AsyncNocvilleClient`.
|
|
151
|
+
|
|
152
|
+
`auto_offline=True` opts into a best-effort interpreter-exit callback (default `False`).
|
|
153
|
+
For async clients this callback uses a synchronous request because the event loop may
|
|
154
|
+
already be closed. Prefer explicit shutdown in `finally`; exit callbacks cannot run after
|
|
155
|
+
SIGKILL or a crash. Python 3.9 or newer is required.
|
nocville-0.2.0/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# nocville
|
|
2
|
+
|
|
3
|
+
Python SDK for pushing status updates to Nocville.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install nocville
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For async support:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install nocville[async]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Synchronous
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from nocville import NocvilleClient, Status, Mood
|
|
23
|
+
|
|
24
|
+
client = NocvilleClient(
|
|
25
|
+
api_key="your-api-key",
|
|
26
|
+
service_id="my-service",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Push a status update
|
|
30
|
+
response = client.push_status(
|
|
31
|
+
status=Status.HEALTHY,
|
|
32
|
+
mood=Mood.HAPPY,
|
|
33
|
+
message="All systems operational",
|
|
34
|
+
metrics={"cpu": 45, "memory": 60},
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Quick helpers
|
|
38
|
+
client.healthy("Everything is fine")
|
|
39
|
+
client.warning("High memory usage")
|
|
40
|
+
client.critical("Service down!")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Asynchronous
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import asyncio
|
|
47
|
+
from nocville.client import AsyncNocvilleClient, Status
|
|
48
|
+
|
|
49
|
+
async def main():
|
|
50
|
+
client = AsyncNocvilleClient(
|
|
51
|
+
api_url="https://your-nocville-server.com",
|
|
52
|
+
api_key="your-api-key",
|
|
53
|
+
service_id="my-service",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
response = await client.push_status(
|
|
57
|
+
status=Status.HEALTHY,
|
|
58
|
+
message="All systems operational",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
asyncio.run(main())
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Configuration
|
|
65
|
+
|
|
66
|
+
| Option | Type | Default | Description |
|
|
67
|
+
| ------------- | ----- | ---------------------- | ------------------------------------------- |
|
|
68
|
+
| `api_key` | str | required | Team API key for authentication |
|
|
69
|
+
| `api_url` | str | `https://nocville.com` | Nocville API URL (override for development) |
|
|
70
|
+
| `service_id` | str | required | The service ID this client represents |
|
|
71
|
+
| `timeout` | float | 5.0 | Request timeout in seconds |
|
|
72
|
+
| `retries` | int | 3 | Number of retry attempts on failure |
|
|
73
|
+
| `retry_delay` | float | 1.0 | Base delay between retries in seconds |
|
|
74
|
+
| `debug` | bool | False | Enable debug logging |
|
|
75
|
+
|
|
76
|
+
## Status Values
|
|
77
|
+
|
|
78
|
+
- `Status.HEALTHY` - Service is operating normally
|
|
79
|
+
- `Status.WARNING` - Service has non-critical issues
|
|
80
|
+
- `Status.CRITICAL` - Service has critical issues
|
|
81
|
+
- `Status.UNKNOWN` - Service status cannot be determined
|
|
82
|
+
|
|
83
|
+
## Mood Values
|
|
84
|
+
|
|
85
|
+
- `Mood.HAPPY` - NPC appears happy
|
|
86
|
+
- `Mood.CONCERNED` - NPC appears concerned
|
|
87
|
+
- `Mood.STRESSED` - NPC appears stressed
|
|
88
|
+
- `Mood.IDLE` - NPC appears neutral
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT
|
|
93
|
+
|
|
94
|
+
## Maps, AI coworkers and shutdown
|
|
95
|
+
|
|
96
|
+
Both clients accept `map="Ops"` (map name or ID) and the same keyword-only status fields:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from nocville import NocvilleClient, BehaviorHints, CompanionSpec
|
|
100
|
+
|
|
101
|
+
client = NocvilleClient(api_key="your-api-key", service_id="build-agent", map="Ops")
|
|
102
|
+
behavior: BehaviorHints = {"activity": "busy", "busy": "seek-desk"}
|
|
103
|
+
companion: CompanionSpec = {
|
|
104
|
+
"screenType": "desk-sign",
|
|
105
|
+
"placement": "on-desk",
|
|
106
|
+
"size": {"w": 3, "h": 1},
|
|
107
|
+
"label": "checkout-api",
|
|
108
|
+
}
|
|
109
|
+
try:
|
|
110
|
+
client.push_status(
|
|
111
|
+
"healthy", name="Claude", message="Running tests",
|
|
112
|
+
behavior=behavior, companion=companion,
|
|
113
|
+
appearance={"family": "claude"},
|
|
114
|
+
agent_stats={"added": 12, "removed": 3},
|
|
115
|
+
)
|
|
116
|
+
finally:
|
|
117
|
+
client.shutdown()
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`agent_stats` becomes `agentStats` on the wire. Behavior and companion dictionaries use
|
|
121
|
+
API camelCase keys. `offline=True` immediately removes the NPC. `shutdown()` stops and
|
|
122
|
+
drains heartbeats before sending an unknown/idle/offline sentinel, and returns a
|
|
123
|
+
`PushResponse`; use `await client.shutdown()` for `AsyncNocvilleClient`.
|
|
124
|
+
|
|
125
|
+
`auto_offline=True` opts into a best-effort interpreter-exit callback (default `False`).
|
|
126
|
+
For async clients this callback uses a synchronous request because the event loop may
|
|
127
|
+
already be closed. Prefer explicit shutdown in `finally`; exit callbacks cannot run after
|
|
128
|
+
SIGKILL or a crash. Python 3.9 or newer is required.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Nocville Status Pusher SDK for Python
|
|
3
|
+
|
|
4
|
+
Example usage:
|
|
5
|
+
from nocville import NocvilleClient
|
|
6
|
+
|
|
7
|
+
client = NocvilleClient(
|
|
8
|
+
api_url="https://your-nocville-server.com",
|
|
9
|
+
api_key="your-api-key",
|
|
10
|
+
service_id="my-service",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Push a status update
|
|
14
|
+
client.push_status(
|
|
15
|
+
status="healthy",
|
|
16
|
+
mood="happy",
|
|
17
|
+
message="All systems operational",
|
|
18
|
+
metrics={"cpu": 45, "memory": 60},
|
|
19
|
+
)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from .client import (
|
|
23
|
+
NocvilleClient,
|
|
24
|
+
AsyncNocvilleClient,
|
|
25
|
+
Status,
|
|
26
|
+
Mood,
|
|
27
|
+
StatusUpdate,
|
|
28
|
+
PushResponse,
|
|
29
|
+
ScreenValue,
|
|
30
|
+
ScreenData,
|
|
31
|
+
NPCLink,
|
|
32
|
+
NPCAction,
|
|
33
|
+
AlertConfig,
|
|
34
|
+
BehaviorHints,
|
|
35
|
+
CompanionSpec,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"NocvilleClient",
|
|
40
|
+
"AsyncNocvilleClient",
|
|
41
|
+
"Status",
|
|
42
|
+
"Mood",
|
|
43
|
+
"StatusUpdate",
|
|
44
|
+
"PushResponse",
|
|
45
|
+
"ScreenValue",
|
|
46
|
+
"ScreenData",
|
|
47
|
+
"NPCLink",
|
|
48
|
+
"NPCAction",
|
|
49
|
+
"AlertConfig",
|
|
50
|
+
"BehaviorHints",
|
|
51
|
+
"CompanionSpec",
|
|
52
|
+
]
|
|
53
|
+
__version__ = "0.2.0"
|