libsh 0.0.0__tar.gz → 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.
libsh-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.3
2
+ Name: libsh
3
+ Version: 0.2.0
4
+ Summary: Scott Hyndman's reusable common package for Python projects. Provides opinionated structured logging with custom rendering (24-bit colors, relative timestamps, compact levels) and type-safe value formatting utilities (time units, ranges, pretty-printing).
5
+ Author: shyndman
6
+ Author-email: shyndman <scotty.hyndman@gmail.com>
7
+ Requires-Dist: numpy
8
+ Requires-Dist: pydantic>=2
9
+ Requires-Dist: rich>=14
10
+ Requires-Dist: structlog>=25
11
+ Requires-Python: >=3.12
12
+ Project-URL: Bug Tracker, https://github.com/shyndman/libsh-python/issues
13
+ Project-URL: repository, https://github.com/shyndman/libsh-python
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "libsh"
3
- version = "0.0.0"
4
- description = "Add your description here"
3
+ version = "0.2.0"
4
+ description = "Scott Hyndman's reusable common package for Python projects. Provides opinionated structured logging with custom rendering (24-bit colors, relative timestamps, compact levels) and type-safe value formatting utilities (time units, ranges, pretty-printing)."
5
5
  authors = [{name = "shyndman", email = "scotty.hyndman@gmail.com"}]
6
6
  requires-python = ">=3.12"
7
- dependencies = ["numpy<2", "pydantic>=2", "rich>=14.1.0", "structlog>=25.4.0"]
7
+ dependencies = ["numpy", "pydantic>=2", "rich>=14", "structlog>=25"]
8
8
 
9
9
  [build-system]
10
10
  requires = ["uv_build>=0.9.5,<0.10.0"]
@@ -133,12 +133,7 @@ def _relative_time_processor(
133
133
  _logger: structlog.stdlib.BoundLogger, _method_name: str, event_dict: EventDict
134
134
  ) -> EventDict:
135
135
  """Add relative timestamp since program start with hours:minutes:seconds.milliseconds format."""
136
- elapsed = time.time() - _PROGRAM_START_TIME
137
-
138
- # Calculate hours, minutes, seconds
139
- hours = int(elapsed // 3600)
140
- minutes = int((elapsed % 3600) // 60)
141
- seconds = elapsed % 60
136
+ hours, minutes, seconds = _relative_time_parts()
142
137
 
143
138
  # ANSI color codes: \x1b[2m for dim/gray, \x1b[90m for darker gray, \x1b[0m to reset
144
139
  gray = "\x1b[2m" # Normal gray (like original timestamp)
@@ -163,6 +158,30 @@ def _relative_time_processor(
163
158
  return event_dict
164
159
 
165
160
 
161
+ def _relative_time_processor_plain(
162
+ _logger: structlog.stdlib.BoundLogger, _method_name: str, event_dict: EventDict
163
+ ) -> EventDict:
164
+ """Add relative timestamp without ANSI styling for machine-consumable outputs."""
165
+ hours, minutes, seconds = _relative_time_parts()
166
+
167
+ separator = ":"
168
+ hours_str = f"{hours:02d}{separator}" if hours != 0 else ""
169
+ minutes_str = f"{minutes:02d}{separator}" if minutes != 0 and hours != 0 else ""
170
+ seconds_str = f"{seconds:06.3f}"
171
+
172
+ event_dict["timestamp"] = f"+{hours_str}{minutes_str}{seconds_str}"
173
+ return event_dict
174
+
175
+
176
+ def _relative_time_parts() -> tuple[int, int, float]:
177
+ """Return elapsed (hours, minutes, seconds) since program start."""
178
+ elapsed = time.time() - _PROGRAM_START_TIME
179
+ hours = int(elapsed // 3600)
180
+ minutes = int((elapsed % 3600) // 60)
181
+ seconds = elapsed % 60
182
+ return hours, minutes, seconds
183
+
184
+
166
185
  def _compact_level_processor(
167
186
  _logger: structlog.stdlib.BoundLogger, _method_name: str, event_dict: EventDict
168
187
  ) -> EventDict:
@@ -238,25 +257,42 @@ def setup_logging(
238
257
  filters += [LoggerFilterProcessor(filter_to_logger)]
239
258
 
240
259
  # Configure processors
241
- shared_processors: list[Processor] = [
242
- structlog.stdlib.add_logger_name,
243
- structlog.stdlib.add_log_level,
244
- *filters,
245
- _debug_event_colorer, # Run before level processing
246
- _compact_level_processor,
247
- structlog.stdlib.PositionalArgumentsFormatter(),
248
- structlog.stdlib.ExtraAdder(),
249
- FloatPrecisionProcessor(digits=3),
250
- _relative_time_processor,
251
- structlog.processors.StackInfoRenderer(),
252
- # structlog.processors.format_exc_info,
253
- ]
260
+ processors: list[Processor] = []
254
261
 
255
262
  # Add correlation ID if provided
256
263
  if correlation_id:
257
- shared_processors.insert(0, structlog.contextvars.merge_contextvars)
264
+ processors.append(structlog.contextvars.merge_contextvars)
258
265
  structlog.contextvars.bind_contextvars(correlation_id=correlation_id)
259
266
 
267
+ # Level filtering should happen before any expensive processors run
268
+ processors.extend(filters)
269
+
270
+ processors += [
271
+ structlog.stdlib.add_logger_name,
272
+ structlog.stdlib.add_log_level,
273
+ ]
274
+
275
+ if json_output:
276
+ processors += [
277
+ structlog.stdlib.PositionalArgumentsFormatter(),
278
+ structlog.stdlib.ExtraAdder(),
279
+ FloatPrecisionProcessor(digits=3),
280
+ _relative_time_processor_plain,
281
+ structlog.processors.StackInfoRenderer(),
282
+ # structlog.processors.format_exc_info,
283
+ ]
284
+ else:
285
+ processors += [
286
+ _debug_event_colorer, # Run before level processing
287
+ _compact_level_processor,
288
+ structlog.stdlib.PositionalArgumentsFormatter(),
289
+ structlog.stdlib.ExtraAdder(),
290
+ FloatPrecisionProcessor(digits=3),
291
+ _relative_time_processor,
292
+ structlog.processors.StackInfoRenderer(),
293
+ # structlog.processors.format_exc_info,
294
+ ]
295
+
260
296
  # Configure output format
261
297
  if json_output:
262
298
  log_renderer = structlog.processors.JSONRenderer()
@@ -283,7 +319,7 @@ def setup_logging(
283
319
  value_style_map=[
284
320
  (
285
321
  # Integers (including negative) get bright green styling
286
- r"^True|False$",
322
+ r"^(True|False)$",
287
323
  hex_to_ansi_fg(0x6E6A86),
288
324
  ),
289
325
  (
@@ -340,16 +376,19 @@ def setup_logging(
340
376
  ],
341
377
  )
342
378
 
379
+ # Omit level filters when processing stdlib log records to avoid double filtering
380
+ formatter_pre_chain: list[Processor] = [proc for proc in processors if proc not in filters]
381
+
343
382
  # Configure structlog
344
383
  structlog.configure(
345
- processors=shared_processors + [structlog.stdlib.ProcessorFormatter.wrap_for_formatter],
384
+ processors=processors + [structlog.stdlib.ProcessorFormatter.wrap_for_formatter],
346
385
  wrapper_class=structlog.stdlib.BoundLogger,
347
386
  logger_factory=structlog.stdlib.LoggerFactory(),
348
387
  cache_logger_on_first_use=True,
349
388
  )
350
389
 
351
390
  formatter = structlog.stdlib.ProcessorFormatter(
352
- foreign_pre_chain=shared_processors,
391
+ foreign_pre_chain=formatter_pre_chain,
353
392
  processors=[
354
393
  structlog.stdlib.ProcessorFormatter.remove_processors_meta,
355
394
  log_renderer,
libsh-0.0.0/PKG-INFO DELETED
@@ -1,13 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: libsh
3
- Version: 0.0.0
4
- Summary: Add your description here
5
- Author: shyndman
6
- Author-email: shyndman <scotty.hyndman@gmail.com>
7
- Requires-Dist: numpy<2
8
- Requires-Dist: pydantic>=2
9
- Requires-Dist: rich>=14.1.0
10
- Requires-Dist: structlog>=25.4.0
11
- Requires-Python: >=3.12
12
- Project-URL: Bug Tracker, https://github.com/shyndman/libsh-python/issues
13
- Project-URL: repository, https://github.com/shyndman/libsh-python
File without changes
File without changes
File without changes
File without changes
File without changes