meter-lib 0.0.3__tar.gz → 0.0.4__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.

Potentially problematic release.


This version of meter-lib might be problematic. Click here for more details.

@@ -0,0 +1,228 @@
1
+ Metadata-Version: 2.4
2
+ Name: meter-lib
3
+ Version: 0.0.4
4
+ Summary: A litewave library to collect the customer credit usage
5
+ Project-URL: Homepage, https://github.com/aiorch/meter-lib
6
+ Project-URL: Repository, https://github.com/aiorch/meter-lib
7
+ Project-URL: Issues, https://github.com/aiorch/meter-lib/issues
8
+ Author-email: Sruthi <sruthi@litewave.ai>
9
+ License: MIT
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: requests>=2.28
17
+ Description-Content-Type: text/markdown
18
+
19
+ ## meter-lib — Usage Guide
20
+
21
+ ### Overview
22
+
23
+ `meter-lib` is a lightweight helper library for sending metering events to the Litewave backend and for looking up a customer account by `tenant_id`.
24
+
25
+ ### Requirements
26
+
27
+ - Python 3.10+
28
+
29
+ ### Installation
30
+
31
+ ```bash
32
+ pip install meter-lib
33
+ ```
34
+
35
+ ### Parameters Required
36
+
37
+ ```
38
+ tenant_id,
39
+ device_id,
40
+ meter_id,
41
+ total_usage,
42
+ start_time,
43
+ end_time
44
+ ```
45
+
46
+ ### Quickstart
47
+
48
+ ```python
49
+ from meter_lib import post_meter_usage
50
+
51
+ tenant_id = "tenant_123"
52
+ device_id = "us-east-ing1"
53
+ meter_id = "document.basic.page"
54
+
55
+ result = post_meter_usage(
56
+ tenant_id=tenant_id,
57
+ device_id=device_id,
58
+ meter_id=meter_id,
59
+ total_usage=24, # integer units as defined by your meter
60
+ )
61
+ ```
62
+
63
+ ### For AI enabled
64
+
65
+ ```python
66
+ from meter_lib import post_meter_usage
67
+
68
+ tenant_id = "tenant_123"
69
+ device_id = "us-east-ing1"
70
+ meter_id = "chat.on.time_hours"
71
+ start_time = 1759791552000 # Timestamp in milliseconds
72
+
73
+ result = post_meter_usage(
74
+ tenant_id=tenant_id,
75
+ device_id=device_id,
76
+ meter_id=meter_id,
77
+ start_time= start_time # Timestamp in milliseconds
78
+ )
79
+
80
+ ```
81
+
82
+ ### For AI disabled
83
+
84
+ ```python
85
+ from meter_lib import post_meter_usage
86
+
87
+ tenant_id = "tenant_123"
88
+ device_id = "us-east-ing1"
89
+ meter_id = "chat.on.time_hours"
90
+ end_time = 1779799552000 # Timestamp in milliseconds
91
+
92
+ result = post_meter_usage(
93
+ tenant_id=tenant_id,
94
+ device_id=device_id,
95
+ meter_id=meter_id,
96
+ end_time= end_time # Timestamp in milliseconds
97
+ )
98
+ ```
99
+
100
+ ```python
101
+ if result is None:
102
+ print("Failed to post meter usage event")
103
+ else:
104
+ print("Event accepted:", result)
105
+ ```
106
+
107
+ ### Error Handling
108
+
109
+ - `post_meter_usage` returns `None` for network errors or non-success HTTP statuses.
110
+ - Prefer explicit checks for `None` and add retries or backoff in your application layer if needed.
111
+
112
+ ### API Reference
113
+
114
+ #### post_meter_usage(tenant_id: str, device_id: str, meter_id: str, total_usage: int) -> dict | None
115
+
116
+ - **Description**: Posts a metering event for a device and meter under a given tenant.
117
+ - **Headers**:
118
+ - `x-tenant-id`: the tenant identifier (string)
119
+ - `x-device-id`: the device identifier (string)
120
+ - **Payload (JSON)**:
121
+ - `meter_id` (string)
122
+ - `total_usage` (integer)
123
+ - `customer_id` (string) — auto-filled by the library.`
124
+ - **Returns**: The backend JSON response (`dict`) on success, otherwise `None`.
125
+ - **Timeout**: 10 seconds.
126
+ - **Notes**:
127
+ - If the customer lookup fails, the call is skipped and `None` is returned.
128
+ - This function is synchronous and will block until the request completes or times out.
129
+
130
+ ### List Of Meters:
131
+ - meter_id: "page.processed.basic"
132
+ name: "Basic Document Scanning"
133
+ type: "volume"
134
+ description: "Total number of basic pages processed"
135
+
136
+ - meter_id: "page.processed.advanced"
137
+ name: "Advanced Document Scanning"
138
+ type: "volume"
139
+ description: "Total number of advanced pages processed"
140
+
141
+ - meter_id: "report.generated.small"
142
+ name: "Small Report Generation"
143
+ type: "volume"
144
+ description: "Total number of small reports generated"
145
+
146
+ - meter_id: "report.generated.medium"
147
+ name: "Medium Report Generation"
148
+ type: "volume"
149
+ description: "Total number of medium reports generated"
150
+
151
+ - meter_id: "report.generated.large"
152
+ name: "Large Report Generation"
153
+ type: "volume"
154
+ description: "Total number of large reports generated"
155
+
156
+ - meter_id: "report.generated.dataquery"
157
+ name: "Data Query Report Generation"
158
+ type: "volume"
159
+ description: "Total number of data query reports generated"
160
+
161
+ - meter_id: "report.generated.insights"
162
+ name: "Insights Report Generation"
163
+ type: "volume"
164
+ description: "Total number of insights reports generated"
165
+
166
+ - meter_id: "rule.executed.small"
167
+ name: "Small Rule Execution"
168
+ type: "volume"
169
+ description: "Total number of rules executed with runtime less than 1 minute"
170
+
171
+ - meter_id: "rule.executed.medium"
172
+ name: "Medium Rule Execution"
173
+ type: "volume"
174
+ description: "Total number of rules executed with runtime between 1 and 3 minutes"
175
+
176
+ - meter_id: "rule.executed.large"
177
+ name: "Large Rule Execution"
178
+ type: "volume"
179
+ description: "Total number of rules executed with runtime greater than 4 minutes"
180
+
181
+ - meter_id: "chat.on.time_hours"
182
+ name: "Litewave AI Assistant Usage (Hours)"
183
+ type: "performance"
184
+ description: "Total active chat usage time in hours"
185
+
186
+ - meter_id: "chat.query.time_secs"
187
+ name: "Litewave AI Assistant Query Time (Seconds)"
188
+ type: "performance"
189
+ description: "Total time spent per query in seconds"
190
+
191
+ - meter_id: "document.storage.size_gb"
192
+ name: "Document Storage Size"
193
+ type: "volume"
194
+ description: "Total document storage consumed in GB"
195
+
196
+ - meter_id: "template.processed.small"
197
+ name: "Small Template Processing"
198
+ type: "volume"
199
+ description: "Total number of small templates processed"
200
+
201
+ - meter_id: "template.processed.medium"
202
+ name: "Medium Template Processing"
203
+ type: "volume"
204
+ description: "Total number of medium templates processed"
205
+
206
+ - meter_id: "template.processed.large"
207
+ name: "Large Template Processing"
208
+ type: "volume"
209
+ description: "Total number of large templates processed"
210
+
211
+ - meter_id: "template.processed.count"
212
+ name: "Template Licensing Count"
213
+ type: "volume"
214
+ description: "Total number of licensed templates processed"
215
+
216
+ - meter_id: "template.licensed.total"
217
+ name: "Yearly Template Setup"
218
+ type: "volume"
219
+ description: "Total yearly template setup count"
220
+
221
+ ### Troubleshooting
222
+
223
+ - Confirm your `tenant_id`, `device_id`, and `meter_id` values are correct.
224
+
225
+ ### Support
226
+
227
+ - Homepage: `https://github.com/aiorch/meter-lib`
228
+ - Issues: `https://github.com/aiorch/meter-lib/issues`
@@ -0,0 +1,210 @@
1
+ ## meter-lib — Usage Guide
2
+
3
+ ### Overview
4
+
5
+ `meter-lib` is a lightweight helper library for sending metering events to the Litewave backend and for looking up a customer account by `tenant_id`.
6
+
7
+ ### Requirements
8
+
9
+ - Python 3.10+
10
+
11
+ ### Installation
12
+
13
+ ```bash
14
+ pip install meter-lib
15
+ ```
16
+
17
+ ### Parameters Required
18
+
19
+ ```
20
+ tenant_id,
21
+ device_id,
22
+ meter_id,
23
+ total_usage,
24
+ start_time,
25
+ end_time
26
+ ```
27
+
28
+ ### Quickstart
29
+
30
+ ```python
31
+ from meter_lib import post_meter_usage
32
+
33
+ tenant_id = "tenant_123"
34
+ device_id = "us-east-ing1"
35
+ meter_id = "document.basic.page"
36
+
37
+ result = post_meter_usage(
38
+ tenant_id=tenant_id,
39
+ device_id=device_id,
40
+ meter_id=meter_id,
41
+ total_usage=24, # integer units as defined by your meter
42
+ )
43
+ ```
44
+
45
+ ### For AI enabled
46
+
47
+ ```python
48
+ from meter_lib import post_meter_usage
49
+
50
+ tenant_id = "tenant_123"
51
+ device_id = "us-east-ing1"
52
+ meter_id = "chat.on.time_hours"
53
+ start_time = 1759791552000 # Timestamp in milliseconds
54
+
55
+ result = post_meter_usage(
56
+ tenant_id=tenant_id,
57
+ device_id=device_id,
58
+ meter_id=meter_id,
59
+ start_time= start_time # Timestamp in milliseconds
60
+ )
61
+
62
+ ```
63
+
64
+ ### For AI disabled
65
+
66
+ ```python
67
+ from meter_lib import post_meter_usage
68
+
69
+ tenant_id = "tenant_123"
70
+ device_id = "us-east-ing1"
71
+ meter_id = "chat.on.time_hours"
72
+ end_time = 1779799552000 # Timestamp in milliseconds
73
+
74
+ result = post_meter_usage(
75
+ tenant_id=tenant_id,
76
+ device_id=device_id,
77
+ meter_id=meter_id,
78
+ end_time= end_time # Timestamp in milliseconds
79
+ )
80
+ ```
81
+
82
+ ```python
83
+ if result is None:
84
+ print("Failed to post meter usage event")
85
+ else:
86
+ print("Event accepted:", result)
87
+ ```
88
+
89
+ ### Error Handling
90
+
91
+ - `post_meter_usage` returns `None` for network errors or non-success HTTP statuses.
92
+ - Prefer explicit checks for `None` and add retries or backoff in your application layer if needed.
93
+
94
+ ### API Reference
95
+
96
+ #### post_meter_usage(tenant_id: str, device_id: str, meter_id: str, total_usage: int) -> dict | None
97
+
98
+ - **Description**: Posts a metering event for a device and meter under a given tenant.
99
+ - **Headers**:
100
+ - `x-tenant-id`: the tenant identifier (string)
101
+ - `x-device-id`: the device identifier (string)
102
+ - **Payload (JSON)**:
103
+ - `meter_id` (string)
104
+ - `total_usage` (integer)
105
+ - `customer_id` (string) — auto-filled by the library.`
106
+ - **Returns**: The backend JSON response (`dict`) on success, otherwise `None`.
107
+ - **Timeout**: 10 seconds.
108
+ - **Notes**:
109
+ - If the customer lookup fails, the call is skipped and `None` is returned.
110
+ - This function is synchronous and will block until the request completes or times out.
111
+
112
+ ### List Of Meters:
113
+ - meter_id: "page.processed.basic"
114
+ name: "Basic Document Scanning"
115
+ type: "volume"
116
+ description: "Total number of basic pages processed"
117
+
118
+ - meter_id: "page.processed.advanced"
119
+ name: "Advanced Document Scanning"
120
+ type: "volume"
121
+ description: "Total number of advanced pages processed"
122
+
123
+ - meter_id: "report.generated.small"
124
+ name: "Small Report Generation"
125
+ type: "volume"
126
+ description: "Total number of small reports generated"
127
+
128
+ - meter_id: "report.generated.medium"
129
+ name: "Medium Report Generation"
130
+ type: "volume"
131
+ description: "Total number of medium reports generated"
132
+
133
+ - meter_id: "report.generated.large"
134
+ name: "Large Report Generation"
135
+ type: "volume"
136
+ description: "Total number of large reports generated"
137
+
138
+ - meter_id: "report.generated.dataquery"
139
+ name: "Data Query Report Generation"
140
+ type: "volume"
141
+ description: "Total number of data query reports generated"
142
+
143
+ - meter_id: "report.generated.insights"
144
+ name: "Insights Report Generation"
145
+ type: "volume"
146
+ description: "Total number of insights reports generated"
147
+
148
+ - meter_id: "rule.executed.small"
149
+ name: "Small Rule Execution"
150
+ type: "volume"
151
+ description: "Total number of rules executed with runtime less than 1 minute"
152
+
153
+ - meter_id: "rule.executed.medium"
154
+ name: "Medium Rule Execution"
155
+ type: "volume"
156
+ description: "Total number of rules executed with runtime between 1 and 3 minutes"
157
+
158
+ - meter_id: "rule.executed.large"
159
+ name: "Large Rule Execution"
160
+ type: "volume"
161
+ description: "Total number of rules executed with runtime greater than 4 minutes"
162
+
163
+ - meter_id: "chat.on.time_hours"
164
+ name: "Litewave AI Assistant Usage (Hours)"
165
+ type: "performance"
166
+ description: "Total active chat usage time in hours"
167
+
168
+ - meter_id: "chat.query.time_secs"
169
+ name: "Litewave AI Assistant Query Time (Seconds)"
170
+ type: "performance"
171
+ description: "Total time spent per query in seconds"
172
+
173
+ - meter_id: "document.storage.size_gb"
174
+ name: "Document Storage Size"
175
+ type: "volume"
176
+ description: "Total document storage consumed in GB"
177
+
178
+ - meter_id: "template.processed.small"
179
+ name: "Small Template Processing"
180
+ type: "volume"
181
+ description: "Total number of small templates processed"
182
+
183
+ - meter_id: "template.processed.medium"
184
+ name: "Medium Template Processing"
185
+ type: "volume"
186
+ description: "Total number of medium templates processed"
187
+
188
+ - meter_id: "template.processed.large"
189
+ name: "Large Template Processing"
190
+ type: "volume"
191
+ description: "Total number of large templates processed"
192
+
193
+ - meter_id: "template.processed.count"
194
+ name: "Template Licensing Count"
195
+ type: "volume"
196
+ description: "Total number of licensed templates processed"
197
+
198
+ - meter_id: "template.licensed.total"
199
+ name: "Yearly Template Setup"
200
+ type: "volume"
201
+ description: "Total yearly template setup count"
202
+
203
+ ### Troubleshooting
204
+
205
+ - Confirm your `tenant_id`, `device_id`, and `meter_id` values are correct.
206
+
207
+ ### Support
208
+
209
+ - Homepage: `https://github.com/aiorch/meter-lib`
210
+ - Issues: `https://github.com/aiorch/meter-lib/issues`
@@ -0,0 +1 @@
1
+ from .core import post_meter_usage, post_ai_meter_usage
@@ -0,0 +1,112 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+ import requests
4
+
5
+ def fetch_customer_id(tenant_id: str):
6
+ """
7
+ Fetch the customer account for a given tenant_id.
8
+ Returns a dict with customer info, or None if not found/error.
9
+ """
10
+ url = f"http://metering.metering.svc.cluster.local:8000/v1alpha1/customer-accounts/tenant/{tenant_id}"
11
+ try:
12
+ response = requests.get(url, timeout=10)
13
+ response.raise_for_status()
14
+ data = response.json()
15
+
16
+ # Handle list response
17
+ if isinstance(data, list) and len(data) > 0:
18
+ return data[0]
19
+ elif isinstance(data, dict):
20
+ return data
21
+ else:
22
+ print(f"No customer account found for tenant {tenant_id}")
23
+ return None
24
+
25
+ except requests.RequestException as e:
26
+ print(f"Error fetching {url}: {e}")
27
+ return None
28
+
29
+
30
+ def post_meter_usage(tenant_id: str, device_id: str, meter_id: str, total_usage: int) :
31
+ """
32
+ Posts meter usage to the events API.
33
+ Uses tenant_id + device_id in headers and includes customer_id in payload.
34
+ """
35
+ customer_account = fetch_customer_id(tenant_id)
36
+ if not customer_account:
37
+ print("No customer account available, skipping meter usage post")
38
+ return None
39
+
40
+ url = "https://stream.app.litewave.ai/topics/usage-events"
41
+ headers = {
42
+ "Content-Type": "application/vnd.kafka.json.v2+json",
43
+ }
44
+ payload = {
45
+ "records": [
46
+ {
47
+ "value": {
48
+ "meter_id": meter_id,
49
+ "customer_id": customer_account["id"],
50
+ "total_usage": total_usage
51
+ }
52
+ }
53
+ ]
54
+ }
55
+
56
+ try:
57
+ response = requests.post(url, headers=headers, json=payload, timeout=10)
58
+ response.raise_for_status()
59
+ return response.json()
60
+ except requests.RequestException as e:
61
+ print(f" Error posting to {url}: {e}")
62
+ return None
63
+
64
+ def post_ai_meter_usage(tenant_id: str, device_id: str, meter_id: str, start_time:Optional[datetime]= None, end_time:Optional[datetime]=None) :
65
+ """
66
+ Posts meter usage to the ai events API.
67
+ Uses tenant_id + device_id in headers and includes customer_id in payload.
68
+ """
69
+ customer_account = fetch_customer_id(tenant_id)
70
+ if not customer_account:
71
+ print("No customer account available, skipping meter usage post")
72
+ return None
73
+
74
+ url = "https://stream.app.litewave.ai/topics/usage-events"
75
+ headers = {
76
+ "Content-Type": "application/vnd.kafka.json.v2+json",
77
+ }
78
+ if start_time:
79
+ payload = {
80
+ "records": [
81
+ {
82
+ "value": {
83
+ "ai_event": True,
84
+ "meter_id": meter_id,
85
+ "customer_id": customer_account["id"],
86
+ "start_time": start_time
87
+ }
88
+ }
89
+ ]
90
+ }
91
+ else:
92
+ payload = {
93
+ "records": [
94
+ {
95
+ "value": {
96
+ "ai_event": True,
97
+ "meter_id": meter_id,
98
+ "customer_id": customer_account["id"],
99
+ "end_time": end_time
100
+ }
101
+ }
102
+ ]
103
+ }
104
+
105
+ try:
106
+ response = requests.post(url, headers=headers, json=payload, timeout=10)
107
+ response.raise_for_status()
108
+ return response.json()
109
+ except requests.RequestException as e:
110
+ print(f" Error posting to {url}: {e}")
111
+ return None
112
+
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "meter-lib"
7
- version = "0.0.3"
7
+ version = "0.0.4"
8
8
  description = "A litewave library to collect the customer credit usage"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -10,7 +10,7 @@ with open("requirements.txt", "r", encoding="utf-8") as fh:
10
10
 
11
11
  setup(
12
12
  name="meter-lib",
13
- version="0.0.3",
13
+ version="0.0.4",
14
14
  author="Sruthi R",
15
15
  author_email="sruthi@litewave.ai",
16
16
  description="A litewave library to collect the customer credit usage",
meter_lib-0.0.3/PKG-INFO DELETED
@@ -1,97 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: meter-lib
3
- Version: 0.0.3
4
- Summary: A litewave library to collect the customer credit usage
5
- Project-URL: Homepage, https://github.com/aiorch/meter-lib
6
- Project-URL: Repository, https://github.com/aiorch/meter-lib
7
- Project-URL: Issues, https://github.com/aiorch/meter-lib/issues
8
- Author-email: Sruthi <sruthi@litewave.ai>
9
- License: MIT
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.10
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Requires-Python: >=3.10
16
- Requires-Dist: requests>=2.28
17
- Description-Content-Type: text/markdown
18
-
19
- ## meter-lib — Usage Guide
20
-
21
- ### Overview
22
-
23
- `meter-lib` is a lightweight helper library for sending metering events to the Litewave backend and for looking up a customer account by `tenant_id`.
24
-
25
- ### Requirements
26
-
27
- - Python 3.10+
28
-
29
- ### Installation
30
-
31
- ```bash
32
- pip install meter-lib
33
- ```
34
-
35
- ### Parameters Required
36
-
37
- ```
38
- tenant_id,
39
- device_id,
40
- meter_id,
41
- total_usage
42
- ```
43
-
44
- ### Quickstart
45
-
46
- ```python
47
- from meter_lib import post_meter_usage
48
-
49
- tenant_id = "tenant_123"
50
- device_id = "device_456"
51
- meter_id = "pages.processed.rate.hourly"
52
-
53
- result = post_meter_usage(
54
- tenant_id=tenant_id,
55
- device_id=device_id,
56
- meter_id=meter_id,
57
- total_usage=24, # integer units as defined by your meter
58
- )
59
-
60
- if result is None:
61
- # Handle network error or non-2xx response
62
- print("Failed to post meter usage event")
63
- else:
64
- print("Event accepted:", result)
65
- ```
66
-
67
- ### Error Handling
68
-
69
- - `post_meter_usage` returns `None` for network errors or non-success HTTP statuses.
70
- - Prefer explicit checks for `None` and add retries or backoff in your application layer if needed.
71
-
72
- ### API Reference
73
-
74
- #### post_meter_usage(tenant_id: str, device_id: str, meter_id: str, total_usage: int) -> dict | None
75
-
76
- - **Description**: Posts a metering event for a device and meter under a given tenant.
77
- - **Headers**:
78
- - `x-tenant-id`: the tenant identifier (string)
79
- - `x-device-id`: the device identifier (string)
80
- - **Payload (JSON)**:
81
- - `meter_id` (string)
82
- - `total_usage` (integer)
83
- - `customer_id` (string) — auto-filled by the library.`
84
- - **Returns**: The backend JSON response (`dict`) on success, otherwise `None`.
85
- - **Timeout**: 10 seconds.
86
- - **Notes**:
87
- - If the customer lookup fails, the call is skipped and `None` is returned.
88
- - This function is synchronous and will block until the request completes or times out.
89
-
90
- ### Troubleshooting
91
-
92
- - Confirm your `tenant_id`, `device_id`, and `meter_id` values are correct.
93
-
94
- ### Support
95
-
96
- - Homepage: `https://github.com/aiorch/meter-lib`
97
- - Issues: `https://github.com/aiorch/meter-lib/issues`
meter_lib-0.0.3/README.md DELETED
@@ -1,79 +0,0 @@
1
- ## meter-lib — Usage Guide
2
-
3
- ### Overview
4
-
5
- `meter-lib` is a lightweight helper library for sending metering events to the Litewave backend and for looking up a customer account by `tenant_id`.
6
-
7
- ### Requirements
8
-
9
- - Python 3.10+
10
-
11
- ### Installation
12
-
13
- ```bash
14
- pip install meter-lib
15
- ```
16
-
17
- ### Parameters Required
18
-
19
- ```
20
- tenant_id,
21
- device_id,
22
- meter_id,
23
- total_usage
24
- ```
25
-
26
- ### Quickstart
27
-
28
- ```python
29
- from meter_lib import post_meter_usage
30
-
31
- tenant_id = "tenant_123"
32
- device_id = "device_456"
33
- meter_id = "pages.processed.rate.hourly"
34
-
35
- result = post_meter_usage(
36
- tenant_id=tenant_id,
37
- device_id=device_id,
38
- meter_id=meter_id,
39
- total_usage=24, # integer units as defined by your meter
40
- )
41
-
42
- if result is None:
43
- # Handle network error or non-2xx response
44
- print("Failed to post meter usage event")
45
- else:
46
- print("Event accepted:", result)
47
- ```
48
-
49
- ### Error Handling
50
-
51
- - `post_meter_usage` returns `None` for network errors or non-success HTTP statuses.
52
- - Prefer explicit checks for `None` and add retries or backoff in your application layer if needed.
53
-
54
- ### API Reference
55
-
56
- #### post_meter_usage(tenant_id: str, device_id: str, meter_id: str, total_usage: int) -> dict | None
57
-
58
- - **Description**: Posts a metering event for a device and meter under a given tenant.
59
- - **Headers**:
60
- - `x-tenant-id`: the tenant identifier (string)
61
- - `x-device-id`: the device identifier (string)
62
- - **Payload (JSON)**:
63
- - `meter_id` (string)
64
- - `total_usage` (integer)
65
- - `customer_id` (string) — auto-filled by the library.`
66
- - **Returns**: The backend JSON response (`dict`) on success, otherwise `None`.
67
- - **Timeout**: 10 seconds.
68
- - **Notes**:
69
- - If the customer lookup fails, the call is skipped and `None` is returned.
70
- - This function is synchronous and will block until the request completes or times out.
71
-
72
- ### Troubleshooting
73
-
74
- - Confirm your `tenant_id`, `device_id`, and `meter_id` values are correct.
75
-
76
- ### Support
77
-
78
- - Homepage: `https://github.com/aiorch/meter-lib`
79
- - Issues: `https://github.com/aiorch/meter-lib/issues`
@@ -1 +0,0 @@
1
- from .core import fetch_customer_id, post_meter_usage
@@ -1,56 +0,0 @@
1
- import requests
2
-
3
- def fetch_customer_id(tenant_id: str):
4
- """
5
- Fetch the customer account for a given tenant_id.
6
- Returns a dict with customer info, or None if not found/error.
7
- """
8
- url = f"http://metering.metering.svc.cluster.local:8000/api/v1/customer-accounts/tenant/{tenant_id}"
9
- try:
10
- response = requests.get(url, timeout=10)
11
- response.raise_for_status()
12
- data = response.json()
13
-
14
- # Handle list response
15
- if isinstance(data, list) and len(data) > 0:
16
- return data[0]
17
- elif isinstance(data, dict):
18
- return data
19
- else:
20
- print(f"No customer account found for tenant {tenant_id}")
21
- return None
22
-
23
- except requests.RequestException as e:
24
- print(f"Error fetching {url}: {e}")
25
- return None
26
-
27
-
28
- def post_meter_usage(tenant_id: str, device_id: str, meter_id: str, total_usage: int) :
29
- """
30
- Posts meter usage to the events API.
31
- Uses tenant_id + device_id in headers and includes customer_id in payload.
32
- """
33
- customer_account = fetch_customer_id(tenant_id)
34
- if not customer_account:
35
- print("No customer account available, skipping meter usage post")
36
- return None
37
-
38
- url = "http://metering.metering.svc.cluster.local:8000/api/v1/events"
39
- headers = {
40
- "x-tenant-id": tenant_id,
41
- "x-device-id": device_id,
42
- "Content-Type": "application/json"
43
- }
44
- payload = {
45
- "meter_id": meter_id,
46
- "total_usage": total_usage,
47
- "customer_id": customer_account["id"]
48
- }
49
-
50
- try:
51
- response = requests.post(url, headers=headers, json=payload, timeout=10)
52
- response.raise_for_status()
53
- return response.json()
54
- except requests.RequestException as e:
55
- print(f" Error posting to {url}: {e}")
56
- return None
File without changes
File without changes