uipath-core 0.1.6__tar.gz → 0.1.8__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.
Files changed (60) hide show
  1. {uipath_core-0.1.6 → uipath_core-0.1.8}/.github/workflows/publish-dev.yml +16 -4
  2. {uipath_core-0.1.6 → uipath_core-0.1.8}/PKG-INFO +1 -1
  3. {uipath_core-0.1.6 → uipath_core-0.1.8}/pyproject.toml +1 -1
  4. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/decorators.py +36 -11
  5. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/span_utils.py +24 -2
  6. uipath_core-0.1.8/tests/tracing/test_span_nesting.py +650 -0
  7. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/tracing/test_traced.py +158 -0
  8. {uipath_core-0.1.6 → uipath_core-0.1.8}/uv.lock +1 -1
  9. uipath_core-0.1.6/tests/tracing/test_span_nesting.py +0 -298
  10. {uipath_core-0.1.6 → uipath_core-0.1.8}/.cursorrules +0 -0
  11. {uipath_core-0.1.6 → uipath_core-0.1.8}/.editorconfig +0 -0
  12. {uipath_core-0.1.6 → uipath_core-0.1.8}/.gitattributes +0 -0
  13. {uipath_core-0.1.6 → uipath_core-0.1.8}/.github/workflows/cd.yml +0 -0
  14. {uipath_core-0.1.6 → uipath_core-0.1.8}/.github/workflows/ci.yml +0 -0
  15. {uipath_core-0.1.6 → uipath_core-0.1.8}/.github/workflows/commitlint.yml +0 -0
  16. {uipath_core-0.1.6 → uipath_core-0.1.8}/.github/workflows/lint.yml +0 -0
  17. {uipath_core-0.1.6 → uipath_core-0.1.8}/.github/workflows/test.yml +0 -0
  18. {uipath_core-0.1.6 → uipath_core-0.1.8}/.gitignore +0 -0
  19. {uipath_core-0.1.6 → uipath_core-0.1.8}/.pre-commit-config.yaml +0 -0
  20. {uipath_core-0.1.6 → uipath_core-0.1.8}/.python-version +0 -0
  21. {uipath_core-0.1.6 → uipath_core-0.1.8}/.vscode/extensions.json +0 -0
  22. {uipath_core-0.1.6 → uipath_core-0.1.8}/.vscode/launch.json +0 -0
  23. {uipath_core-0.1.6 → uipath_core-0.1.8}/.vscode/settings.json +0 -0
  24. {uipath_core-0.1.6 → uipath_core-0.1.8}/CONTRIBUTING.md +0 -0
  25. {uipath_core-0.1.6 → uipath_core-0.1.8}/LICENSE +0 -0
  26. {uipath_core-0.1.6 → uipath_core-0.1.8}/README.md +0 -0
  27. {uipath_core-0.1.6 → uipath_core-0.1.8}/justfile +0 -0
  28. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/__init__.py +0 -0
  29. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/__init__.py +0 -0
  30. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/async_stream.py +0 -0
  31. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/citation.py +0 -0
  32. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/content.py +0 -0
  33. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/conversation.py +0 -0
  34. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/error.py +0 -0
  35. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/event.py +0 -0
  36. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/exchange.py +0 -0
  37. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/interrupt.py +0 -0
  38. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/message.py +0 -0
  39. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/meta.py +0 -0
  40. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/chat/tool.py +0 -0
  41. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/errors/__init__.py +0 -0
  42. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/errors/errors.py +0 -0
  43. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/guardrails/__init__.py +0 -0
  44. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/guardrails/_deterministic_guardrails_service.py +0 -0
  45. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/guardrails/_evaluators.py +0 -0
  46. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/guardrails/guardrails.py +0 -0
  47. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/py.typed +0 -0
  48. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/__init__.py +0 -0
  49. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/_utils.py +0 -0
  50. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/exporters.py +0 -0
  51. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/processors.py +0 -0
  52. {uipath_core-0.1.6 → uipath_core-0.1.8}/src/uipath/core/tracing/trace_manager.py +0 -0
  53. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/__init__.py +0 -0
  54. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/conftest.py +0 -0
  55. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/guardrails/test_deterministic_guardrails_service.py +0 -0
  56. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/tracing/test_external_integration.py +0 -0
  57. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/tracing/test_serialization.py +0 -0
  58. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/tracing/test_span_registry.py +0 -0
  59. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/tracing/test_trace_manager.py +0 -0
  60. {uipath_core-0.1.6 → uipath_core-0.1.8}/tests/tracing/test_tracing_utils.py +0 -0
@@ -60,9 +60,14 @@ jobs:
60
60
 
61
61
  Write-Output "Package version set to $DEV_VERSION"
62
62
 
63
+ $startMarker = "<!-- DEV_PACKAGE_START -->"
64
+ $endMarker = "<!-- DEV_PACKAGE_END -->"
65
+
63
66
  $dependencyMessage = @"
67
+ $startMarker
64
68
  ## Development Package
65
69
 
70
+ - Use ``uipath pack --nolock`` to get the latest dev build from this PR (requires version range).
66
71
  - Add this package as a dependency in your pyproject.toml:
67
72
 
68
73
  ``````toml
@@ -83,7 +88,13 @@ jobs:
83
88
 
84
89
  [tool.uv.sources]
85
90
  $PROJECT_NAME = { index = "testpypi" }
91
+
92
+ [tool.uv]
93
+ override-dependencies = [
94
+ "$PROJECT_NAME>=$MIN_VERSION,<$MAX_VERSION",
95
+ ]
86
96
  ``````
97
+ $endMarker
87
98
  "@
88
99
 
89
100
  # Get the owner and repo from the GitHub repository
@@ -101,10 +112,11 @@ jobs:
101
112
  $pr = Invoke-RestMethod -Uri $prUri -Method Get -Headers $headers
102
113
  $currentBody = $pr.body
103
114
 
104
- # Check if there's already a development package section
105
- if ($currentBody -match '## Development Package') {
106
- # Replace the existing section with the new dependency message
107
- $newBody = $currentBody -replace '## Development Package(\r?\n|.)*?(?=##|$)', $dependencyMessage
115
+ # Check if markers already exist in the PR description
116
+ $markerPattern = "(?s)$([regex]::Escape($startMarker)).*?$([regex]::Escape($endMarker))"
117
+ if ($currentBody -match $markerPattern) {
118
+ # Replace everything between markers (including markers)
119
+ $newBody = $currentBody -replace $markerPattern, $dependencyMessage
108
120
  } else {
109
121
  # Append the dependency message to the end of the description
110
122
  $newBody = if ($currentBody) { "$currentBody`n`n$dependencyMessage" } else { $dependencyMessage }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath-core
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: UiPath Core abstractions
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-core-python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "uipath-core"
3
- version = "0.1.6"
3
+ version = "0.1.8"
4
4
  description = "UiPath Core abstractions"
5
5
  readme = { file = "README.md", content-type = "text/markdown" }
6
6
  requires-python = ">=3.11"
@@ -6,8 +6,10 @@ import random
6
6
  from functools import wraps
7
7
  from typing import Any, Callable, Optional
8
8
 
9
+ from opentelemetry import context as context_api
9
10
  from opentelemetry import trace
10
- from opentelemetry.trace import NonRecordingSpan, SpanContext, TraceFlags
11
+ from opentelemetry.context import _SUPPRESS_INSTRUMENTATION_KEY
12
+ from opentelemetry.trace import SpanContext, TraceFlags
11
13
  from opentelemetry.trace.status import StatusCode
12
14
 
13
15
  from uipath.core.tracing._utils import (
@@ -15,7 +17,11 @@ from uipath.core.tracing._utils import (
15
17
  set_span_input_attributes,
16
18
  set_span_output_attributes,
17
19
  )
18
- from uipath.core.tracing.span_utils import UiPathSpanUtils
20
+ from uipath.core.tracing.span_utils import (
21
+ ParentedNonRecordingSpan,
22
+ UiPathSpanUtils,
23
+ _span_registry,
24
+ )
19
25
 
20
26
  logger = logging.getLogger(__name__)
21
27
 
@@ -48,7 +54,10 @@ def _opentelemetry_traced(
48
54
  trace_name = name or func.__name__
49
55
 
50
56
  def get_span():
57
+ ctx = UiPathSpanUtils.get_parent_context()
51
58
  if not recording:
59
+ parent_context = trace.get_current_span(ctx).get_span_context()
60
+
52
61
  # Create a valid but non-sampled trace context
53
62
  # Generate a valid trace ID (not INVALID)
54
63
  trace_id = random.getrandbits(128)
@@ -60,24 +69,30 @@ def _opentelemetry_traced(
60
69
  is_remote=False,
61
70
  trace_flags=TraceFlags(0x00), # NOT sampled
62
71
  )
63
- non_recording = NonRecordingSpan(non_sampled_context)
72
+ non_recording = ParentedNonRecordingSpan(
73
+ non_sampled_context, parent=parent_context
74
+ )
64
75
 
65
76
  # Make it active so children see it
66
77
  span_cm = trace.use_span(non_recording)
67
78
  span_cm.__enter__()
68
- return span_cm, non_recording
69
79
 
70
- # Normal recording span
71
- ctx = UiPathSpanUtils.get_parent_context()
72
- span_cm = trace.get_tracer(__name__).start_as_current_span(
73
- trace_name, context=ctx
74
- )
75
- span = span_cm.__enter__()
76
- return span_cm, span
80
+ _span_registry.register_span(non_recording)
81
+
82
+ return span_cm, non_recording
83
+ else:
84
+ # Normal recording span
85
+ span_cm = trace.get_tracer(__name__).start_as_current_span(
86
+ trace_name, context=ctx
87
+ )
88
+ span = span_cm.__enter__()
89
+ return span_cm, span
77
90
 
78
91
  # --------- Sync wrapper ---------
79
92
  @wraps(func)
80
93
  def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
94
+ if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
95
+ return func(*args, **kwargs)
81
96
  span_cm, span = get_span()
82
97
  try:
83
98
  # Set input attributes BEFORE execution
@@ -113,6 +128,8 @@ def _opentelemetry_traced(
113
128
  # --------- Async wrapper ---------
114
129
  @wraps(func)
115
130
  async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
131
+ if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
132
+ return await func(*args, **kwargs)
116
133
  span_cm, span = get_span()
117
134
  try:
118
135
  # Set input attributes BEFORE execution
@@ -148,6 +165,10 @@ def _opentelemetry_traced(
148
165
  # --------- Generator wrapper ---------
149
166
  @wraps(func)
150
167
  def generator_wrapper(*args: Any, **kwargs: Any) -> Any:
168
+ if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
169
+ for item in func(*args, **kwargs):
170
+ yield item
171
+ return
151
172
  span_cm, span = get_span()
152
173
  try:
153
174
  # Set input attributes BEFORE execution
@@ -186,6 +207,10 @@ def _opentelemetry_traced(
186
207
  # --------- Async generator wrapper ---------
187
208
  @wraps(func)
188
209
  async def async_generator_wrapper(*args: Any, **kwargs: Any) -> Any:
210
+ if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
211
+ async for item in func(*args, **kwargs):
212
+ yield item
213
+ return
189
214
  span_cm, span = get_span()
190
215
  try:
191
216
  # Set input attributes BEFORE execution
@@ -4,11 +4,33 @@ import logging
4
4
  from typing import Callable, Optional
5
5
 
6
6
  from opentelemetry import context, trace
7
- from opentelemetry.trace import Span, set_span_in_context
7
+ from opentelemetry.trace import NonRecordingSpan, Span, set_span_in_context
8
8
 
9
9
  logger = logging.getLogger(__name__)
10
10
 
11
11
 
12
+ class ParentedNonRecordingSpan(NonRecordingSpan):
13
+ """Non-recording span with explicit parent tracking.
14
+
15
+ Extends NonRecordingSpan to include a parent attribute, allowing the SpanRegistry
16
+ to properly track parent-child relationships for non-recording spans.
17
+ This is necessary because NonRecordingSpan instances created directly don't have
18
+ their parent automatically set like normal recording spans do.
19
+ """
20
+
21
+ def __init__(
22
+ self, context: trace.SpanContext, parent: Optional[trace.SpanContext] = None
23
+ ):
24
+ """Initialize a parented non-recording span.
25
+
26
+ Args:
27
+ context: The SpanContext for this span
28
+ parent: Optional parent SpanContext
29
+ """
30
+ super().__init__(context)
31
+ self.parent = parent
32
+
33
+
12
34
  class SpanRegistry:
13
35
  """Registry to track all spans and their parent relationships."""
14
36
 
@@ -309,4 +331,4 @@ class UiPathSpanUtils:
309
331
  return UiPathSpanUtils._current_span_ancestors_provider
310
332
 
311
333
 
312
- __all__ = ["UiPathSpanUtils"]
334
+ __all__ = ["ParentedNonRecordingSpan", "UiPathSpanUtils"]