mermaid-trace 0.4.1__py3-none-any.whl → 0.5.3.post0__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,14 +1,21 @@
1
1
  """
2
- FastAPI Integration Module
2
+ FastAPI Integration Module for MermaidTrace.
3
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.
4
+ This module provides the middleware necessary to integrate MermaidTrace with
5
+ FastAPI applications. It serves as the bridge between HTTP requests and the
6
+ sequence diagram generation logic.
7
+
8
+ Key functionalities include:
9
+ - Middleware for intercepting all incoming HTTP requests.
10
+ - Automatic extraction of tracing headers (X-Source, X-Trace-ID).
11
+ - Initialization of logging context for request lifecycles.
12
+ - Automatic logging of request start and response completion (success or error).
7
13
  """
8
14
 
9
15
  from typing import Any, TYPE_CHECKING
10
16
  import time
11
17
  import uuid
18
+ import traceback
12
19
 
13
20
  from ..core.events import FlowEvent
14
21
  from ..core.context import LogContext
@@ -16,21 +23,21 @@ from ..core.decorators import get_flow_logger
16
23
 
17
24
  # Conditional imports to support optional FastAPI dependency
18
25
  if TYPE_CHECKING:
19
- # For type checking only, import the actual FastAPI/Starlette types
26
+ # For static type checkers (mypy, pyright), import the actual types.
20
27
  from fastapi import Request, Response
21
28
  from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
22
29
  else:
23
30
  try:
24
- # Try to import FastAPI/Starlette at runtime
31
+ # Runtime import attempt for FastAPI and Starlette.
25
32
  from fastapi import Request, Response
26
33
  from starlette.middleware.base import (
27
34
  BaseHTTPMiddleware,
28
35
  RequestResponseEndpoint,
29
36
  )
30
37
  except ImportError:
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__
38
+ # Fallback for when FastAPI is not installed in the environment.
39
+ # This prevents ImportErrors when importing this module without FastAPI.
40
+ # However, instantiating the middleware will still fail.
34
41
  BaseHTTPMiddleware = object # type: ignore[misc,assignment]
35
42
  Request = Any # type: ignore[assignment]
36
43
  Response = Any # type: ignore[assignment]
@@ -41,12 +48,22 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
41
48
  """
42
49
  FastAPI Middleware to trace HTTP requests as interactions in the sequence diagram.
43
50
 
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
51
+ This middleware wraps the entire request processing pipeline. It is responsible for
52
+ recording the initial interaction between an external client (Source) and this
53
+ service (Target).
54
+
55
+ Middleware Logic:
56
+ 1. **Request Interception**: Captures the request before it reaches any route handler.
57
+ 2. **Context Initialization**: Sets up the `LogContext` with the current service name
58
+ and trace ID, ensuring all internal function calls are correctly associated.
59
+ 3. **Event Logging**: Logs the "Request" event (Client -> API) and the corresponding
60
+ "Response" event (API -> Client).
61
+ 4. **Error Handling**: Captures exceptions, logs error events (API --x Client),
62
+ and re-raises them to standard error handlers.
63
+
64
+ Attributes:
65
+ app_name (str): The name of the current service/application. This name will
66
+ appear as a participant in the generated Mermaid sequence diagram.
50
67
  """
51
68
 
52
69
  def __init__(self, app: Any, app_name: str = "FastAPI"):
@@ -54,19 +71,20 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
54
71
  Initialize the middleware.
55
72
 
56
73
  Args:
57
- app: The FastAPI application instance
58
- app_name: The name of this service to appear in the diagram (e.g., "UserAPI")
74
+ app (Any): The FastAPI application instance.
75
+ app_name (str): The name of this service to appear in the diagram (e.g., "UserAPI").
76
+ Defaults to "FastAPI".
59
77
 
60
78
  Raises:
61
- ImportError: If FastAPI/Starlette are not installed
79
+ ImportError: If FastAPI or Starlette is not installed in the current environment.
62
80
  """
63
- # Check if FastAPI is installed by verifying BaseHTTPMiddleware is not our dummy object
81
+ # Validate that the necessary dependencies are present.
64
82
  if BaseHTTPMiddleware is object: # type: ignore[comparison-overlap]
65
83
  raise ImportError(
66
84
  "FastAPI/Starlette is required to use MermaidTraceMiddleware"
67
85
  )
68
86
 
69
- # Initialize the parent BaseHTTPMiddleware
87
+ # Initialize the base class.
70
88
  super().__init__(app)
71
89
  self.app_name = app_name
72
90
 
@@ -74,62 +92,88 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
74
92
  self, request: Request, call_next: RequestResponseEndpoint
75
93
  ) -> Response:
76
94
  """
77
- Intercepts and processes incoming HTTP requests.
95
+ Dispatch method to handle the incoming request.
96
+
97
+ This is the core logic of the middleware. It wraps the `call_next` execution
98
+ with tracing logic.
78
99
 
79
- This method is called for each incoming request and handles the full
80
- request-response cycle tracing.
100
+ Request Tracing & Header Handling:
101
+ - **X-Source**: Used to identify the caller. If present, the diagram will show
102
+ an arrow from `X-Source` to `app_name`. If missing, defaults to "Client".
103
+ - **X-Trace-ID**: Used for distributed tracing. If provided, it links this
104
+ request to an existing trace. If missing, a new UUID is generated.
81
105
 
82
106
  Args:
83
- request (Request): The incoming HTTP request object
84
- call_next (RequestResponseEndpoint): Function to call the next middleware or endpoint
107
+ request (Request): The incoming HTTP request object.
108
+ call_next (RequestResponseEndpoint): A callable that invokes the next
109
+ middleware or the route handler.
85
110
 
86
111
  Returns:
87
- Response: The HTTP response object
112
+ Response: The HTTP response generated by the application.
88
113
  """
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"
114
+ # ----------------------------------------------------------------------
115
+ # 1. Header Handling and Metadata Extraction
116
+ # ----------------------------------------------------------------------
117
+
118
+ # Determine the source participant (Who is calling us?).
119
+ # If the request comes from another service traced by MermaidTrace,
120
+ # it might include the 'X-Source' header.
92
121
  source = request.headers.get("X-Source", "Client")
93
122
 
94
- # 2. Determine Trace ID
95
- # Check for X-Trace-ID header (for distributed tracing) or generate new UUID
123
+ # Determine the unique Trace ID.
124
+ # This ID is critical for grouping all logs related to a single request flow.
96
125
  trace_id = request.headers.get("X-Trace-ID") or str(uuid.uuid4())
97
126
 
98
- # 3. Determine Action name
99
- # Format: "METHOD /path" (e.g., "GET /users", "POST /items")
127
+ # Define the action name for the diagram arrow.
128
+ # Format: "METHOD /path" (e.g., "GET /api/v1/users")
100
129
  action = f"{request.method} {request.url.path}"
101
130
 
131
+ # Get the configured logger for flow events.
102
132
  logger = get_flow_logger()
103
133
 
104
- # 4. Log Request (Source -> App)
105
- # Create and log the initial request event
134
+ # ----------------------------------------------------------------------
135
+ # 2. Log Request Start (Source -> App)
136
+ # ----------------------------------------------------------------------
137
+
138
+ # Create the 'Request' event representing the call coming into this service.
106
139
  req_event = FlowEvent(
107
140
  source=source,
108
141
  target=self.app_name,
109
142
  action=action,
110
143
  message=action,
144
+ # Include query parameters in the note if they exist.
111
145
  params=f"query={request.query_params}" if request.query_params else None,
112
146
  trace_id=trace_id,
113
147
  )
148
+
149
+ # Log the event. This writes the JSON entry that the visualizer will parse.
114
150
  logger.info(
115
151
  f"{source}->{self.app_name}: {action}", extra={"flow_event": req_event}
116
152
  )
117
153
 
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()
154
+ # ----------------------------------------------------------------------
155
+ # 3. Context Setup and Request Processing
156
+ # ----------------------------------------------------------------------
157
+
158
+ # Initialize the LogContext for this async task.
159
+ # Any 'traced' function called within this block will inherit 'trace_id'
160
+ # and see 'participant' as self.app_name.
121
161
  async with LogContext.ascope(
122
162
  {"participant": self.app_name, "trace_id": trace_id}
123
163
  ):
124
164
  start_time = time.time()
125
165
  try:
126
- # Pass control to the next middleware or endpoint
127
- # This executes the actual route logic and returns the response
166
+ # Process the request by calling the next item in the middleware chain.
128
167
  response = await call_next(request)
129
168
 
130
- # 6. Log Success Response (App -> Source)
131
- # Calculate execution duration in milliseconds
169
+ # ------------------------------------------------------------------
170
+ # 4. Log Success Response (App -> Source)
171
+ # ------------------------------------------------------------------
172
+
173
+ # Calculate execution time for performance insights.
132
174
  duration = (time.time() - start_time) * 1000
175
+
176
+ # Create the 'Return' event (dashed line back to caller).
133
177
  resp_event = FlowEvent(
134
178
  source=self.app_name,
135
179
  target=source,
@@ -146,9 +190,17 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
146
190
  return response
147
191
 
148
192
  except Exception as e:
149
- # 7. Log Error Response (App --x Source)
150
- # This captures unhandled exceptions that bubble up to the middleware
151
- # Note: FastAPI's ExceptionHandlers might catch some exceptions before they reach here
193
+ # ------------------------------------------------------------------
194
+ # 5. Log Error Response (App --x Source)
195
+ # ------------------------------------------------------------------
196
+
197
+ # Capture full stack trace for the error.
198
+ stack_trace = "".join(
199
+ traceback.format_exception(type(e), e, e.__traceback__)
200
+ )
201
+
202
+ # If an unhandled exception occurs, log it as an error event.
203
+ # This will render as a cross (X) on the sequence diagram return arrow.
152
204
  err_event = FlowEvent(
153
205
  source=self.app_name,
154
206
  target=source,
@@ -157,10 +209,13 @@ class MermaidTraceMiddleware(BaseHTTPMiddleware):
157
209
  is_return=True,
158
210
  is_error=True,
159
211
  error_message=str(e),
212
+ stack_trace=stack_trace,
160
213
  trace_id=trace_id,
161
214
  )
162
215
  logger.error(
163
216
  f"{self.app_name}-x{source}: Error", extra={"flow_event": err_event}
164
217
  )
165
- # Re-raise the exception to maintain normal error handling flow
218
+
219
+ # Re-raise the exception so FastAPI's exception handlers can take over.
220
+ # We strictly monitor the flow here, not swallow errors.
166
221
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mermaid-trace
3
- Version: 0.4.1
3
+ Version: 0.5.3.post0
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
@@ -39,7 +39,6 @@ Classifier: Programming Language :: Python :: 3.10
39
39
  Classifier: Programming Language :: Python :: 3.11
40
40
  Classifier: Programming Language :: Python :: 3.12
41
41
  Classifier: Programming Language :: Python :: 3.13
42
- Classifier: Programming Language :: Python :: 3.14
43
42
  Classifier: Programming Language :: Python :: Implementation :: CPython
44
43
  Classifier: Programming Language :: Python :: Implementation :: PyPy
45
44
  Classifier: Topic :: Software Development :: Debuggers
@@ -83,18 +82,35 @@ MermaidTrace is a specialized logging tool that automatically generates [Mermaid
83
82
 
84
83
  ## 📚 Documentation
85
84
 
85
+ ### Core Documentation
86
+
86
87
  [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
+ ### Code Comment Documents (Chinese)
90
+
91
+ | Category | Links |
92
+ | :--- | :--- |
93
+ | **Core Modules** | [Context](docs/zh/code_comments/src/mermaid_trace/core/context.md) · [Decorators](docs/zh/code_comments/src/mermaid_trace/core/decorators.md) · [Events](docs/zh/code_comments/src/mermaid_trace/core/events.md) · [Formatter](docs/zh/code_comments/src/mermaid_trace/core/formatter.md) |
94
+ | **Handlers** | [Async Handler](docs/zh/code_comments/src/mermaid_trace/handlers/async_handler.md) · [Mermaid Handler](docs/zh/code_comments/src/mermaid_trace/handlers/mermaid_handler.md) |
95
+ | **Integrations** | [FastAPI](docs/zh/code_comments/src/mermaid_trace/integrations/fastapi.md) |
96
+ | **Others** | [init](docs/zh/code_comments/src/mermaid_trace/__init__.md) · [CLI](docs/zh/code_comments/src/mermaid_trace/cli.md) |
97
+
88
98
  ---
89
99
 
90
100
  ## ✨ Key Features
91
101
 
92
102
  - **Decorator-Driven**: Just add `@trace` or `@trace_interaction` to your functions.
103
+ - **Auto-Instrumentation**: Use `@trace_class` to trace a whole class at once.
104
+ - **Third-Party Patching**: Use `patch_object` to trace calls inside external libraries.
93
105
  - **Auto-Diagramming**: Generates `.mmd` files that can be viewed in VS Code, GitHub, or Mermaid Live Editor.
94
106
  - **Async Support**: Works seamlessly with `asyncio` coroutines.
95
107
  - **Context Inference**: Automatically tracks nested calls and infers `source` participants using `contextvars`.
96
- - **FastAPI Integration**: Includes middleware for zero-config HTTP request tracing.
97
- - **CLI Tool**: Built-in viewer to preview diagrams in your browser.
108
+ - **Intelligent Collapsing**: Prevents diagram explosion by collapsing repetitive high-frequency calls and identifying recurring patterns (e.g., loops).
109
+ - **Detailed Exceptions**: Captures full stack traces for errors, displayed in interactive notes.
110
+ - **Simplified Objects**: Automatically cleans up memory addresses (e.g., `<__main__.Obj at 0x...>` -> `<Obj>`) and **groups consecutive identical items** in lists/tuples (e.g., `[<Obj> x 5]`) for cleaner diagrams.
111
+ - **Log Rotation**: Supports `RotatingMermaidFileHandler` for handling long-running systems by splitting logs based on size or time.
112
+ - **FastAPI Integration**: Includes middleware for zero-config HTTP request tracing, supporting distributed tracing via `X-Trace-ID` and `X-Source` headers.
113
+ - **CLI Tool**: Built-in viewer with live-reload to preview diagrams in your browser.
98
114
 
99
115
  ---
100
116
 
@@ -113,7 +129,8 @@ from mermaid_trace import trace, configure_flow
113
129
  import time
114
130
 
115
131
  # 1. Configure output
116
- configure_flow("my_flow.mmd")
132
+ # Recommendation: Store diagrams in a dedicated directory (e.g., mermaid_diagrams/)
133
+ configure_flow("mermaid_diagrams/my_flow.mmd", async_mode=True)
117
134
 
118
135
  # 2. Add decorators
119
136
  @trace(source="Client", target="PaymentService", action="Process Payment")
@@ -130,6 +147,29 @@ def check_balance(amount):
130
147
  process_payment(100)
131
148
  ```
132
149
 
150
+ ### Configuration
151
+
152
+ You can configure global settings via `configure_flow` or environment variables to control performance and behavior.
153
+
154
+ ```python
155
+ configure_flow(
156
+ "flow.mmd",
157
+ overwrite=True, # Overwrite the file on each restart (default: True)
158
+ level=logging.DEBUG,
159
+ queue_size=5000, # Increase buffer for high-throughput
160
+ config_overrides={
161
+ "capture_args": False, # Disable arg capturing for max performance
162
+ "max_string_length": 100 # Increase string truncation limit
163
+ }
164
+ )
165
+ ```
166
+
167
+ **Environment Variables:**
168
+ - `MERMAID_TRACE_CAPTURE_ARGS` (true/false)
169
+ - `MERMAID_TRACE_MAX_STRING_LENGTH` (int)
170
+ - `MERMAID_TRACE_MAX_ARG_DEPTH` (int)
171
+ - `MERMAID_TRACE_QUEUE_SIZE` (int)
172
+
133
173
  ### Nested Calls (Context Inference)
134
174
 
135
175
  You don't need to specify `source` every time. MermaidTrace infers it from the current context.
@@ -167,6 +207,18 @@ Visualize your generated `.mmd` files instantly:
167
207
  mermaid-trace serve my_flow.mmd
168
208
  ```
169
209
 
210
+ ### Examples
211
+
212
+ Check out the [examples/](examples/) directory for a complete set of demos covering all features:
213
+ - **[Basic Usage](examples/01_basic_usage.py)**: Decorators and class methods.
214
+ - **[Advanced Instrumentation](examples/02_advanced_instrumentation.py)**: `@trace_class` and `patch_object` for third-party libraries.
215
+ - **[Async & Concurrency](examples/03_async_concurrency.py)**: Tracing `asyncio` and concurrent tasks.
216
+ - **[Error Handling](examples/04_error_handling.py)**: Stack trace capture and error rendering.
217
+ - **[Intelligent Collapsing](examples/05_intelligent_collapsing.py)**: Keeping diagrams clean in loops.
218
+ - **[FastAPI Integration](examples/06_fastapi_integration.py)**: Middleware for web apps.
219
+ - **[Full Stack App](examples/07_full_stack_app.py)**: Comprehensive example with FastAPI, SQLAlchemy, and Pydantic.
220
+ - **[Log Rotation](examples/08-log-rotation.py)**: Handling long-running processes with file rotation.
221
+
170
222
  ---
171
223
 
172
224
  ## 🤝 Contributing
@@ -0,0 +1,19 @@
1
+ mermaid_trace/__init__.py,sha256=EnAsz6R6ag4dtabdHEg1wdB2k7V1uwmwpYTTC41GQX4,6721
2
+ mermaid_trace/cli.py,sha256=g7Qriiox9YqfJutUntE1a7GwByg62wGwQcLfpvicjT8,15076
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/config.py,sha256=akTOc3m_bzcZ7e1Qtf1n5Ct9Dj8XPTTcWzATG3-qJHw,1890
6
+ mermaid_trace/core/context.py,sha256=wr-Ys3c6PsYCtbPUsQTrnaciSkP-fofxOewo4oZ27QM,8556
7
+ mermaid_trace/core/decorators.py,sha256=2h7UzjQcL46jrCIdVMWSZT_4JlTsDkpY9M9Ihr0vuq4,23037
8
+ mermaid_trace/core/events.py,sha256=2etS45A40GaP4dF_F6Jh99rhF2YVip4AjoZlLPuP6pQ,1949
9
+ mermaid_trace/core/formatter.py,sha256=3KEq236E3GAj_j53MuBM2ndWm7Kx4KeywJWmoY5o568,11038
10
+ mermaid_trace/core/utils.py,sha256=FagsMYLZcbmOgKmRo3v9tcRNVIpuc1YEKTAjcRk7keY,3410
11
+ mermaid_trace/handlers/async_handler.py,sha256=WmLcULXHasapt7-W0p_Eltjmwvlq6r6BS6pViuseZ4w,8252
12
+ mermaid_trace/handlers/mermaid_handler.py,sha256=Czar6JYSPTu5L1fQC0I8v1UpToD6aE_r96IkPpRSByw,6142
13
+ mermaid_trace/integrations/__init__.py,sha256=uU_8E1tlP327Fn79kvzlgEdoiIpQLsWJl3BgyqgsFMQ,104
14
+ mermaid_trace/integrations/fastapi.py,sha256=6LRs4Z508l38ymfj5SP39vOV6OLfYLRkpxyL_SxvudM,9483
15
+ mermaid_trace-0.5.3.post0.dist-info/METADATA,sha256=FR1kgM-wlTzrFasLpIeqbWbV_X3h3TwwUkxQCvgbvo0,9959
16
+ mermaid_trace-0.5.3.post0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
+ mermaid_trace-0.5.3.post0.dist-info/entry_points.txt,sha256=WS57KT_870v0A4B87QDjQUqJcddMQxbCQyYeczDAX34,57
18
+ mermaid_trace-0.5.3.post0.dist-info/licenses/LICENSE,sha256=BrBog1Etiq9PdWy0SVQNVByIMD9ss4Edz-R0oXt49zA,1062
19
+ mermaid_trace-0.5.3.post0.dist-info/RECORD,,
@@ -1,16 +0,0 @@
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,,