uipath 0.0.1__py3-none-any.whl → 1.0.0__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.

Potentially problematic release.


This version of uipath might be problematic. Click here for more details.

uipath/__init__.py CHANGED
@@ -1 +1,9 @@
1
- from .sequence import Sequence
1
+ from uipath.__version__ import __version__
2
+ from uipath.auth.authentication import UiPathAuth
3
+ from uipath.client.api_client import UiPathClient
4
+
5
+ __all__ = [
6
+ '__version__',
7
+ 'UiPathAuth',
8
+ 'UiPathClient',
9
+ ]
uipath/__version__.py ADDED
@@ -0,0 +1,3 @@
1
+ VERSION = (1, 0, 0)
2
+
3
+ __version__ = '.'.join(map(str, VERSION))
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019 christianblandford
3
+ Copyright (c) 2024 Your Name
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
@@ -0,0 +1,181 @@
1
+ Metadata-Version: 2.2
2
+ Name: uipath
3
+ Version: 1.0.0
4
+ Summary: A Python SDK for UiPath
5
+ Home-page: https://github.com/christianblandford/uipath
6
+ Author: Christian Blandford
7
+ Author-email: christianblandford@me.com
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.7
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: requests>=2.25.0
23
+ Requires-Dist: typing-extensions>=4.0.0; python_version < "3.8"
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=6.0; extra == "dev"
26
+ Requires-Dist: pytest-cov>=2.0; extra == "dev"
27
+ Requires-Dist: black>=22.0; extra == "dev"
28
+ Requires-Dist: isort>=5.0; extra == "dev"
29
+ Requires-Dist: mypy>=0.900; extra == "dev"
30
+ Requires-Dist: flake8>=3.9; extra == "dev"
31
+ Dynamic: author
32
+ Dynamic: author-email
33
+ Dynamic: classifier
34
+ Dynamic: description
35
+ Dynamic: description-content-type
36
+ Dynamic: home-page
37
+ Dynamic: provides-extra
38
+ Dynamic: requires-dist
39
+ Dynamic: requires-python
40
+ Dynamic: summary
41
+
42
+ # UiPath Python SDK
43
+
44
+ A Python SDK for interacting with UiPath's APIs. This SDK provides a simple and intuitive way to automate UiPath operations programmatically.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install uipath
50
+ ```
51
+
52
+ ## Quick Start
53
+
54
+ ```python
55
+ from uipath.auth.authentication import UiPathAuth
56
+ from uipath.client.api_client import UiPathClient
57
+ from uipath.resources.robots import RobotsResource
58
+
59
+ # Initialize authentication
60
+ auth = UiPathAuth(
61
+ tenant_name="your_tenant",
62
+ client_id="your_client_id",
63
+ client_secret="your_client_secret"
64
+ )
65
+
66
+ # Create API client
67
+ client = UiPathClient(auth)
68
+
69
+ # Use the robots resource
70
+ robots = RobotsResource(client)
71
+
72
+ # List all robots
73
+ all_robots = robots.list_robots()
74
+ ```
75
+
76
+ ## Features
77
+
78
+ - Simple, intuitive interface for UiPath APIs
79
+ - Authentication handling
80
+ - Comprehensive error handling
81
+ - Type hints for better IDE support
82
+ - Resource classes for all major UiPath entities:
83
+ - Robots
84
+ - Jobs
85
+ - Processes
86
+ - Assets
87
+ - And more...
88
+
89
+ ## Authentication
90
+
91
+ The SDK supports client credentials authentication. You'll need:
92
+ - Tenant name
93
+ - Client ID
94
+ - Client secret
95
+
96
+ You can obtain these credentials from your UiPath Orchestrator account under Admin → API Access.
97
+
98
+ ```python
99
+ auth = UiPathAuth(
100
+ tenant_name="your_tenant",
101
+ client_id="your_client_id",
102
+ client_secret="your_client_secret",
103
+ scope="OR.Default" # Optional, defaults to OR.Default
104
+ )
105
+ ```
106
+
107
+ ## Usage Examples
108
+
109
+ ### Working with Robots
110
+
111
+ ```python
112
+ # List all robots
113
+ robots = RobotsResource(client)
114
+ all_robots = robots.list_robots()
115
+
116
+ # Get a specific robot
117
+ robot = robots.get_robot(robot_id=123)
118
+
119
+ # Create a new robot
120
+ new_robot = robots.create_robot(
121
+ name="MyNewRobot",
122
+ machine_name="DESKTOP-123",
123
+ type="Unattended"
124
+ )
125
+ ```
126
+
127
+ ### Error Handling
128
+
129
+ The SDK provides custom exceptions for different types of errors:
130
+
131
+ ```python
132
+ from uipath.exceptions.exceptions import AuthenticationError, ApiError
133
+
134
+ try:
135
+ robots.get_robot(robot_id=999)
136
+ except AuthenticationError as e:
137
+ print("Authentication failed:", e)
138
+ except ApiError as e:
139
+ print("API request failed:", e)
140
+ ```
141
+
142
+ ## Configuration
143
+
144
+ The SDK can be configured with custom endpoints and API versions:
145
+
146
+ ```python
147
+ client = UiPathClient(
148
+ auth,
149
+ base_url="https://cloud.uipath.com", # Custom base URL
150
+ api_version="v1" # API version
151
+ )
152
+ ```
153
+
154
+ ## Contributing
155
+
156
+ Contributions are welcome! Please feel free to submit a Pull Request.
157
+
158
+ 1. Fork the repository
159
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
160
+ 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
161
+ 4. Push to the branch (`git push origin feature/AmazingFeature`)
162
+ 5. Open a Pull Request
163
+
164
+ ## License
165
+
166
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
167
+
168
+ ## Support
169
+
170
+ If you encounter any problems or have questions, please:
171
+ 1. Check the [documentation](docs/)
172
+ 2. Open an issue in the GitHub repository
173
+
174
+ ## Requirements
175
+
176
+ - Python 3.7+
177
+ - requests library
178
+
179
+ ## Disclaimer
180
+
181
+ This is an unofficial SDK and is not affiliated with, maintained, authorized, endorsed, or sponsored by UiPath.
@@ -0,0 +1,7 @@
1
+ uipath/__init__.py,sha256=j2gsFvg5BudvoZxfNncyip-FBq9PqdM39hvCJzS6k0k,215
2
+ uipath/__version__.py,sha256=Q1SV_A_xAMGhRrDOq-kOmB2-vbVwqaYR7R11-BM4jq8,63
3
+ uipath-1.0.0.dist-info/LICENSE,sha256=FyuBsNr3YLXHPRQfWIpCAC4brUeSdYelr01V-Fkog8U,1066
4
+ uipath-1.0.0.dist-info/METADATA,sha256=r9uU1FkrqU8Lkyb7l-GqA1pzys9E4VaActrh878pzoM,4536
5
+ uipath-1.0.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
6
+ uipath-1.0.0.dist-info/top_level.txt,sha256=cO-fuTo_YlozqaZ6VNk0ST79wuBjLkcTRzYpXLM6rRg,7
7
+ uipath-1.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
- Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.33.1)
3
- Root-Is-Purelib: true
4
- Tag: py3-none-any
5
-
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
uipath/sequence.py DELETED
@@ -1,483 +0,0 @@
1
- from bs4 import BeautifulSoup
2
-
3
- class Sequence:
4
- def __init__(self, file):
5
- self.file = file
6
-
7
- self.init_vars() # load all the vars from the xaml file
8
-
9
- #Initializes all variables for the class file
10
- def init_vars(self):
11
- self.xaml = self.read_xaml() # Read xaml file
12
- self.name = self.get_class_name() # get class name from XAML file
13
- self.arguments = self.build_arguments(self.get_arguments())
14
- self.sequences = self.create_sequences(self.get_sequences())
15
-
16
- #Gets the existing XAML
17
- def get_xaml(self):
18
- return self.xaml
19
-
20
- #Reads an XAML file
21
- def read_xaml(self):
22
- infile = open(self.file, "r")
23
- data = infile.read()
24
- infile.close()
25
-
26
- data = data[data.find("<"):len(data)] # remove garbage from start of file
27
- xaml = BeautifulSoup(data, "xml");
28
- return xaml
29
-
30
- #Updates a node of the XAML stored in memory
31
- def update_xaml_node(self, node, new_xaml):
32
- self.xaml = new_xaml
33
- self.save()
34
-
35
- #Saves the raw XAML in memory to the XAML file
36
- def save(self):
37
- #First we need to strip the <XML> tag that our xaml parser adds
38
- xml_string = '<?xml version="1.0" encoding="utf-8"?>\n' # The XML encoding tag we need to remove
39
- data = str(self.xaml).replace(xml_string, "", 1)
40
-
41
- file = open(self.file,"w+")
42
- file.write(str(data))
43
- file.close()
44
-
45
- return file
46
-
47
- #Get classname from raw XAML
48
- def get_class_name(self):
49
- return self.xaml.find_all("Activity")[0]["x:Class"]
50
-
51
- #Sets a class name for the file
52
- def set_class_name(self, new_name):
53
- self.xaml.find("Activity")["x:Class"] = new_name
54
- self.save()
55
- return new_name
56
-
57
- #Returns the first sequece/block/whatever in the class. The outmost layer
58
- def get_first_block(self):
59
- return self.xaml.find("TextExpression.ReferencesForImplementation").next_sibling.next_sibling
60
-
61
- #Get annotation for node
62
- def get_annotation(self, node):
63
- return node["sap2010:Annotation.AnnotationText"]
64
-
65
- #Set annotation for node
66
- def set_annotation(self, node, text):
67
- node["sap2010:Annotation.AnnotationText"] = text
68
- self.save()
69
-
70
- #Gets node name
71
- def get_node_name(self, node):
72
- return node["DisplayName"]
73
-
74
- #Sets node name
75
- def set_node_name(self, node, new_name):
76
- node["DisplayName"] = new_name
77
- return new_name
78
-
79
- #Returns an argument by name
80
- def get_argument_by_name(self, name):
81
- if not self.arguments is None:
82
- for item in self.arguments:
83
- if item.name == name:
84
- return item
85
-
86
- #Gets arguments of sequence
87
- def get_arguments(self):
88
- return self.xaml.find_all("x:Property")
89
-
90
- #Builds the argument objects for the main class
91
- def build_arguments(self, argument_list):
92
- if not argument_list is None and len(argument_list) > 0:
93
- args = []
94
- for item in argument_list:
95
- args.append(Sequence.Argument(self, item))
96
- return args
97
-
98
- #Creates and adds a new argument for the sequence
99
- def add_argument(self, name, string_direction, datatype):
100
- new_arg = self.xaml.new_tag("x:Property")
101
- new_arg["Name"] = name
102
-
103
- #build XAML friendly variables for the passed in arguments
104
- new_arg_type_end = ")"
105
- if string_direction == "in":
106
- new_arg_type_start = "InArgument("
107
- elif string_direction == "out":
108
- new_arg_type_start = "OutArgument("
109
- elif string_direction == "io":
110
- new_arg_type_start = "InOutArgument("
111
- else:
112
- new_arg_type_end = ""
113
- new_arg_type_start = ""
114
-
115
- # Type="InArgument(scg:Dictionary(x:String, x:Object))"
116
- new_arg["Type"] = new_arg_type_start + datatype + new_arg_type_end
117
-
118
- #Add to array in XAML
119
- self.xaml.find("x:Members").append(new_arg)
120
- #Rebuild all arguments from the XAML
121
- self.arguments = self.build_arguments(self.get_arguments())
122
-
123
- self.save()
124
-
125
- #Gets a block by its Displayname
126
- def get_node_by_display_name(self, display_name):
127
- return self.xaml.find(DisplayName=display_name)
128
-
129
- #Gets nested sequences
130
- def get_sequences(self):
131
- return self.xaml.find_all("Sequence")
132
-
133
- #Builds the argument objects for the main class
134
- def create_sequences(self, sequence_list):
135
- if not sequence_list is None and len(sequence_list) > 0:
136
- sequences = []
137
- for item in sequence_list:
138
- sequences.append(Sequence.Inner_Sequence(self, item))
139
- return sequences
140
-
141
-
142
- #To String.
143
- def __str__(self):
144
- to_return = "{" + "\n"
145
- for key in self.__dict__.keys():
146
- if key != "xaml":
147
- if isinstance(self.__dict__[key], (list,)):
148
- to_return = to_return + "\t" + key + ": [" + "\n"
149
- for item in self.__dict__[key]:
150
- to_return = to_return + "\t\t" + str(item) + "\n"
151
- to_return = to_return + "\t]" + "\n"
152
- else:
153
- to_return = to_return + "\t" + key + ":" + str(self.__dict__[key]) + "\n"
154
-
155
- to_return = to_return + "}"
156
- return to_return
157
-
158
- #-----------------------------------------------------------------------------------------------------------------------
159
- # Subclass: Variable
160
- # Description: Stores the data about a variable in a sequence
161
- #-----------------------------------------------------------------------------------------------------------------------
162
- class Variable():
163
- def __init__(self, parent=None, xaml = None, name=None, type_arg=None, default=None):
164
- self.parent = parent #Store the calling sequence
165
-
166
- #If xaml was passed in just use that
167
- self.xaml = xaml
168
- if not self.xaml is None:
169
- self.name = self.xaml["Name"]
170
- self.type = self.xaml["x:TypeArguments"]
171
- #Else build new xaml based on the name and type passed in
172
- else:
173
- self.name = name
174
- self.type = type_arg
175
- self.default = default
176
- self.xaml = self.build_xaml()
177
-
178
- #Builds XAML for a name and type
179
- def build_xaml(self):
180
- new_node = self.parent.xaml.new_tag("Variable") # have the beautiful soup instance from the parent create a new tag
181
- new_node["Name"] = self.name
182
- new_node["x:TypeArguments"] = self.type
183
- if not self.default is None:
184
- new_node["Default"] = self.default
185
- return new_node
186
-
187
- #-----------------------------------------------------------------------------------------------------------------------
188
- # Subclass: Argument
189
- # Description: Stores the arguments and their default values from the xaml file
190
- #-----------------------------------------------------------------------------------------------------------------------
191
-
192
- #Define subclass for the arguments
193
- class Argument():
194
- def __init__(self, outer_sequence, xaml, default_value=None):
195
- self.outer_sequence = outer_sequence #the containing sequence
196
-
197
- self.xaml = xaml
198
- self.init_vars()
199
- self.default_value = self.get_default_value_for_attr()
200
-
201
-
202
- #Creates a new argument
203
-
204
- #Get default value for attribute
205
- def get_default_value_for_attr(self):
206
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
207
- key = "this:" + self.outer_sequence.name + "." + self.name
208
-
209
- if key in values_string:
210
- return values_string["this:" + self.outer_sequence.name + "." + self.name]
211
-
212
- #Decodes XAML into python friendly strings
213
- def init_vars(self):
214
- self.name = self.xaml["Name"]
215
- self.direction = self.get_direction_from_xaml()
216
- self.type = self.get_datatype_from_xaml()
217
-
218
- #Converts string direction to xaml direction
219
- def convert_string_direction_to_xaml(self, string_direction):
220
- if string_direction == "in":
221
- return "InArgument"
222
- elif string_direction == "out":
223
- return "OutArgument"
224
- elif string_direction == "io":
225
- return "InOutArgument"
226
- else:
227
- return "Property"
228
-
229
- #Gets direction of argument
230
- def get_direction_from_xaml(self):
231
- temp = self.xaml["Type"]
232
-
233
- if "InArgument" in temp:
234
- return "InArgument"
235
- elif "OutArgument" in temp:
236
- return "OutArgument"
237
- elif "InOutArgument" in temp:
238
- return "InOutArgument"
239
- else:
240
- return "Property"
241
-
242
- #Gets the datatype of the argument
243
- def get_datatype_from_xaml(self):
244
- return self.xaml["Type"].replace("(", "").replace(")", "").replace(self.direction, "")
245
-
246
- #Sets a new name value for this Class instance, as well as updating the parent raw XAML.
247
- def set_name(self, new_name):
248
- self.update_default_value_name(self.name, new_name)
249
- self.xaml["Name"] = new_name
250
- self.name = new_name
251
- self.update_outer_sequence()
252
-
253
-
254
- #Sets a new direction value for this Class instance, as well as updating the parent raw XAML.
255
- def set_direction(self, direction_string):
256
- self.direction = direction_string #update class' variable
257
-
258
- new_direction_xaml = ""
259
- if self.direction == "InArgument":
260
- new_direction_xaml = "InArgument(" + self.type + ")"
261
- elif self.direction == "InOutArgument":
262
- self.delete_default_value() #delete default value as it is not supported by this direction type
263
- new_direction_xaml = "InOutArgument(" + self.type + ")"
264
- elif self.direction == "OutArgument":
265
- self.delete_default_value() #delete default value as it is not supported by this direction type
266
- new_direction_xaml = "OutArgument(" + self.type + ")"
267
- else:
268
- new_direction_xaml = self.type
269
-
270
- self.xaml["Type"] = new_direction_xaml
271
- self.update_outer_sequence()
272
-
273
- #Creates a default value when one does not yet exist
274
- #STUB
275
-
276
- #Sets a new default value for this Class instance, as well as updating the parent raw XAML.
277
- def update_default_value(self, new_value):
278
- self.default_value = new_value
279
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
280
- values_string["this:" + self.outer_sequence.name + "." + self.name] = new_value
281
- self.update_outer_sequence()
282
-
283
- #Changes the name of default values to match the argument name when it is changed
284
- def update_default_value_name(self, old_name, new_name):
285
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
286
- key = "this:" + self.outer_sequence.name + "." + self.name
287
-
288
- if key in values_string:
289
- self.delete_default_value()
290
- values_string["this:" + self.outer_sequence.name + "." + new_name] = self.default_value
291
- #values_string["this:" + self.outer_sequence.name + "." + self.name] = new_value
292
-
293
- #Deletes the default value
294
- def delete_default_value(self):
295
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
296
- key = "this:" + self.outer_sequence.name + "." + self.name
297
-
298
- if key in values_string:
299
- del self.outer_sequence.xaml.find_all("Activity")[0]["this:" + self.outer_sequence.name + "." + self.name]
300
-
301
- if not self.default_value is None:
302
- del self.default_value
303
-
304
- #Update parent Sequence XAML. Do this when using any setter method defined above
305
- def update_outer_sequence(self):
306
- #if not self.outer_sequence.xaml.find(attrs={"Name":self.name})["Name"] is None:
307
- self.outer_sequence.xaml.find(attrs={"Name":self.name}).replace_with(self.xaml)
308
- self.outer_sequence.save()
309
-
310
- #override to string method
311
- def __str__(self):
312
- if self.default_value is None: # check if self has default_value
313
- return "{name: \"" + self.name + "\", direction: \"" + self.direction + "\", type: \"" + self.type + "\"}"
314
- else:
315
- return "{name: \"" + self.name + "\", direction: \"" + self.direction + "\", type: \"" + self.type + "\", default_value: \"" + self.default_value + "\"}"
316
-
317
-
318
- #-----------------------------------------------------------------------------------------------------------------------
319
- # Subclass: Argument
320
- # Description: Stores the arguments and their default values from the xaml file
321
- #-----------------------------------------------------------------------------------------------------------------------
322
-
323
- #Define subclass for the arguments
324
- class Inner_Sequence():
325
- def __init__(self, outer_sequence, xaml):
326
- self.outer_sequence = outer_sequence
327
- self.xaml = xaml
328
- self.id = xaml["sap2010:WorkflowViewState.IdRef"]
329
- self.get_invoked_workflow()
330
- self.variables = self.get_sequence_variables()
331
-
332
- #Get the invoked workflow for the sequences, if applicable
333
- def get_invoked_workflow(self):
334
- self.invoked_workflow = self.xaml.find("ui:InvokeWorkflowFile")
335
-
336
- if not self.invoked_workflow is None:
337
- #Get path to invoked workflow
338
- self.invoked_workflow_path = self.invoked_workflow["WorkflowFileName"]
339
-
340
- #get arguments of invoked workflow
341
- self.invoked_workflow_arguments_xaml = self.invoked_workflow.find("ui:InvokeWorkflowFile.Arguments")
342
-
343
- if len(self.invoked_workflow_arguments_xaml.findChildren()) > 0:
344
- self.invoked_workflow_arguments = []
345
- for index,child in enumerate(self.invoked_workflow_arguments_xaml.findChildren()):
346
- self.invoked_workflow_arguments.append(Sequence.Inner_Sequence.Invoked_Workflow_Argument(self, child, index))
347
-
348
- #Get variables in this sequence
349
- def get_sequence_variables(self):
350
- vars_from_xaml = self.xaml.find_all("Variable")
351
-
352
- #If there are any variables, we will build an array of variable objects and return them
353
- if len(vars_from_xaml) > 0:
354
- all_vars = []
355
-
356
- for item in self.xaml.find_all("Variable"):
357
- all_vars.append(self.outer_sequence.Variable(self.outer_sequence, xaml=item))
358
-
359
- return all_vars
360
-
361
- #Add variable to sequence
362
- def create_variable(self, xaml=None, name=None, type=None, default=None):
363
- #If xaml is None, build new BS node
364
- if xaml is None:
365
- xaml = self.outer_sequence.xaml.new_tag("Variable")
366
- xaml["Name"] = name
367
- xaml["x:TypeArguments"] = type
368
-
369
- if not default is None:
370
- xaml["Default"] = default
371
-
372
- self.xaml.find("Sequence.Variables").append(xaml) #Add new variable to xaml file
373
- self.variables = self.get_sequence_variables() #Regenerate vars from xaml
374
- self.update_outer_sequence()
375
-
376
- return xaml #return the new variable
377
-
378
- #Deletes a variable by name
379
- def delete_variable(self, var_name):
380
- self.xaml.find_all("Variable", Name=var_name)[0].decompose() #Deletes the variable from the XAML
381
- self.variables = self.get_sequence_variables() #Regenerate vars from xaml
382
- self.update_outer_sequence()
383
-
384
-
385
- #Imports arguments from invoked function. Just like the button in UiPath
386
- def import_arguments(self):
387
- #Clear the array of invoked workflow argument objects
388
- self.invoked_workflow_arguments = []
389
- self.invoked_workflow_arguments_xaml.clear()
390
- #clear the array of
391
- invoked_sequence = Sequence(self.invoked_workflow_path) #Load the invoked sequence
392
-
393
- #Create new nodes for each of the imported arguments
394
- for index,item in enumerate(invoked_sequence.arguments):
395
- #Determine new node type
396
- new_node_type = item.direction
397
-
398
- #build a new Invoked_Workflow_Argument object
399
- new_node = self.outer_sequence.xaml.new_tag(new_node_type) # have the beautiful soup instance from the parent create a new tag
400
- new_node["x:Key"] = item.name
401
- new_node["x:TypeArguments"] = item.type
402
- new_node.string = "" #Add this so BS adds a closing tag
403
-
404
- #Add it to this sequence's invoked workflow arguments
405
- self.invoked_workflow_arguments.append(Sequence.Inner_Sequence.Invoked_Workflow_Argument(self, new_node, index))
406
- #Add new node to the invoked_arguments_xaml
407
- self.invoked_workflow_arguments_xaml.append(new_node)
408
-
409
- self.update_outer_sequence()
410
- return self.invoked_workflow_arguments
411
-
412
- #Update parent Sequence XAML. Do this when using any setter method defined above
413
- def update_outer_sequence(self):
414
- #if not self.outer_sequence.xaml.find(attrs={"Name":self.name})["Name"] is None:
415
- self.outer_sequence.xaml.find(attrs={"sap2010:WorkflowViewState.IdRef":self.id}).replace_with(self.xaml)
416
- self.outer_sequence.save()
417
-
418
-
419
- #Define inner class for invoked_argument
420
- class Invoked_Workflow_Argument():
421
- def __init__(self, parent, xaml, index):
422
- self.parent = parent
423
- self.xaml = xaml
424
- self.name = xaml.name
425
- self.index = index
426
- self.key = self.xaml["x:Key"]
427
- self.type = self.xaml["x:TypeArguments"]
428
- self.value = self.xaml.getText()
429
- self.value_type = "value" # if the value is a pre-entered value and not a variable
430
-
431
- #Check if the value is a variable (denoted by square braces)
432
- if "[" in self.value:
433
- self.value = self.value[1:(len(self.value) - 1)]
434
- self.value_type = "variable"
435
-
436
- #Change the value of the argument (passing a value, not a variable)
437
- def set_value(self, new_value):
438
- self.value = new_value
439
- self.value_type = "value"
440
- self.xaml.string = new_value
441
- self.update_parent()
442
-
443
- #Change the value of the argument (the variable that is entered)
444
- def set_value_to_variable(self, variable):
445
- self.value = variable
446
- self.value_type = "variable"
447
- self.xaml.string = "[" + variable + "]"
448
- self.update_parent()
449
-
450
- #Change the key that the argument is pointing to
451
- def set_key(self, new_value):
452
- self.key = new_value
453
- self.xaml["x:Key"] = new_value
454
- self.update_parent()
455
-
456
- #Change the data type of the argument
457
- def set_type(self, new_type):
458
- if new_type == "InArgument":
459
- self.name = "InArgument"
460
- self.xaml.name = "InArgument"
461
- elif new_type == "OutArgument":
462
- self.name = "OutArgument"
463
- self.xaml.name = "OutArgument"
464
- elif new_type == "InOutArgument":
465
- self.name = "InOutArgument"
466
- self.xaml.name = "InOutArgument"
467
- self.update_parent()
468
-
469
-
470
-
471
- #Update parent Sequence XAML. Do this when using any setter method defined above
472
- def update_parent(self):
473
- self.parent.invoked_workflow.find("ui:InvokeWorkflowFile.Arguments").findChildren()[self.index].replace_with(self.xaml)
474
- self.parent.update_outer_sequence()
475
-
476
-
477
-
478
-
479
-
480
-
481
-
482
-
483
-
uipath/uipath.py DELETED
@@ -1,483 +0,0 @@
1
- from bs4 import BeautifulSoup
2
-
3
- class Sequence:
4
- def __init__(self, file):
5
- self.file = file
6
-
7
- self.init_vars() # load all the vars from the xaml file
8
-
9
- #Initializes all variables for the class file
10
- def init_vars(self):
11
- self.xaml = self.read_xaml() # Read xaml file
12
- self.name = self.get_class_name() # get class name from XAML file
13
- self.arguments = self.build_arguments(self.get_arguments())
14
- self.sequences = self.create_sequences(self.get_sequences())
15
-
16
- #Gets the existing XAML
17
- def get_xaml(self):
18
- return self.xaml
19
-
20
- #Reads an XAML file
21
- def read_xaml(self):
22
- infile = open(self.file, "r")
23
- data = infile.read()
24
- infile.close()
25
-
26
- data = data[data.find("<"):len(data)] # remove garbage from start of file
27
- xaml = BeautifulSoup(data, "xml");
28
- return xaml
29
-
30
- #Updates a node of the XAML stored in memory
31
- def update_xaml_node(self, node, new_xaml):
32
- self.xaml = new_xaml
33
- self.save()
34
-
35
- #Saves the raw XAML in memory to the XAML file
36
- def save(self):
37
- #First we need to strip the <XML> tag that our xaml parser adds
38
- xml_string = '<?xml version="1.0" encoding="utf-8"?>\n' # The XML encoding tag we need to remove
39
- data = str(self.xaml).replace(xml_string, "", 1)
40
-
41
- file = open(self.file,"w+")
42
- file.write(str(data))
43
- file.close()
44
-
45
- return file
46
-
47
- #Get classname from raw XAML
48
- def get_class_name(self):
49
- return self.xaml.find_all("Activity")[0]["x:Class"]
50
-
51
- #Sets a class name for the file
52
- def set_class_name(self, new_name):
53
- self.xaml.find("Activity")["x:Class"] = new_name
54
- self.save()
55
- return new_name
56
-
57
- #Returns the first sequece/block/whatever in the class. The outmost layer
58
- def get_first_block(self):
59
- return self.xaml.find("TextExpression.ReferencesForImplementation").next_sibling.next_sibling
60
-
61
- #Get annotation for node
62
- def get_annotation(self, node):
63
- return node["sap2010:Annotation.AnnotationText"]
64
-
65
- #Set annotation for node
66
- def set_annotation(self, node, text):
67
- node["sap2010:Annotation.AnnotationText"] = text
68
- self.save()
69
-
70
- #Gets node name
71
- def get_node_name(self, node):
72
- return node["DisplayName"]
73
-
74
- #Sets node name
75
- def set_node_name(self, node, new_name):
76
- node["DisplayName"] = new_name
77
- return new_name
78
-
79
- #Returns an argument by name
80
- def get_argument_by_name(self, name):
81
- if not self.arguments is None:
82
- for item in self.arguments:
83
- if item.name == name:
84
- return item
85
-
86
- #Gets arguments of sequence
87
- def get_arguments(self):
88
- return self.xaml.find_all("x:Property")
89
-
90
- #Builds the argument objects for the main class
91
- def build_arguments(self, argument_list):
92
- if not argument_list is None and len(argument_list) > 0:
93
- args = []
94
- for item in argument_list:
95
- args.append(Sequence.Argument(self, item))
96
- return args
97
-
98
- #Creates and adds a new argument for the sequence
99
- def add_argument(self, name, string_direction, datatype):
100
- new_arg = self.xaml.new_tag("x:Property")
101
- new_arg["Name"] = name
102
-
103
- #build XAML friendly variables for the passed in arguments
104
- new_arg_type_end = ")"
105
- if string_direction == "in":
106
- new_arg_type_start = "InArgument("
107
- elif string_direction == "out":
108
- new_arg_type_start = "OutArgument("
109
- elif string_direction == "io":
110
- new_arg_type_start = "InOutArgument("
111
- else:
112
- new_arg_type_end = ""
113
- new_arg_type_start = ""
114
-
115
- # Type="InArgument(scg:Dictionary(x:String, x:Object))"
116
- new_arg["Type"] = new_arg_type_start + datatype + new_arg_type_end
117
-
118
- #Add to array in XAML
119
- self.xaml.find("x:Members").append(new_arg)
120
- #Rebuild all arguments from the XAML
121
- self.arguments = self.build_arguments(self.get_arguments())
122
-
123
- self.save()
124
-
125
- #Gets a block by its Displayname
126
- def get_node_by_display_name(self, display_name):
127
- return self.xaml.find(DisplayName=display_name)
128
-
129
- #Gets nested sequences
130
- def get_sequences(self):
131
- return self.xaml.find_all("Sequence")
132
-
133
- #Builds the argument objects for the main class
134
- def create_sequences(self, sequence_list):
135
- if not sequence_list is None and len(sequence_list) > 0:
136
- sequences = []
137
- for item in sequence_list:
138
- sequences.append(Sequence.Inner_Sequence(self, item))
139
- return sequences
140
-
141
-
142
- #To String.
143
- def __str__(self):
144
- to_return = "{" + "\n"
145
- for key in self.__dict__.keys():
146
- if key != "xaml":
147
- if isinstance(self.__dict__[key], (list,)):
148
- to_return = to_return + "\t" + key + ": [" + "\n"
149
- for item in self.__dict__[key]:
150
- to_return = to_return + "\t\t" + str(item) + "\n"
151
- to_return = to_return + "\t]" + "\n"
152
- else:
153
- to_return = to_return + "\t" + key + ":" + str(self.__dict__[key]) + "\n"
154
-
155
- to_return = to_return + "}"
156
- return to_return
157
-
158
- #-----------------------------------------------------------------------------------------------------------------------
159
- # Subclass: Variable
160
- # Description: Stores the data about a variable in a sequence
161
- #-----------------------------------------------------------------------------------------------------------------------
162
- class Variable():
163
- def __init__(self, parent=None, xaml = None, name=None, type_arg=None, default=None):
164
- self.parent = parent #Store the calling sequence
165
-
166
- #If xaml was passed in just use that
167
- self.xaml = xaml
168
- if not self.xaml is None:
169
- self.name = self.xaml["Name"]
170
- self.type = self.xaml["x:TypeArguments"]
171
- #Else build new xaml based on the name and type passed in
172
- else:
173
- self.name = name
174
- self.type = type_arg
175
- self.default = default
176
- self.xaml = self.build_xaml()
177
-
178
- #Builds XAML for a name and type
179
- def build_xaml(self):
180
- new_node = self.parent.xaml.new_tag("Variable") # have the beautiful soup instance from the parent create a new tag
181
- new_node["Name"] = self.name
182
- new_node["x:TypeArguments"] = self.type
183
- if not self.default is None:
184
- new_node["Default"] = self.default
185
- return new_node
186
-
187
- #-----------------------------------------------------------------------------------------------------------------------
188
- # Subclass: Argument
189
- # Description: Stores the arguments and their default values from the xaml file
190
- #-----------------------------------------------------------------------------------------------------------------------
191
-
192
- #Define subclass for the arguments
193
- class Argument():
194
- def __init__(self, outer_sequence, xaml, default_value=None):
195
- self.outer_sequence = outer_sequence #the containing sequence
196
-
197
- self.xaml = xaml
198
- self.init_vars()
199
- self.default_value = self.get_default_value_for_attr()
200
-
201
-
202
- #Creates a new argument
203
-
204
- #Get default value for attribute
205
- def get_default_value_for_attr(self):
206
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
207
- key = "this:" + self.outer_sequence.name + "." + self.name
208
-
209
- if key in values_string:
210
- return values_string["this:" + self.outer_sequence.name + "." + self.name]
211
-
212
- #Decodes XAML into python friendly strings
213
- def init_vars(self):
214
- self.name = self.xaml["Name"]
215
- self.direction = self.get_direction_from_xaml()
216
- self.type = self.get_datatype_from_xaml()
217
-
218
- #Converts string direction to xaml direction
219
- def convert_string_direction_to_xaml(self, string_direction):
220
- if string_direction == "in":
221
- return "InArgument"
222
- elif string_direction == "out":
223
- return "OutArgument"
224
- elif string_direction == "io":
225
- return "InOutArgument"
226
- else:
227
- return "Property"
228
-
229
- #Gets direction of argument
230
- def get_direction_from_xaml(self):
231
- temp = self.xaml["Type"]
232
-
233
- if "InArgument" in temp:
234
- return "InArgument"
235
- elif "OutArgument" in temp:
236
- return "OutArgument"
237
- elif "InOutArgument" in temp:
238
- return "InOutArgument"
239
- else:
240
- return "Property"
241
-
242
- #Gets the datatype of the argument
243
- def get_datatype_from_xaml(self):
244
- return self.xaml["Type"].replace("(", "").replace(")", "").replace(self.direction, "")
245
-
246
- #Sets a new name value for this Class instance, as well as updating the parent raw XAML.
247
- def set_name(self, new_name):
248
- self.update_default_value_name(self.name, new_name)
249
- self.xaml["Name"] = new_name
250
- self.name = new_name
251
- self.update_outer_sequence()
252
-
253
-
254
- #Sets a new direction value for this Class instance, as well as updating the parent raw XAML.
255
- def set_direction(self, direction_string):
256
- self.direction = direction_string #update class' variable
257
-
258
- new_direction_xaml = ""
259
- if self.direction == "InArgument":
260
- new_direction_xaml = "InArgument(" + self.type + ")"
261
- elif self.direction == "InOutArgument":
262
- self.delete_default_value() #delete default value as it is not supported by this direction type
263
- new_direction_xaml = "InOutArgument(" + self.type + ")"
264
- elif self.direction == "OutArgument":
265
- self.delete_default_value() #delete default value as it is not supported by this direction type
266
- new_direction_xaml = "OutArgument(" + self.type + ")"
267
- else:
268
- new_direction_xaml = self.type
269
-
270
- self.xaml["Type"] = new_direction_xaml
271
- self.update_outer_sequence()
272
-
273
- #Creates a default value when one does not yet exist
274
- #STUB
275
-
276
- #Sets a new default value for this Class instance, as well as updating the parent raw XAML.
277
- def update_default_value(self, new_value):
278
- self.default_value = new_value
279
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
280
- values_string["this:" + self.outer_sequence.name + "." + self.name] = new_value
281
- self.update_outer_sequence()
282
-
283
- #Changes the name of default values to match the argument name when it is changed
284
- def update_default_value_name(self, old_name, new_name):
285
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
286
- key = "this:" + self.outer_sequence.name + "." + self.name
287
-
288
- if key in values_string:
289
- self.delete_default_value()
290
- values_string["this:" + self.outer_sequence.name + "." + new_name] = self.default_value
291
- #values_string["this:" + self.outer_sequence.name + "." + self.name] = new_value
292
-
293
- #Deletes the default value
294
- def delete_default_value(self):
295
- values_string = self.outer_sequence.xaml.find_all("Activity")[0]
296
- key = "this:" + self.outer_sequence.name + "." + self.name
297
-
298
- if key in values_string:
299
- del self.outer_sequence.xaml.find_all("Activity")[0]["this:" + self.outer_sequence.name + "." + self.name]
300
-
301
- if not self.default_value is None:
302
- del self.default_value
303
-
304
- #Update parent Sequence XAML. Do this when using any setter method defined above
305
- def update_outer_sequence(self):
306
- #if not self.outer_sequence.xaml.find(attrs={"Name":self.name})["Name"] is None:
307
- self.outer_sequence.xaml.find(attrs={"Name":self.name}).replace_with(self.xaml)
308
- self.outer_sequence.save()
309
-
310
- #override to string method
311
- def __str__(self):
312
- if self.default_value is None: # check if self has default_value
313
- return "{name: \"" + self.name + "\", direction: \"" + self.direction + "\", type: \"" + self.type + "\"}"
314
- else:
315
- return "{name: \"" + self.name + "\", direction: \"" + self.direction + "\", type: \"" + self.type + "\", default_value: \"" + self.default_value + "\"}"
316
-
317
-
318
- #-----------------------------------------------------------------------------------------------------------------------
319
- # Subclass: Argument
320
- # Description: Stores the arguments and their default values from the xaml file
321
- #-----------------------------------------------------------------------------------------------------------------------
322
-
323
- #Define subclass for the arguments
324
- class Inner_Sequence():
325
- def __init__(self, outer_sequence, xaml):
326
- self.outer_sequence = outer_sequence
327
- self.xaml = xaml
328
- self.id = xaml["sap2010:WorkflowViewState.IdRef"]
329
- self.get_invoked_workflow()
330
- self.variables = self.get_sequence_variables()
331
-
332
- #Get the invoked workflow for the sequences, if applicable
333
- def get_invoked_workflow(self):
334
- self.invoked_workflow = self.xaml.find("ui:InvokeWorkflowFile")
335
-
336
- if not self.invoked_workflow is None:
337
- #Get path to invoked workflow
338
- self.invoked_workflow_path = self.invoked_workflow["WorkflowFileName"]
339
-
340
- #get arguments of invoked workflow
341
- self.invoked_workflow_arguments_xaml = self.invoked_workflow.find("ui:InvokeWorkflowFile.Arguments")
342
-
343
- if len(self.invoked_workflow_arguments_xaml.findChildren()) > 0:
344
- self.invoked_workflow_arguments = []
345
- for index,child in enumerate(self.invoked_workflow_arguments_xaml.findChildren()):
346
- self.invoked_workflow_arguments.append(Sequence.Inner_Sequence.Invoked_Workflow_Argument(self, child, index))
347
-
348
- #Get variables in this sequence
349
- def get_sequence_variables(self):
350
- vars_from_xaml = self.xaml.find_all("Variable")
351
-
352
- #If there are any variables, we will build an array of variable objects and return them
353
- if len(vars_from_xaml) > 0:
354
- all_vars = []
355
-
356
- for item in self.xaml.find_all("Variable"):
357
- all_vars.append(self.outer_sequence.Variable(self.outer_sequence, xaml=item))
358
-
359
- return all_vars
360
-
361
- #Add variable to sequence
362
- def create_variable(self, xaml=None, name=None, type=None, default=None):
363
- #If xaml is None, build new BS node
364
- if xaml is None:
365
- xaml = self.outer_sequence.xaml.new_tag("Variable")
366
- xaml["Name"] = name
367
- xaml["x:TypeArguments"] = type
368
-
369
- if not default is None:
370
- xaml["Default"] = default
371
-
372
- self.xaml.find("Sequence.Variables").append(xaml) #Add new variable to xaml file
373
- self.variables = self.get_sequence_variables() #Regenerate vars from xaml
374
- self.update_outer_sequence()
375
-
376
- return xaml #return the new variable
377
-
378
- #Deletes a variable by name
379
- def delete_variable(self, var_name):
380
- self.xaml.find_all("Variable", Name=var_name)[0].decompose() #Deletes the variable from the XAML
381
- self.variables = self.get_sequence_variables() #Regenerate vars from xaml
382
- self.update_outer_sequence()
383
-
384
-
385
- #Imports arguments from invoked function. Just like the button in UiPath
386
- def import_arguments(self):
387
- #Clear the array of invoked workflow argument objects
388
- self.invoked_workflow_arguments = []
389
- self.invoked_workflow_arguments_xaml.clear()
390
- #clear the array of
391
- invoked_sequence = Sequence(self.invoked_workflow_path) #Load the invoked sequence
392
-
393
- #Create new nodes for each of the imported arguments
394
- for index,item in enumerate(invoked_sequence.arguments):
395
- #Determine new node type
396
- new_node_type = item.direction
397
-
398
- #build a new Invoked_Workflow_Argument object
399
- new_node = self.outer_sequence.xaml.new_tag(new_node_type) # have the beautiful soup instance from the parent create a new tag
400
- new_node["x:Key"] = item.name
401
- new_node["x:TypeArguments"] = item.type
402
- new_node.string = "" #Add this so BS adds a closing tag
403
-
404
- #Add it to this sequence's invoked workflow arguments
405
- self.invoked_workflow_arguments.append(Sequence.Inner_Sequence.Invoked_Workflow_Argument(self, new_node, index))
406
- #Add new node to the invoked_arguments_xaml
407
- self.invoked_workflow_arguments_xaml.append(new_node)
408
-
409
- self.update_outer_sequence()
410
- return self.invoked_workflow_arguments
411
-
412
- #Update parent Sequence XAML. Do this when using any setter method defined above
413
- def update_outer_sequence(self):
414
- #if not self.outer_sequence.xaml.find(attrs={"Name":self.name})["Name"] is None:
415
- self.outer_sequence.xaml.find(attrs={"sap2010:WorkflowViewState.IdRef":self.id}).replace_with(self.xaml)
416
- self.outer_sequence.save()
417
-
418
-
419
- #Define inner class for invoked_argument
420
- class Invoked_Workflow_Argument():
421
- def __init__(self, parent, xaml, index):
422
- self.parent = parent
423
- self.xaml = xaml
424
- self.name = xaml.name
425
- self.index = index
426
- self.key = self.xaml["x:Key"]
427
- self.type = self.xaml["x:TypeArguments"]
428
- self.value = self.xaml.getText()
429
- self.value_type = "value" # if the value is a pre-entered value and not a variable
430
-
431
- #Check if the value is a variable (denoted by square braces)
432
- if "[" in self.value:
433
- self.value = self.value[1:(len(self.value) - 1)]
434
- self.value_type = "variable"
435
-
436
- #Change the value of the argument (passing a value, not a variable)
437
- def set_value(self, new_value):
438
- self.value = new_value
439
- self.value_type = "value"
440
- self.xaml.string = new_value
441
- self.update_parent()
442
-
443
- #Change the value of the argument (the variable that is entered)
444
- def set_value_to_variable(self, variable):
445
- self.value = variable
446
- self.value_type = "variable"
447
- self.xaml.string = "[" + variable + "]"
448
- self.update_parent()
449
-
450
- #Change the key that the argument is pointing to
451
- def set_key(self, new_value):
452
- self.key = new_value
453
- self.xaml["x:Key"] = new_value
454
- self.update_parent()
455
-
456
- #Change the data type of the argument
457
- def set_type(self, new_type):
458
- if new_type == "InArgument":
459
- self.name = "InArgument"
460
- self.xaml.name = "InArgument"
461
- elif new_type == "OutArgument":
462
- self.name = "OutArgument"
463
- self.xaml.name = "OutArgument"
464
- elif new_type == "InOutArgument":
465
- self.name = "InOutArgument"
466
- self.xaml.name = "InOutArgument"
467
- self.update_parent()
468
-
469
-
470
-
471
- #Update parent Sequence XAML. Do this when using any setter method defined above
472
- def update_parent(self):
473
- self.parent.invoked_workflow.find("ui:InvokeWorkflowFile.Arguments").findChildren()[self.index].replace_with(self.xaml)
474
- self.parent.update_outer_sequence()
475
-
476
-
477
-
478
-
479
-
480
-
481
-
482
-
483
-
@@ -1,21 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: uipath
3
- Version: 0.0.1
4
- Summary: A python API for editing UiPath .xaml files programatically.
5
- Home-page: https://github.com/christianblandford/UiPath-Python
6
- Author: Christian Blandford
7
- Author-email: christianblandford@me.com
8
- License: UNKNOWN
9
- Platform: UNKNOWN
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Description-Content-Type: text/markdown
14
- Requires-Dist: beautifulsoup4 (>=4.7.1)
15
-
16
- # UiPath_Python
17
-
18
- A Python API for editing UiPath .xaml files.
19
-
20
- Documentation coming soon!
21
-
@@ -1,8 +0,0 @@
1
- uipath/__init__.py,sha256=XCE4SE2Ptda40VfLHckUvbkDJ0f2pn6Js7KZVbDxOMQ,30
2
- uipath/sequence.py,sha256=rkb5hadh1Hxddpkdn8bZpF2h0pyegzNtQd_e4vsF_lU,17569
3
- uipath/uipath.py,sha256=rkb5hadh1Hxddpkdn8bZpF2h0pyegzNtQd_e4vsF_lU,17569
4
- uipath-0.0.1.dist-info/LICENSE,sha256=LADYfaeSfJ_78McUNX4cM3TxzfFAbZ-zZzLDk8RqwFE,1074
5
- uipath-0.0.1.dist-info/METADATA,sha256=RwIjWR93zOZm7cup-BWk4vMka4AWxl0OPfXrQgKdZJw,604
6
- uipath-0.0.1.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
7
- uipath-0.0.1.dist-info/top_level.txt,sha256=cO-fuTo_YlozqaZ6VNk0ST79wuBjLkcTRzYpXLM6rRg,7
8
- uipath-0.0.1.dist-info/RECORD,,