mermaid-trace 0.4.0__py3-none-any.whl → 0.4.1__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,3 +1,11 @@
1
+ """
2
+ Asynchronous Mermaid Handler Module
3
+
4
+ This module provides a non-blocking logging handler that uses a background thread
5
+ for writing logs. It's designed to improve performance in high-throughput applications
6
+ by decoupling the logging I/O from the main execution thread.
7
+ """
8
+
1
9
  import logging
2
10
  import logging.handlers
3
11
  import queue
@@ -12,41 +20,86 @@ class AsyncMermaidHandler(logging.handlers.QueueHandler):
12
20
  This handler pushes log records to a queue, which are then picked up by a
13
21
  QueueListener running in a separate thread and dispatched to the actual
14
22
  handlers (e.g., MermaidFileHandler).
23
+
24
+ This architecture provides several benefits:
25
+ - Main thread doesn't block waiting for disk I/O
26
+ - Logs are processed in the background
27
+ - Better performance in high-throughput applications
28
+ - Smooth handling of burst traffic
15
29
  """
16
30
 
17
- def __init__(self, handlers: List[logging.Handler], queue_size: int = -1):
31
+ def __init__(self, handlers: List[logging.Handler], queue_size: int = 1000):
18
32
  """
19
33
  Initialize the async handler.
20
-
34
+
21
35
  Args:
22
36
  handlers: A list of handlers that should receive the logs from the queue.
23
- (e.g., [MermaidFileHandler(...)])
24
- queue_size: The maximum size of the queue. -1 means infinite.
37
+ These are typically MermaidFileHandler instances.
38
+ queue_size: The maximum size of the queue. Default is 1000.
39
+ If the queue fills up, new log records may be dropped.
25
40
  """
41
+ # Create a bounded queue with the specified size
26
42
  self._log_queue: queue.Queue[logging.LogRecord] = queue.Queue(queue_size)
43
+ self._queue_size = queue_size
44
+
45
+ # Initialize parent QueueHandler with our queue
27
46
  super().__init__(self._log_queue)
28
-
29
- # Initialize QueueListener
47
+
48
+ # Initialize QueueListener to process records from the queue
30
49
  # It starts an internal thread to monitor the queue
31
50
  # respect_handler_level=True ensures the target handlers' log levels are respected
32
- self._listener: Optional[logging.handlers.QueueListener] = logging.handlers.QueueListener(
33
- self._log_queue,
34
- *handlers,
35
- respect_handler_level=True
51
+ self._listener: Optional[logging.handlers.QueueListener] = (
52
+ logging.handlers.QueueListener(
53
+ self._log_queue, *handlers, respect_handler_level=True
54
+ )
36
55
  )
56
+
57
+ # Start the listener thread
37
58
  self._listener.start()
38
-
39
- # Ensure the listener is stopped and queue is flushed upon exit
40
- # This prevents lost logs at program termination
59
+
60
+ # Register stop method to be called on program exit
61
+ # This ensures all pending logs are written to disk before termination
41
62
  atexit.register(self.stop)
42
63
 
64
+ def emit(self, record: logging.LogRecord) -> None:
65
+ """
66
+ Emit a log record to the queue with a timeout and drop policy.
67
+
68
+ If the queue is full, this method will attempt to put the record with
69
+ a short timeout. If that fails, it will drop the record and print a warning.
70
+
71
+ Args:
72
+ record: The log record to emit
73
+ """
74
+ from typing import cast
75
+
76
+ try:
77
+ # Try to put the record in the queue with a short timeout (0.1 seconds)
78
+ # This prevents the main thread from blocking indefinitely if the queue is full
79
+ # Use cast to tell Mypy this is a queue.Queue instance
80
+ queue_instance = cast(queue.Queue[logging.LogRecord], self.queue)
81
+ queue_instance.put(record, block=True, timeout=0.1)
82
+ except queue.Full:
83
+ # If queue is full, log a warning and drop the record
84
+ if record.levelno >= logging.WARNING:
85
+ # Avoid infinite recursion by not using self.logger
86
+ print(
87
+ f"WARNING: AsyncMermaidHandler queue is full (size: {self._queue_size}), dropping log record: {record.msg}"
88
+ )
89
+
43
90
  def stop(self) -> None:
44
91
  """
45
- Stops the listener and flushes the queue.
92
+ Stops the listener and flushes all pending logs from the queue.
46
93
 
47
- This is registered with `atexit` to ensure that all pending logs
94
+ This method is registered with `atexit` to ensure that all pending logs
48
95
  are written to disk before the application terminates.
49
96
  """
50
97
  if self._listener:
51
- self._listener.stop()
52
- self._listener = None
98
+ try:
99
+ # Stop the listener - this will process all remaining records in the queue
100
+ self._listener.stop()
101
+ self._listener = None
102
+ except queue.Full:
103
+ # Handle case where queue is full when trying to put sentinel value
104
+ # The listener thread may still be processing, but we can safely exit
105
+ pass
@@ -1,3 +1,11 @@
1
+ """
2
+ Mermaid File Handler Module
3
+
4
+ This module provides a custom logging handler that writes FlowEvent objects to
5
+ Mermaid (.mmd) files. It handles the Mermaid syntax formatting, file headers, and
6
+ ensures thread-safe file writing.
7
+ """
8
+
1
9
  import logging
2
10
  import os
3
11
 
@@ -26,24 +34,23 @@ class MermaidFileHandler(logging.FileHandler):
26
34
  delay: bool = False,
27
35
  ):
28
36
  """
29
- Initialize the handler.
37
+ Initialize the Mermaid file handler.
30
38
 
31
39
  Args:
32
40
  filename (str): The path to the output .mmd file.
33
- title (str): The title of the Mermaid diagram (written in the header).
34
- mode (str): File open mode. 'w' (overwrite) or 'a' (append).
35
- encoding (str): File encoding. Defaults to 'utf-8'.
36
- delay (bool): If True, file opening is deferred until the first call to emit.
37
- Useful to avoid creating empty files if no logs occur.
41
+ title (str, optional): The title of the Mermaid diagram. Defaults to "Log Flow".
42
+ mode (str, optional): File open mode. 'w' (overwrite) or 'a' (append). Defaults to "a".
43
+ encoding (str, optional): File encoding. Defaults to "utf-8".
44
+ delay (bool, optional): If True, file opening is deferred until the first call to emit.
45
+ Useful to avoid creating empty files if no logs occur. Defaults to False.
38
46
  """
39
- # Ensure directory exists to prevent FileNotFoundError on open
47
+ # Ensure the directory exists to prevent FileNotFoundError when opening the file
40
48
  os.makedirs(os.path.dirname(os.path.abspath(filename)) or ".", exist_ok=True)
41
49
 
42
- # Header Strategy:
43
- # We need to write the "sequenceDiagram" preamble ONLY if:
44
- # 1. We are overwriting the file (mode='w').
45
- # 2. We are appending (mode='a'), but the file doesn't exist or is empty.
46
- # This prevents invalid Mermaid files (e.g., multiple "sequenceDiagram" lines).
50
+ # Determine if we need to write a header
51
+ # Header is written only if:
52
+ # 1. We are overwriting the file (mode='w'), or
53
+ # 2. We are appending (mode='a') but the file doesn't exist or is empty
47
54
  should_write_header = False
48
55
  if mode == "w":
49
56
  should_write_header = True
@@ -51,49 +58,62 @@ class MermaidFileHandler(logging.FileHandler):
51
58
  if not os.path.exists(filename) or os.path.getsize(filename) == 0:
52
59
  should_write_header = True
53
60
 
54
- # Initialize standard FileHandler (opens the file unless delay=True)
61
+ # Initialize the parent FileHandler (opens the file unless delay=True)
55
62
  super().__init__(filename, mode, encoding, delay)
56
63
  self.title = title
57
64
 
58
- # Write header immediately if needed.
65
+ # Write the header immediately if needed
59
66
  if should_write_header:
60
67
  self._write_header()
61
68
 
62
69
  def _write_header(self) -> None:
63
70
  """
64
- Writes the initial Mermaid syntax lines.
71
+ Writes the initial Mermaid syntax lines to the file.
72
+
73
+ This setup is required for Mermaid JS or Live Editor to render the diagram correctly.
74
+ It defines:
75
+ - Diagram type (sequenceDiagram)
76
+ - Title of the diagram
77
+ - Autonumbering of steps
65
78
 
66
- This setup is required for Mermaid JS or Live Editor to render the diagram.
67
- It defines the diagram type (sequenceDiagram), title, and enables autonumbering.
79
+ Thread Safety: Uses the handler's internal lock to prevent concurrent writes
80
+ when delay=True, ensuring the header is written only once.
68
81
  """
69
- # We use the stream directly if available, or open momentarily if delayed
70
- if self.stream:
71
- self.stream.write("sequenceDiagram\n")
72
- self.stream.write(f" title {self.title}\n")
73
- self.stream.write(" autonumber\n")
74
- # Flush ensures the header is written to disk immediately,
75
- # so it appears even if the program crashes right after.
76
- self.flush()
77
- else:
78
- # Handling 'delay=True' case:
79
- # If the file isn't open yet, we temporarily open it just to write the header.
80
- # This ensures the file is valid even if the application crashes before the first log.
81
- with open(self.baseFilename, self.mode, encoding=self.encoding) as f:
82
- f.write("sequenceDiagram\n")
83
- f.write(f" title {self.title}\n")
84
- f.write(" autonumber\n")
82
+ # Use the handler's internal lock to ensure thread safety
83
+ assert self.lock is not None, "Handler lock should always be initialized"
84
+ with self.lock:
85
+ # Write to the existing stream if available, otherwise open temporarily
86
+ if self.stream:
87
+ # Stream is already open (delay=False or emit() has been called)
88
+ self.stream.write("sequenceDiagram\n")
89
+ self.stream.write(f" title {self.title}\n")
90
+ self.stream.write(" autonumber\n")
91
+ # Flush ensures the header is written to disk immediately
92
+ self.flush()
93
+ else:
94
+ # Handle delay=True case: file not yet opened
95
+ # Temporarily open the file just to write the header
96
+ with open(self.baseFilename, self.mode, encoding=self.encoding) as f:
97
+ f.write("sequenceDiagram\n")
98
+ f.write(f" title {self.title}\n")
99
+ f.write(" autonumber\n")
85
100
 
86
101
  def emit(self, record: logging.LogRecord) -> None:
87
102
  """
88
- Process a log record.
103
+ Process a log record and write it to the Mermaid file.
104
+
105
+ This method overrides the parent's emit method to filter out non-FlowEvent records.
89
106
 
90
107
  Optimization:
91
- - Checks for `flow_event` attribute first. This allows this handler
92
- to be attached to the root logger without processing irrelevant system logs.
93
- It acts as a high-performance filter before formatting.
94
- - Delegates the actual writing to `super().emit()`, which handles
95
- thread locking and stream flushing safely.
108
+ - Checks for `flow_event` attribute first, acting as a high-performance filter
109
+ - Only processes records containing structured FlowEvent data
110
+ - Delegates actual writing to parent's emit() method, which handles locking and flushing
111
+
112
+ Args:
113
+ record (logging.LogRecord): The log record to process
96
114
  """
97
115
  # Only process records that contain our structured FlowEvent data
116
+ # This allows the handler to be attached to the root logger without processing
117
+ # irrelevant system logs
98
118
  if hasattr(record, "flow_event"):
99
119
  super().emit(record)
@@ -1,3 +1,11 @@
1
+ """
2
+ FastAPI Integration Module
3
+
4
+ This module provides middleware for integrating MermaidTrace with FastAPI applications.
5
+ It automatically traces HTTP requests and responses, converting them into Mermaid
6
+ sequence diagram events.
7
+ """
8
+
1
9
  from typing import Any, TYPE_CHECKING
2
10
  import time
3
11
  import uuid
@@ -6,20 +14,23 @@ from ..core.events import FlowEvent
6
14
  from ..core.context import LogContext
7
15
  from ..core.decorators import get_flow_logger
8
16
 
17
+ # Conditional imports to support optional FastAPI dependency
9
18
  if TYPE_CHECKING:
19
+ # For type checking only, import the actual FastAPI/Starlette types
10
20
  from fastapi import Request, Response
11
21
  from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
12
22
  else:
13
23
  try:
24
+ # Try to import FastAPI/Starlette at runtime
14
25
  from fastapi import Request, Response
15
26
  from starlette.middleware.base import (
16
27
  BaseHTTPMiddleware,
17
28
  RequestResponseEndpoint,
18
29
  )
19
30
  except ImportError:
20
- # Handle the case where FastAPI/Starlette are not installed.
21
- # We define dummy types to prevent NameErrors at import time,
22
- # but instantiation will fail explicitly in __init__.
31
+ # Handle the case where FastAPI/Starlette are not installed
32
+ # Define dummy types to prevent NameErrors at import time
33
+ # Instantiation will fail explicitly in __init__
23
34
  BaseHTTPMiddleware = object # type: ignore[misc,assignment]
24
35
  Request = Any # type: ignore[assignment]
25
36
  Response = Any # type: ignore[assignment]
@@ -30,11 +41,12 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
30
41
  """
31
42
  FastAPI Middleware to trace HTTP requests as interactions in the sequence diagram.
32
43
 
33
- This middleware acts as the entry point for tracing a web request. It:
34
- 1. Identifies the client (Source).
35
- 2. Logs the incoming request.
36
- 3. Initializes the `LogContext` for the request lifecycle.
37
- 4. Logs the response or error.
44
+ This middleware acts as the entry point for tracing web requests, handling:
45
+ 1. Identification of the client (Source participant)
46
+ 2. Logging of incoming requests
47
+ 3. Initialization of the `LogContext` for the request lifecycle
48
+ 4. Logging of responses or errors
49
+ 5. Cleanup of context after request completion
38
50
  """
39
51
 
40
52
  def __init__(self, app: Any, app_name: str = "FastAPI"):
@@ -42,13 +54,19 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
42
54
  Initialize the middleware.
43
55
 
44
56
  Args:
45
- app: The FastAPI application instance.
46
- app_name: The name of this service to appear in the diagram (e.g., "UserAPI").
57
+ app: The FastAPI application instance
58
+ app_name: The name of this service to appear in the diagram (e.g., "UserAPI")
59
+
60
+ Raises:
61
+ ImportError: If FastAPI/Starlette are not installed
47
62
  """
63
+ # Check if FastAPI is installed by verifying BaseHTTPMiddleware is not our dummy object
48
64
  if BaseHTTPMiddleware is object: # type: ignore[comparison-overlap]
49
65
  raise ImportError(
50
66
  "FastAPI/Starlette is required to use MermaidTraceMiddleware"
51
67
  )
68
+
69
+ # Initialize the parent BaseHTTPMiddleware
52
70
  super().__init__(app)
53
71
  self.app_name = app_name
54
72
 
@@ -56,31 +74,35 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
56
74
  self, request: Request, call_next: RequestResponseEndpoint
57
75
  ) -> Response:
58
76
  """
59
- Intercepts the incoming request.
77
+ Intercepts and processes incoming HTTP requests.
78
+
79
+ This method is called for each incoming request and handles the full
80
+ request-response cycle tracing.
60
81
 
61
82
  Args:
62
- request (Request): The incoming HTTP request.
63
- call_next (Callable): The function to call the next middleware or endpoint.
83
+ request (Request): The incoming HTTP request object
84
+ call_next (RequestResponseEndpoint): Function to call the next middleware or endpoint
64
85
 
65
86
  Returns:
66
- Response: The HTTP response.
87
+ Response: The HTTP response object
67
88
  """
68
- # 1. Determine Source (Client)
69
- # Try to get a specific ID from headers (useful for distributed tracing),
70
- # otherwise fallback to "Client".
89
+ # 1. Determine Source (Client participant)
90
+ # Try to get a specific ID from X-Source header (useful for distributed tracing),
91
+ # otherwise fallback to "Client"
71
92
  source = request.headers.get("X-Source", "Client")
72
93
 
73
- # Determine Trace ID
74
- # Check X-Trace-ID header or generate new UUID
94
+ # 2. Determine Trace ID
95
+ # Check for X-Trace-ID header (for distributed tracing) or generate new UUID
75
96
  trace_id = request.headers.get("X-Trace-ID") or str(uuid.uuid4())
76
97
 
77
- # 2. Determine Action
78
- # Format: "METHOD /path" (e.g., "GET /users")
98
+ # 3. Determine Action name
99
+ # Format: "METHOD /path" (e.g., "GET /users", "POST /items")
79
100
  action = f"{request.method} {request.url.path}"
80
101
 
81
102
  logger = get_flow_logger()
82
103
 
83
- # 3. Log Request (Source -> App)
104
+ # 4. Log Request (Source -> App)
105
+ # Create and log the initial request event
84
106
  req_event = FlowEvent(
85
107
  source=source,
86
108
  target=self.app_name,
@@ -93,21 +115,20 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
93
115
  f"{source}->{self.app_name}: {action}", extra={"flow_event": req_event}
94
116
  )
95
117
 
96
- # 4. Set Context and Process Request
97
- # We set the current participant to the app name.
98
- # `ascope` ensures this context applies to all code running within `call_next`.
99
- # This includes route handlers, dependencies, and other middlewares called after this one.
118
+ # 5. Set Context and Process Request
119
+ # Use async context manager to set the current participant to the app name
120
+ # This context will be inherited by all code called within call_next()
100
121
  async with LogContext.ascope(
101
122
  {"participant": self.app_name, "trace_id": trace_id}
102
123
  ):
103
124
  start_time = time.time()
104
125
  try:
105
- # Pass control to the application
106
- # This executes the actual route logic
126
+ # Pass control to the next middleware or endpoint
127
+ # This executes the actual route logic and returns the response
107
128
  response = await call_next(request)
108
129
 
109
- # 5. Log Response (App -> Source)
110
- # Calculate execution duration for the response label
130
+ # 6. Log Success Response (App -> Source)
131
+ # Calculate execution duration in milliseconds
111
132
  duration = (time.time() - start_time) * 1000
112
133
  resp_event = FlowEvent(
113
134
  source=self.app_name,
@@ -125,10 +146,9 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
125
146
  return response
126
147
 
127
148
  except Exception as e:
128
- # 6. Log Error (App --x Source)
149
+ # 7. Log Error Response (App --x Source)
129
150
  # This captures unhandled exceptions that bubble up to the middleware
130
- # Note: FastAPI's ExceptionHandlers might catch this before it reaches here.
131
- # If so, you might see a successful return with 500 status instead.
151
+ # Note: FastAPI's ExceptionHandlers might catch some exceptions before they reach here
132
152
  err_event = FlowEvent(
133
153
  source=self.app_name,
134
154
  target=source,
@@ -142,4 +162,5 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
142
162
  logger.error(
143
163
  f"{self.app_name}-x{source}: Error", extra={"flow_event": err_event}
144
164
  )
165
+ # Re-raise the exception to maintain normal error handling flow
145
166
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mermaid-trace
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Visualize your Python code execution flow as Mermaid Sequence Diagrams.
5
5
  Project-URL: Documentation, https://github.com/xt765/mermaid-trace#readme
6
6
  Project-URL: Changelog, https://github.com/xt765/mermaid-trace/blob/main/docs/en/CHANGELOG.md
@@ -63,17 +63,31 @@ Description-Content-Type: text/markdown
63
63
 
64
64
  # MermaidTrace: The Python Logger That Draws Diagrams
65
65
 
66
- [![PyPI version](https://img.shields.io/pypi/v/mermaid-trace.svg?style=flat-square)](https://pypi.org/project/mermaid-trace/)
67
- [![Python Versions](https://img.shields.io/pypi/pyversions/mermaid-trace.svg?style=flat-square)](https://pypi.org/project/mermaid-trace/)
66
+ 🌐 **Language**: [English](README.md) | [中文](README_CN.md)
67
+
68
+ [![PyPI version](https://img.shields.io/pypi/v/mermaid-trace.svg?style=flat-square&color=blue)](https://pypi.org/project/mermaid-trace/)
69
+ [![Python Versions](https://img.shields.io/pypi/pyversions/mermaid-trace.svg?style=flat-square&color=blue)](https://pypi.org/project/mermaid-trace/)
68
70
  [![License](https://img.shields.io/github/license/xt765/mermaid-trace?style=flat-square)](LICENSE)
69
71
  [![CI Status](https://img.shields.io/github/actions/workflow/status/xt765/mermaid-trace/ci.yml?style=flat-square&label=CI)](https://github.com/xt765/mermaid-trace/actions/workflows/ci.yml)
70
72
  [![Codecov](https://img.shields.io/codecov/c/github/xt765/mermaid-trace?style=flat-square&logo=codecov)](https://codecov.io/gh/xt765/mermaid-trace)
71
73
 
74
+ ---
75
+
76
+ ## 📋 Overview
77
+
72
78
  **Stop reading logs. Start watching them.**
73
79
 
74
80
  MermaidTrace is a specialized logging tool that automatically generates [Mermaid JS](https://mermaid.js.org/) sequence diagrams from your code execution. It's perfect for visualizing complex business logic, microservice interactions, or asynchronous flows.
75
81
 
76
- ## ✨ Features
82
+ ---
83
+
84
+ ## 📚 Documentation
85
+
86
+ [User Guide](docs/en/USER_GUIDE.md) · [API Reference](docs/en/API.md) · [Contributing Guidelines](docs/en/CONTRIBUTING.md) · [Changelog](docs/en/CHANGELOG.md) · [License](docs/en/LICENSE)
87
+
88
+ ---
89
+
90
+ ## ✨ Key Features
77
91
 
78
92
  - **Decorator-Driven**: Just add `@trace` or `@trace_interaction` to your functions.
79
93
  - **Auto-Diagramming**: Generates `.mmd` files that can be viewed in VS Code, GitHub, or Mermaid Live Editor.
@@ -82,6 +96,8 @@ MermaidTrace is a specialized logging tool that automatically generates [Mermaid
82
96
  - **FastAPI Integration**: Includes middleware for zero-config HTTP request tracing.
83
97
  - **CLI Tool**: Built-in viewer to preview diagrams in your browser.
84
98
 
99
+ ---
100
+
85
101
  ## 🚀 Quick Start
86
102
 
87
103
  ### Installation
@@ -151,15 +167,14 @@ Visualize your generated `.mmd` files instantly:
151
167
  mermaid-trace serve my_flow.mmd
152
168
  ```
153
169
 
154
- ## 📂 Documentation
155
-
156
- - [English Documentation](docs/en/USER_GUIDE.md)
157
- - [中文文档](README_CN.md)
170
+ ---
158
171
 
159
172
  ## 🤝 Contributing
160
173
 
161
174
  We welcome contributions! Please see [CONTRIBUTING.md](docs/en/CONTRIBUTING.md) for details.
162
175
 
176
+ ---
177
+
163
178
  ## 📄 License
164
179
 
165
180
  MIT
@@ -0,0 +1,16 @@
1
+ mermaid_trace/__init__.py,sha256=ZXviz2KlX0eER7FPZJG2edsXfyDewt5iXpfGMifBoyE,5323
2
+ mermaid_trace/cli.py,sha256=w7xh9kvyaokcUcuwIsBAtgwcl9zW8mosXesp5e0CtHg,11224
3
+ mermaid_trace/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ mermaid_trace/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ mermaid_trace/core/context.py,sha256=wr-Ys3c6PsYCtbPUsQTrnaciSkP-fofxOewo4oZ27QM,8556
6
+ mermaid_trace/core/decorators.py,sha256=lNNx_Qj2cDJkPX67qPl3NBH946ofoJ8osqxq3oBoCgU,16164
7
+ mermaid_trace/core/events.py,sha256=h1g8uk1SGUj_NzefuJXYrkWO8ZuezeFjfU8IpYILnB8,5977
8
+ mermaid_trace/core/formatter.py,sha256=A9ULgcu3xHiG3iD6k54sQ7nm9kHceMvplVCHw_nu09I,5259
9
+ mermaid_trace/handlers/async_handler.py,sha256=Cbs6ZuKywf2VWwSIPNRXFOtoPArIhoYl-QHeW05hhWg,4272
10
+ mermaid_trace/handlers/mermaid_handler.py,sha256=rF-S3IXsMvTS-6kgGN7By-_2kqlCyMwcNgaorlci1Q8,5137
11
+ mermaid_trace/integrations/fastapi.py,sha256=H9Hl2pFxdbM3NwqONyJ7kAP-oGdOOnuoG3hEEbpoOjE,6487
12
+ mermaid_trace-0.4.1.dist-info/METADATA,sha256=JLDyn-TuDnehsO34g6GAArjIl-XN4izSVZIVulmiu6c,6539
13
+ mermaid_trace-0.4.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
+ mermaid_trace-0.4.1.dist-info/entry_points.txt,sha256=WS57KT_870v0A4B87QDjQUqJcddMQxbCQyYeczDAX34,57
15
+ mermaid_trace-0.4.1.dist-info/licenses/LICENSE,sha256=BrBog1Etiq9PdWy0SVQNVByIMD9ss4Edz-R0oXt49zA,1062
16
+ mermaid_trace-0.4.1.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- mermaid_trace/__init__.py,sha256=yhc-shETKioVEQEfqmCGFyVelRR3_ypeClbMR_D2oBQ,5267
2
- mermaid_trace/cli.py,sha256=F5-QfnKp_Et719IKWvU5IAWZTpq9ft01ow62DqNpHdA,9477
3
- mermaid_trace/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- mermaid_trace/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- mermaid_trace/core/context.py,sha256=WyTKbC_I1ge802VUj9PdUiqa-VgL1r3DQUW_y8PlG8M,6618
6
- mermaid_trace/core/decorators.py,sha256=13-n6qsmWnInpKgQ0Bgnnn5aQIWkRZ7raTD2xVtKVmU,12303
7
- mermaid_trace/core/events.py,sha256=TVtarp7IwfTR_C404ZWoyqBZmTtScROz5hWL0uel3G4,2857
8
- mermaid_trace/core/formatter.py,sha256=6k79eBU09TSCEUcDJN1mfn-_KMld0xXfKtQTKZb8Ogw,3178
9
- mermaid_trace/handlers/async_handler.py,sha256=uGC27TCgfxyvQQEiJ_7Ir1EFJdsLHBUzHEsLktEaFtM,1893
10
- mermaid_trace/handlers/mermaid_handler.py,sha256=JUq5gSQepNISreUYkyucS_rk27zGIiwSYFw_Lb8lL28,4314
11
- mermaid_trace/integrations/fastapi.py,sha256=GJL2H0Ypi4HqiAR-kkV4kSUTitdOj4RkhPi26GGNORM,5515
12
- mermaid_trace-0.4.0.dist-info/METADATA,sha256=4oszQifzCHhgCEI0Ly1nKAUuvcF-Bs-ejCReGUOsTbo,6287
13
- mermaid_trace-0.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
- mermaid_trace-0.4.0.dist-info/entry_points.txt,sha256=WS57KT_870v0A4B87QDjQUqJcddMQxbCQyYeczDAX34,57
15
- mermaid_trace-0.4.0.dist-info/licenses/LICENSE,sha256=BrBog1Etiq9PdWy0SVQNVByIMD9ss4Edz-R0oXt49zA,1062
16
- mermaid_trace-0.4.0.dist-info/RECORD,,