PyObservability 1.0.1__py3-none-any.whl → 1.2.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.
@@ -1,167 +1,208 @@
1
1
  <!doctype html>
2
2
  <html lang="en">
3
3
  <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width,initial-scale=1" />
6
- <title>Node Monitor — Single Node View</title>
7
-
8
- <link rel="stylesheet" href="/static/styles.css" />
9
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5
+ <title>PyObservability Node Monitor</title>
6
+ <meta property="og:type" content="CommandRunner">
7
+ <meta name="keywords" content="Python, Monitor, fastapi, JavaScript, HTML, CSS">
8
+ <meta name="author" content="Vignesh Rao">
9
+ <!-- Favicon.ico and Apple Touch Icon -->
10
+ <link property="og:image" rel="icon" href="https://thevickypedia.github.io/open-source/images/logo/pyninja.ico">
11
+ <link property="og:image" rel="apple-touch-icon"
12
+ href="https://thevickypedia.github.io/open-source/images/logo/pyninja.png">
13
+ <meta content="width=device-width, initial-scale=1" name="viewport">
14
+
15
+ <link rel="stylesheet" href="/static/styles.css"/>
16
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
17
  </head>
11
18
  <body>
12
- <header class="topbar">
19
+ <header class="topbar">
13
20
  <div class="brand">Node Monitor</div>
14
21
 
15
22
  <div class="controls">
16
- <label for="node-select">Node:</label>
17
- <select id="node-select" aria-label="Select node"></select>
18
- <button id="refresh-btn" title="Force refresh">Refresh</button>
23
+ <label for="node-select">Node:</label>
24
+ <select id="node-select" aria-label="Select node"></select>
25
+ <button id="refresh-btn" title="Force refresh">Refresh</button>
26
+ <button id="logout" title="Logout" onclick="logout()">Logout</button>
19
27
  </div>
20
- </header>
28
+ </header>
21
29
 
22
- <main class="container">
30
+ <main class="container">
23
31
  <section class="meta-row">
24
- <div class="meta-card">
25
- <div class="meta-title">System</div>
26
- <div id="system" class="meta-value pre"></div>
27
- </div>
28
-
29
- <div class="meta-card">
30
- <div class="meta-title">IP</div>
31
- <div id="ip-info" class="meta-value pre"></div>
32
- </div>
33
-
34
- <div class="meta-card">
35
- <div class="meta-title">GPU / CPU Model</div>
36
- <div id="processor" class="meta-value pre"></div>
37
- </div>
38
-
39
- <div class="meta-card">
40
- <div class="meta-title">CPU Load (1/5/15)</div>
41
- <div id="cpuload" class="meta-value pre"></div>
42
- </div>
43
-
44
- <div class="meta-card">
45
- <div class="meta-title">Disk ( / )</div>
46
- <div id="disk" class="meta-value pre"></div>
47
- </div>
48
-
49
- <div class="meta-card">
50
- <div class="meta-title">Memory</div>
51
- <div id="memory" class="meta-value pre"></div>
52
- </div>
53
- </section>
32
+ <div class="meta-card">
33
+ <div class="meta-title">System</div>
34
+ <div id="system" class="meta-value pre"></div>
35
+ </div>
54
36
 
55
- <section class="charts-row">
56
- <div class="panel">
57
- <div class="panel-header">
58
- <h3>CPU (Average)</h3>
59
- <div class="panel-actions">
60
- <label><input type="checkbox" id="show-cores" checked="true" /> Show per-core</label>
61
- </div>
37
+ <div class="meta-card">
38
+ <div class="meta-title">IP</div>
39
+ <div id="ip-info" class="meta-value pre"></div>
62
40
  </div>
63
- <canvas id="cpu-avg-chart" class="chart"></canvas>
64
- </div>
65
41
 
66
- <div class="panel">
67
- <div class="panel-header"><h3>Memory (%)</h3></div>
68
- <canvas id="mem-chart" class="chart"></canvas>
69
- </div>
70
- </section>
42
+ <div class="meta-card">
43
+ <div class="meta-title">GPU / CPU Model</div>
44
+ <div id="processor" class="meta-value pre"></div>
45
+ </div>
71
46
 
72
- <section class="details-row">
73
- <div class="panel wide">
74
- <div class="panel-header"><h3>Per-Core (sparklines)</h3></div>
75
- <div id="cores-grid" class="cores-grid"></div>
76
- </div>
77
-
78
- <div class="panel narrow">
79
- <div class="panel-header"><h3>CPU Load History</h3></div>
80
- <canvas id="load-chart" class="chart-small"></canvas>
81
- </div>
82
- </section>
47
+ <div class="meta-card">
48
+ <div class="meta-title">CPU Load (1/5/15)</div>
49
+ <div id="cpuload" class="meta-value pre"></div>
50
+ </div>
83
51
 
84
- <section class="tables-row">
85
- <div class="panel">
86
- <div class="panel-header">
87
- <h3>Services</h3>
88
- <div class="panel-actions">
89
- <label><input type="checkbox" id="get-all-services" /> Get all</label>
90
- </div>
52
+ <div class="meta-card">
53
+ <div class="meta-title">Disk ( / )</div>
54
+ <div id="disk" class="meta-value pre"></div>
91
55
  </div>
92
- <div class="panel-body service-controls">
93
- <input id="svc-filter" placeholder="filter service name..." />
56
+
57
+ <div class="meta-card">
58
+ <div class="meta-title">Memory</div>
59
+ <div id="memory" class="meta-value pre"></div>
94
60
  </div>
95
- <table class="table" id="services-table">
96
- <thead><tr><th>PID</th><th>Name</th><th>Status</th><th>CPU</th><th>Memory</th><th>Threads</th><th>Open Files</th></tr></thead>
97
- <tbody></tbody>
98
- </table>
99
- </div>
61
+ </section>
100
62
 
101
- <section class="tables-row">
102
- <div class="panel">
103
- <div class="panel-header"><h3>Processes</h3></div>
104
- <div class="panel-body service-controls">
105
- <input id="proc-filter" placeholder="filter process name..." />
63
+ <section class="charts-row">
64
+ <div class="panel">
65
+ <div class="panel-header">
66
+ <h3>CPU (Average)</h3>
67
+ <div class="panel-actions">
68
+ <label><input type="checkbox" id="show-cores" checked="true"/> Show per-core</label>
69
+ </div>
70
+ </div>
71
+ <canvas id="cpu-avg-chart" class="chart"></canvas>
106
72
  </div>
107
- <table class="table" id="processes-table">
108
- <thead><tr><th>PID</th><th>Name</th><th>Status</th><th>CPU</th><th>Memory</th><th>Uptime</th><th>Threads</th><th>Open Files</th></tr></thead>
109
- <tbody></tbody>
110
- </table>
111
- </div>
112
-
113
- <div class="panel">
114
- <div class="panel-header"><h3>Docker / Containers</h3></div>
115
- <div class="panel-body">
116
- <table class="table" id="docker-table">
117
- <thead></thead>
118
- <tbody></tbody>
119
- </table>
73
+
74
+ <div class="panel">
75
+ <div class="panel-header"><h3>Memory (%)</h3></div>
76
+ <canvas id="mem-chart" class="chart"></canvas>
120
77
  </div>
121
- </div>
122
-
123
- <div class="panel">
124
- <div class="panel-header"><h3>Disks</h3></div>
125
- <div class="panel-body">
126
- <table class="table" id="disks-table">
127
- <thead></thead>
128
- <tbody></tbody>
129
- </table>
78
+ </section>
79
+
80
+ <section class="details-row">
81
+ <div class="panel wide">
82
+ <div class="panel-header"><h3>Per-Core (sparklines)</h3></div>
83
+ <div id="cores-grid" class="cores-grid"></div>
130
84
  </div>
131
- </div>
132
-
133
- <div class="panel">
134
- <div class="panel-header"><h3>PyUdisk</h3></div>
135
- <div class="panel-body">
136
- <table class="table" id="pyudisk-table">
137
- <thead></thead>
138
- <tbody></tbody>
139
- </table>
85
+
86
+ <div class="panel narrow">
87
+ <div class="panel-header"><h3>CPU Load History</h3></div>
88
+ <canvas id="load-chart" class="chart-small"></canvas>
140
89
  </div>
141
- </div>
142
-
143
- <div class="panel">
144
- <div class="panel-header"><h3>Certificates</h3></div>
145
- <div class="panel-body">
146
- <table class="table" id="certificates-table">
147
- <thead></thead>
148
- <tbody></tbody>
149
- </table>
90
+ </section>
91
+
92
+ <section class="tables-row">
93
+ <div class="panel">
94
+ <div class="panel-header">
95
+ <h3>Services</h3>
96
+ <div class="panel-actions">
97
+ <label><input type="checkbox" id="get-all-services"/> Get all</label>
98
+ </div>
99
+ </div>
100
+ <div class="panel-body service-controls">
101
+ <input id="svc-filter" placeholder="filter service name..."/>
102
+ </div>
103
+ <table class="table" id="services-table">
104
+ <thead>
105
+ <tr>
106
+ <th>PID</th>
107
+ <th>Name</th>
108
+ <th>Status</th>
109
+ <th>CPU</th>
110
+ <th>Memory</th>
111
+ <th>Threads</th>
112
+ <th>Open Files</th>
113
+ </tr>
114
+ </thead>
115
+ <tbody></tbody>
116
+ </table>
150
117
  </div>
151
- </div>
118
+
119
+ <section class="tables-row">
120
+ <div class="panel">
121
+ <div class="panel-header"><h3>Processes</h3></div>
122
+ <div class="panel-body service-controls">
123
+ <input id="proc-filter" placeholder="filter process name..."/>
124
+ </div>
125
+ <table class="table" id="processes-table">
126
+ <thead>
127
+ <tr>
128
+ <th>PID</th>
129
+ <th>Name</th>
130
+ <th>Status</th>
131
+ <th>CPU</th>
132
+ <th>Memory</th>
133
+ <th>Uptime</th>
134
+ <th>Threads</th>
135
+ <th>Open Files</th>
136
+ </tr>
137
+ </thead>
138
+ <tbody></tbody>
139
+ </table>
140
+ </div>
141
+
142
+ <div class="panel">
143
+ <div class="panel-header"><h3>Docker / Containers</h3></div>
144
+ <div class="panel-body">
145
+ <table class="table" id="docker-table">
146
+ <thead></thead>
147
+ <tbody></tbody>
148
+ </table>
149
+ </div>
150
+ </div>
151
+
152
+ <div class="panel">
153
+ <div class="panel-header"><h3>Disks</h3></div>
154
+ <div class="panel-body">
155
+ <table class="table" id="disks-table">
156
+ <thead></thead>
157
+ <tbody></tbody>
158
+ </table>
159
+ </div>
160
+ </div>
161
+
162
+ <div class="panel">
163
+ <div class="panel-header"><h3>PyUdisk</h3></div>
164
+ <div class="panel-body">
165
+ <table class="table" id="pyudisk-table">
166
+ <thead></thead>
167
+ <tbody></tbody>
168
+ </table>
169
+ </div>
170
+ </div>
171
+
172
+ <div class="panel">
173
+ <div class="panel-header"><h3>Certificates</h3></div>
174
+ <div class="panel-body">
175
+ <table class="table" id="certificates-table">
176
+ <thead></thead>
177
+ <tbody></tbody>
178
+ </table>
179
+ </div>
180
+ </div>
181
+ </section>
152
182
  </section>
153
- </main>
183
+ </main>
154
184
 
155
- <footer class="footer">
185
+ <footer class="footer">
156
186
  <div><code>PyObservability: v{{ version }}</code><br>
157
- <a href="https://github.com/thevickypedia/PyObservability" target="_blank">https://github.com/thevickypedia/PyObservability</a>
187
+ <a href="https://github.com/thevickypedia/PyObservability" target="_blank">https://github.com/thevickypedia/PyObservability</a>
158
188
  </div>
159
- </footer>
189
+ </footer>
160
190
 
161
- <script>
191
+ <script>
162
192
  // inject server-side targets
163
193
  window.MONITOR_TARGETS = {{ targets | tojson }};
164
- </script>
165
- <script src="/static/app.js"></script>
194
+ </script>
195
+ <script>
196
+ const logoutEndpoint = "{{ logout }}";
197
+
198
+ if (!logoutEndpoint.startsWith('/')) {
199
+ document.getElementById("logout").style.display = "none";
200
+ }
201
+
202
+ function logout() {
203
+ window.location.href = logoutEndpoint;
204
+ }
205
+ </script>
206
+ <script src="/static/app.js"></script>
166
207
  </body>
167
208
  </html>
@@ -10,13 +10,24 @@ from pyobservability.monitor import Monitor
10
10
  LOGGER = logging.getLogger("uvicorn.default")
11
11
 
12
12
 
13
- async def _forward_metrics(websocket: WebSocket, q: asyncio.Queue):
13
+ async def _forward_metrics(websocket: WebSocket, q: asyncio.Queue) -> None:
14
+ """Forward metrics from the monitor's queue to the websocket.
15
+
16
+ Args:
17
+ websocket: FastAPI WebSocket connection.
18
+ q: asyncio.Queue to receive metrics from the monitor.
19
+ """
14
20
  while True:
15
21
  payload = await q.get()
16
22
  await websocket.send_json(payload)
17
23
 
18
24
 
19
- async def websocket_endpoint(websocket: WebSocket):
25
+ async def websocket_endpoint(websocket: WebSocket) -> None:
26
+ """Websocket endpoint to handle observability data streaming.
27
+
28
+ Args:
29
+ websocket: FastAPI WebSocket connection.
30
+ """
20
31
  await websocket.accept()
21
32
 
22
33
  monitor: Monitor | None = None
@@ -1 +1 @@
1
- __version__ = "1.0.1"
1
+ __version__ = "1.2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyObservability
3
- Version: 1.0.1
3
+ Version: 1.2.0
4
4
  Summary: Lightweight OS-agnostic observability UI for PyNinja
5
5
  Author-email: Vignesh Rao <svignesh1793@gmail.com>
6
6
  License: MIT License
@@ -29,7 +29,7 @@ Project-URL: Homepage, https://github.com/thevickypedia/PyObservability
29
29
  Project-URL: Docs, https://thevickypedia.github.io/PyObservability
30
30
  Project-URL: Source, https://github.com/thevickypedia/PyObservability
31
31
  Project-URL: Bug Tracker, https://github.com/thevickypedia/PyObservability/issues
32
- Project-URL: Release Notes, https://github.com/thevickypedia/PyObservability/blob/main/release_notes.rst
32
+ Project-URL: Release Notes, https://github.com/thevickypedia/PyObservability/blob/main/release_notes.md
33
33
  Keywords: PyObservability,observability,system-monitor,PyNinja
34
34
  Classifier: License :: OSI Approved :: MIT License
35
35
  Classifier: Programming Language :: Python :: 3
@@ -50,10 +50,7 @@ Requires-Dist: pydantic-settings==2.12.*
50
50
  Requires-Dist: python-dotenv==1.2.*
51
51
  Requires-Dist: uvicorn[standard]==0.38.*
52
52
  Provides-Extra: dev
53
- Requires-Dist: sphinx==5.1.1; extra == "dev"
54
53
  Requires-Dist: pre-commit; extra == "dev"
55
- Requires-Dist: recommonmark; extra == "dev"
56
- Requires-Dist: gitverse; extra == "dev"
57
54
  Dynamic: license-file
58
55
 
59
56
  # PyObservability
@@ -69,6 +66,7 @@ Dynamic: license-file
69
66
  [![pypi][label-actions-pypi]][gha_pypi]
70
67
  [![notes][label-actions-notes]][gha_notes]
71
68
  [![release][label-actions-release]][gha_release]
69
+ [![docker][label-actions-docker]][gha_docker]
72
70
 
73
71
  [![Pypi][label-pypi]][pypi]
74
72
  [![Pypi-format][label-pypi-format]][pypi-files]
@@ -102,13 +100,25 @@ pyobservability start
102
100
 
103
101
  > Use `pyobservability --help` for usage instructions.
104
102
 
103
+ **Containerized Deployment**
104
+ ```shell
105
+ docker pull thevickypedia/pyobservability:latest
106
+
107
+ docker run \
108
+ --name observability \
109
+ -p 8080:80 \
110
+ -v /home/user/config:/config \
111
+ --restart=no \
112
+ thevickypedia/pyobservability
113
+ ```
114
+
105
115
  ## Environment Variables
106
116
 
107
117
  <details>
108
118
  <summary><strong>Sourcing environment variables from an env file</strong></summary>
109
119
 
110
120
  > _By default, `PyObservability` will look for a `.env` file in the current working directory._
111
- > _Other file options are supported with a custom kwarg or env var `env_file` pointing to the filepath._
121
+ > _Other file options (like JSON and YAML) are supported with a custom kwarg or env var `env_file` pointing to the filepath._
112
122
  </details>
113
123
 
114
124
  **Mandatory**
@@ -123,6 +133,14 @@ pyobservability start
123
133
  **Optional**
124
134
  - **USERNAME** - Username to authenticate the monitoring page.
125
135
  - **PASSWORD** - Password to authenticate the monitoring page.
136
+ - **TIMEOUT** - Timeout (in seconds) for UI authentication. Defaults to 5m.
137
+
138
+ **Logging**
139
+ > PyObservability uses ``uvicorn`` logger by default. Following options can be used to override the default logger.
140
+ - **LOG** - Lazy logger to use a custom log format. Can either be `file` or `stdout`.
141
+ - **DEBUG** - Enables debug level logging. Defaults to `False`.
142
+ - **LOGS_PATH** - Directory path to store log files if `LOG` is set to `file`.
143
+ - **LOG_CONFIG** - Path to a custom logging configuration file.
126
144
 
127
145
  ## License & copyright
128
146
 
@@ -142,22 +160,14 @@ Licensed under the [MIT License][license]
142
160
  [label-pypi-status]: https://img.shields.io/pypi/status/PyObservability
143
161
  [label-actions-notes]: https://github.com/thevickypedia/PyObservability/actions/workflows/notes.yml/badge.svg
144
162
  [label-actions-release]: https://github.com/thevickypedia/PyObservability/actions/workflows/release.yml/badge.svg
163
+ [label-actions-docker]: https://github.com/thevickypedia/PyObservability/actions/workflows/docker.yml/badge.svg
145
164
 
146
165
  [3.11]: https://docs.python.org/3/whatsnew/3.11.html
147
166
  [virtual environment]: https://docs.python.org/3/tutorial/venv.html
148
- [release-notes]: https://github.com/thevickypedia/PyObservability/blob/main/release_notes.rst
149
167
  [gha_pypi]: https://github.com/thevickypedia/PyObservability/actions/workflows/python-publish.yml
150
168
  [gha_notes]: https://github.com/thevickypedia/PyObservability/actions/workflows/notes.yml
151
169
  [gha_release]: https://github.com/thevickypedia/PyObservability/actions/workflows/release.yml
152
- [google-docs]: https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
153
- [pep8]: https://www.python.org/dev/peps/pep-0008/
154
- [isort]: https://pycqa.github.io/isort/
155
- [sphinx]: https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html
170
+ [gha_docker]: https://github.com/thevickypedia/PyObservability/actions/workflows/docker.yml
156
171
  [pypi]: https://pypi.org/project/PyObservability
157
172
  [pypi-files]: https://pypi.org/project/PyObservability/#files
158
- [pypi-repo]: https://packaging.python.org/tutorials/packaging-projects/
159
173
  [license]: https://github.com/thevickypedia/PyObservability/blob/main/LICENSE
160
- [runbook]: https://thevickypedia.github.io/PyObservability/
161
- [samples]: https://github.com/thevickypedia/PyObservability/tree/main/samples
162
- [PyUdisk]: https://github.com/thevickypedia/PyUdisk
163
- [PyArchitecture]: https://github.com/thevickypedia/PyArchitecture
@@ -0,0 +1,16 @@
1
+ pyobservability/__init__.py,sha256=yVBLyTohBiBKp0Otyl04IggPh8mhg3Er25u6eFyxMto,2618
2
+ pyobservability/main.py,sha256=6Ozyxi-XVq9ojkrTEjw9oYWJaW49JJZ-ezBNzEM951Y,4503
3
+ pyobservability/monitor.py,sha256=Y38zDJFPDbQqz_2jQcNmJBnRpeobC_SV2uhN-13e9RU,7591
4
+ pyobservability/transport.py,sha256=zHLAodX20bKkPOuacKjzv1Dqj3JbNAB75o1ABwzum0U,2534
5
+ pyobservability/version.py,sha256=MpAT5hgNoHnTtG1XRD_GV_A7QrHVU6vJjGSw_8qMGA4,22
6
+ pyobservability/config/enums.py,sha256=EhvD9kB5EMW3ARxr5KmISmf-rP3D4IKqOIjw6Tb8SB8,294
7
+ pyobservability/config/settings.py,sha256=l1xtD8teYS5ozXWm6JqpyyrcQsu95Syjs02xsd0m6MI,5886
8
+ pyobservability/static/app.js,sha256=lb0IjLle-FibG_ee0VN6qAe5LGJuSurgXVhHXCQL6WI,24281
9
+ pyobservability/static/styles.css,sha256=4-VCDhzv_FnrvUffETTHkNnyGOFDUJU0qz2eLHCz_QI,5569
10
+ pyobservability/templates/index.html,sha256=OvFDydHMquBtFr_2cy3iXP0I-pax6_RKBJinVVEIzQY,7193
11
+ pyobservability-1.2.0.dist-info/licenses/LICENSE,sha256=_sOIKJWdD2o1WwwDIwYB2qTP2nlSWqT5Tyg9jr1Xa4w,1070
12
+ pyobservability-1.2.0.dist-info/METADATA,sha256=WEEJiWj1F32ixoMA7n8Cc-3bOQpeGn_p586qh9PjfEk,7037
13
+ pyobservability-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ pyobservability-1.2.0.dist-info/entry_points.txt,sha256=DSGIr_VA8Tb3FYa2iNUYpf55eAvuFCAoInNS4ngXaME,57
15
+ pyobservability-1.2.0.dist-info/top_level.txt,sha256=p20T0EmihDYW1uMintRXr7X9bg3XWYKyoSbBHOVC1xI,16
16
+ pyobservability-1.2.0.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- pyobservability/__init__.py,sha256=rr4udGMbbNPl3yo7l8R3FUUVVahBtYVaW6vSWWgXlv0,2617
2
- pyobservability/main.py,sha256=CI6qfOxpwIykrQXu0hYdgD16foo33IqlNHjJCtrSynA,3592
3
- pyobservability/monitor.py,sha256=4Xd8k7gcOmHM-WvQpgFiDVGtzMu_RpFPZXPPoz4GoA4,6224
4
- pyobservability/transport.py,sha256=FyzJAMZPn7JUZIGgxnSw3on1K6T4ciZE1EuGdAcxt_w,2188
5
- pyobservability/version.py,sha256=d4QHYmS_30j0hPN8NmNPnQ_Z0TphDRbu4MtQj9cT9e8,22
6
- pyobservability/config/enums.py,sha256=jXDtyM1_nDKgq_8gVeZULEC5EEYBzqmZWd25qsIs64I,148
7
- pyobservability/config/settings.py,sha256=C2sK9VRfDBsHm8xP0PTMFAdm7K3ySwiQ0vn6Vh6wAM4,5233
8
- pyobservability/static/app.js,sha256=6hjFy2jt4ndYJUI1DZT08CpuxHyWj9iSAZ2vxaTqH2A,20664
9
- pyobservability/static/styles.css,sha256=dnYSXNeXd6Ohu4h8sJCO87vzPbkYcw9XVGGwB8IJbxw,4703
10
- pyobservability/templates/index.html,sha256=2aQdb0QlDY5Hboev-_lJPlpnGxiC6h3fp0FlvL72S9k,5227
11
- pyobservability-1.0.1.dist-info/licenses/LICENSE,sha256=_sOIKJWdD2o1WwwDIwYB2qTP2nlSWqT5Tyg9jr1Xa4w,1070
12
- pyobservability-1.0.1.dist-info/METADATA,sha256=U5yMXMcpC5NVaAy2Urkt45KED7rGmSNukgMBHqsFPtg,6834
13
- pyobservability-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- pyobservability-1.0.1.dist-info/entry_points.txt,sha256=DSGIr_VA8Tb3FYa2iNUYpf55eAvuFCAoInNS4ngXaME,57
15
- pyobservability-1.0.1.dist-info/top_level.txt,sha256=p20T0EmihDYW1uMintRXr7X9bg3XWYKyoSbBHOVC1xI,16
16
- pyobservability-1.0.1.dist-info/RECORD,,