alita-sdk 0.3.157__py3-none-any.whl → 0.3.158__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.
@@ -23,6 +23,16 @@ PostmanGetCollection = create_model(
23
23
  "PostmanGetCollection"
24
24
  )
25
25
 
26
+ PostmanGetCollectionFlat = create_model(
27
+ "PostmanGetCollectionFlat"
28
+ )
29
+
30
+ PostmanGetFolderFlat = create_model(
31
+ "PostmanGetFolderFlat",
32
+ folder_path=(str, Field(
33
+ description="The path to the folder to parse (e.g., 'API/Users' for nested folders)"))
34
+ )
35
+
26
36
  PostmanGetFolder = create_model(
27
37
  "PostmanGetFolder",
28
38
  folder_path=(str, Field(
@@ -45,24 +55,17 @@ PostmanSearchRequests = create_model(
45
55
  description="Optional HTTP method filter", default=None))
46
56
  )
47
57
 
48
- PostmanAnalyzeCollection = create_model(
49
- "PostmanAnalyzeCollection",
50
- include_improvements=(bool, Field(
51
- description="Include improvement suggestions in the analysis", default=False))
52
- )
53
-
54
- PostmanAnalyzeFolder = create_model(
55
- "PostmanAnalyzeFolder",
56
- folder_path=(str, Field(description="The path to the folder to analyze")),
57
- include_improvements=(bool, Field(
58
- description="Include improvement suggestions in the analysis", default=False))
59
- )
60
-
61
- PostmanAnalyzeRequest = create_model(
62
- "PostmanAnalyzeRequest",
63
- request_path=(str, Field(description="The path to the request to analyze")),
58
+ PostmanAnalyze = create_model(
59
+ "PostmanAnalyze",
60
+ scope=(str, Field(
61
+ description="The scope of analysis: 'collection', 'folder', or 'request'",
62
+ default="collection")),
63
+ target_path=(Optional[str], Field(
64
+ description="The path to the folder or request to analyze (required for folder/request scope)",
65
+ default=None)),
64
66
  include_improvements=(bool, Field(
65
- description="Include improvement suggestions in the analysis", default=False))
67
+ description="Include improvement suggestions in the analysis",
68
+ default=False))
66
69
  )
67
70
 
68
71
  PostmanCreateCollection = create_model(
@@ -235,12 +238,18 @@ PostmanMoveRequest = create_model(
235
238
  description="New folder path", default=None))
236
239
  )
237
240
 
238
- PostmanGetRequest = create_model(
239
- "PostmanGetRequest",
241
+ PostmanGetRequestByPath = create_model(
242
+ "PostmanGetRequestByPath",
240
243
  request_path=(str, Field(
241
244
  description="The path to the request (e.g., 'API/Users/Get User' or 'applications/recommendations')"))
242
245
  )
243
246
 
247
+ PostmanGetRequestById = create_model(
248
+ "PostmanGetRequestById",
249
+ request_id=(str, Field(
250
+ description="The unique ID of the request"))
251
+ )
252
+
244
253
  PostmanGetRequestScript = create_model(
245
254
  "PostmanGetRequestScript",
246
255
  request_path=(str, Field(description="Path to the request (folder/requestName)")),
@@ -319,33 +328,54 @@ class PostmanApiWrapper(BaseToolApiWrapper):
319
328
  "args_schema": PostmanGetCollections,
320
329
  "ref": self.get_collections
321
330
  },
331
+ # {
332
+ # "name": "get_collection",
333
+ # "mode": "get_collection",
334
+ # "description": "Get a specific Postman collection by ID",
335
+ # "args_schema": PostmanGetCollection,
336
+ # "ref": self.get_collection
337
+ # },
322
338
  {
323
339
  "name": "get_collection",
324
340
  "mode": "get_collection",
325
- "description": "Get a specific Postman collection by ID",
326
- "args_schema": PostmanGetCollection,
327
- "ref": self.get_collection
341
+ "description": "Get a specific Postman collection in flattened format with path-based structure",
342
+ "args_schema": PostmanGetCollectionFlat,
343
+ "ref": self.get_collection_flat
328
344
  },
329
345
  {
330
346
  "name": "get_folder",
331
347
  "mode": "get_folder",
332
- "description": "Get folders from a collection by path (supports nested paths like 'API/Users')",
333
- "args_schema": PostmanGetFolder,
334
- "ref": self.get_folder
348
+ "description": "Get a specific folder in flattened format with path-based structure",
349
+ "args_schema": PostmanGetFolderFlat,
350
+ "ref": self.get_folder_flat
335
351
  },
352
+ # {
353
+ # "name": "get_folder",
354
+ # "mode": "get_folder",
355
+ # "description": "Get folders from a collection by path (supports nested paths like 'API/Users')",
356
+ # "args_schema": PostmanGetFolder,
357
+ # "ref": self.get_folder
358
+ # },
359
+ # {
360
+ # "name": "get_folder_requests",
361
+ # "mode": "get_folder_requests",
362
+ # "description": "Get detailed information about all requests in a folder",
363
+ # "args_schema": PostmanGetFolderRequests,
364
+ # "ref": self.get_folder_requests
365
+ # },
336
366
  {
337
- "name": "get_folder_requests",
338
- "mode": "get_folder_requests",
339
- "description": "Get detailed information about all requests in a folder",
340
- "args_schema": PostmanGetFolderRequests,
341
- "ref": self.get_folder_requests
367
+ "name": "get_request_by_path",
368
+ "mode": "get_request_by_path",
369
+ "description": "Get a specific request by path",
370
+ "args_schema": PostmanGetRequestByPath,
371
+ "ref": self.get_request_by_path
342
372
  },
343
373
  {
344
- "name": "get_request",
345
- "mode": "get_request",
346
- "description": "Get a specific request by path",
347
- "args_schema": PostmanGetRequest,
348
- "ref": self.get_request
374
+ "name": "get_request_by_id",
375
+ "mode": "get_request_by_id",
376
+ "description": "Get a specific request by ID",
377
+ "args_schema": PostmanGetRequestById,
378
+ "ref": self.get_request_by_id
349
379
  },
350
380
  {
351
381
  "name": "get_request_script",
@@ -362,40 +392,26 @@ class PostmanApiWrapper(BaseToolApiWrapper):
362
392
  "ref": self.search_requests
363
393
  },
364
394
  {
365
- "name": "analyze_collection",
366
- "mode": "analyze_collection",
367
- "description": "Analyze a collection for API quality, best practices, and issues",
368
- "args_schema": PostmanAnalyzeCollection,
369
- "ref": self.analyze_collection
370
- },
371
- {
372
- "name": "analyze_folder",
373
- "mode": "analyze_folder",
374
- "description": "Analyze a specific folder within a collection",
375
- "args_schema": PostmanAnalyzeFolder,
376
- "ref": self.analyze_folder
377
- },
378
- {
379
- "name": "analyze_request",
380
- "mode": "analyze_request",
381
- "description": "Analyze a specific request within a collection",
382
- "args_schema": PostmanAnalyzeRequest,
383
- "ref": self.analyze_request
384
- },
385
- {
386
- "name": "create_collection",
387
- "mode": "create_collection",
388
- "description": "Create a new Postman collection",
389
- "args_schema": PostmanCreateCollection,
390
- "ref": self.create_collection
391
- },
392
- {
393
- "name": "update_collection_name",
394
- "mode": "update_collection_name",
395
- "description": "Update collection name",
396
- "args_schema": PostmanUpdateCollectionName,
397
- "ref": self.update_collection_name
395
+ "name": "analyze",
396
+ "mode": "analyze",
397
+ "description": "Analyze collection, folder, or request for API quality, best practices, and issues",
398
+ "args_schema": PostmanAnalyze,
399
+ "ref": self.analyze
398
400
  },
401
+ # {
402
+ # "name": "create_collection",
403
+ # "mode": "create_collection",
404
+ # "description": "Create a new Postman collection",
405
+ # "args_schema": PostmanCreateCollection,
406
+ # "ref": self.create_collection
407
+ # },
408
+ # {
409
+ # "name": "update_collection_name",
410
+ # "mode": "update_collection_name",
411
+ # "description": "Update collection name",
412
+ # "args_schema": PostmanUpdateCollectionName,
413
+ # "ref": self.update_collection_name
414
+ # },
399
415
  {
400
416
  "name": "update_collection_description",
401
417
  "mode": "update_collection_description",
@@ -570,8 +586,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
570
586
  def get_collection(self, **kwargs) -> str:
571
587
  """Get a specific collection by ID."""
572
588
  try:
573
- response = self._make_request(
574
- 'GET', f'/collections/{self.collection_id}')
589
+ response = self._make_request('GET', f'/collections/{self.collection_id}')
575
590
  return json.dumps(response, indent=2)
576
591
  except Exception as e:
577
592
  stacktrace = format_exc()
@@ -580,6 +595,19 @@ class PostmanApiWrapper(BaseToolApiWrapper):
580
595
  raise ToolException(
581
596
  f"Unable to get collection {self.collection_id}: {str(e)}")
582
597
 
598
+ def get_collection_flat(self, **kwargs) -> str:
599
+ """Get a specific collection by ID in flattened format."""
600
+ try:
601
+ response = self._make_request('GET', f'/collections/{self.collection_id}')
602
+ flattened = self.parse_collection_to_flat_structure(response)
603
+ return json.dumps(flattened, indent=2)
604
+ except Exception as e:
605
+ stacktrace = format_exc()
606
+ logger.error(
607
+ f"Exception when getting flattened collection {self.collection_id}: {stacktrace}")
608
+ raise ToolException(
609
+ f"Unable to get flattened collection {self.collection_id}: {str(e)}")
610
+
583
611
  def get_folder(self, folder_path: str, **kwargs) -> str:
584
612
  """Get folders from a collection by path."""
585
613
  try:
@@ -595,6 +623,19 @@ class PostmanApiWrapper(BaseToolApiWrapper):
595
623
  raise ToolException(
596
624
  f"Unable to get folder {folder_path} from collection {self.collection_id}: {str(e)}")
597
625
 
626
+ def get_folder_flat(self, folder_path: str, **kwargs) -> str:
627
+ """Get a specific folder in flattened format with path-based structure."""
628
+ try:
629
+ response = self._make_request('GET', f'/collections/{self.collection_id}')
630
+ flattened = self.parse_collection_to_flat_structure(response, folder_path)
631
+ return json.dumps(flattened, indent=2)
632
+ except Exception as e:
633
+ stacktrace = format_exc()
634
+ logger.error(
635
+ f"Exception when getting flattened folder {folder_path}: {stacktrace}")
636
+ raise ToolException(
637
+ f"Unable to get flattened folder {folder_path}: {str(e)}")
638
+
598
639
  def get_folder_requests(self, folder_path: str, include_details: bool = False, **kwargs) -> str:
599
640
  """Get detailed information about all requests in a folder."""
600
641
  try:
@@ -626,20 +667,55 @@ class PostmanApiWrapper(BaseToolApiWrapper):
626
667
  f"Unable to get requests from folder {folder_path}: {str(e)}")
627
668
 
628
669
  def search_requests(self, query: str, search_in: str = "all", method: str = None, **kwargs) -> str:
629
- """Search for requests across the collection."""
670
+ """Search for requests across the collection and return results in flattened structure."""
630
671
  try:
631
- collection = self._make_request(
672
+ collection_response = self._make_request(
632
673
  'GET', f'/collections/{self.collection_id}')
633
- requests = self.analyzer.search_requests_in_items(
634
- collection['collection']['item'], query, search_in, method)
635
-
674
+
675
+ # Get the collection in flattened structure
676
+ flattened = self.parse_collection_to_flat_structure(collection_response)
677
+
678
+ # Filter only requests that match the search criteria
679
+ matching_requests = {}
680
+
681
+ for path, item in flattened['items'].items():
682
+ if item.get('type') != 'request':
683
+ continue
684
+
685
+ # Apply method filter if specified
686
+ if method and item.get('method', '').upper() != method.upper():
687
+ continue
688
+
689
+ # Apply search criteria
690
+ match_found = False
691
+ query_lower = query.lower()
692
+
693
+ if search_in == "all" or search_in == "name":
694
+ # Extract request name from path (last part after /)
695
+ request_name = path.split('/')[-1] if '/' in path else path
696
+ if query_lower in request_name.lower():
697
+ match_found = True
698
+
699
+ if not match_found and (search_in == "all" or search_in == "url"):
700
+ url = item.get('request_url', '') or item.get('url', '')
701
+ if query_lower in url.lower():
702
+ match_found = True
703
+
704
+ if not match_found and (search_in == "all" or search_in == "description"):
705
+ description = item.get('description', '')
706
+ if isinstance(description, str) and query_lower in description.lower():
707
+ match_found = True
708
+
709
+ if match_found:
710
+ matching_requests[path] = item
711
+
712
+ # Create result structure similar to flattened format
636
713
  result = {
637
- "collection_id": self.collection_id,
638
714
  "query": query,
639
715
  "search_in": search_in,
640
716
  "method_filter": method,
641
- "results_count": len(requests),
642
- "results": requests
717
+ "results_count": len(matching_requests),
718
+ "items": matching_requests
643
719
  }
644
720
 
645
721
  return json.dumps(result, indent=2)
@@ -649,83 +725,85 @@ class PostmanApiWrapper(BaseToolApiWrapper):
649
725
  raise ToolException(
650
726
  f"Unable to search requests in collection {self.collection_id}: {str(e)}")
651
727
 
652
- def analyze_collection(self, include_improvements: bool = False, **kwargs) -> str:
653
- """Analyze a collection for API quality and best practices."""
728
+ def analyze(self, scope: str = "collection", target_path: str = None, include_improvements: bool = False, **kwargs) -> str:
729
+ """Unified analysis method for collection, folder, or request analysis.
730
+
731
+ Args:
732
+ scope: The scope of analysis ('collection', 'folder', or 'request')
733
+ target_path: The path to the folder or request (required for folder/request scope)
734
+ include_improvements: Whether to include improvement suggestions
735
+ """
654
736
  try:
655
- collection = self._make_request(
656
- 'GET', f'/collections/{self.collection_id}')
657
- analysis = self.analyzer.perform_collection_analysis(collection)
737
+ # Validate parameters
738
+ if scope not in ["collection", "folder", "request"]:
739
+ raise ToolException(f"Invalid scope '{scope}'. Must be 'collection', 'folder', or 'request'")
658
740
 
659
- if include_improvements:
660
- improvements = self.analyzer.generate_improvements(analysis)
661
- analysis["improvements"] = improvements
662
- analysis["improvement_count"] = len(improvements)
741
+ if scope in ["folder", "request"] and not target_path:
742
+ raise ToolException(f"target_path is required when scope is '{scope}'")
663
743
 
664
- return json.dumps(analysis, indent=2)
665
- except Exception as e:
666
- stacktrace = format_exc()
667
- logger.error(f"Exception when analyzing collection: {stacktrace}")
668
- raise ToolException(
669
- f"Unable to analyze collection {self.collection_id}: {str(e)}")
670
-
671
- def analyze_folder(self, folder_path: str, include_improvements: bool = False, **kwargs) -> str:
672
- """Analyze a specific folder within a collection."""
673
- try:
744
+ # Get collection data
674
745
  collection = self._make_request(
675
746
  'GET', f'/collections/{self.collection_id}')
676
- folders = self.analyzer.find_folders_by_path(
677
- collection['collection']['item'], folder_path)
678
-
679
- if not folders:
680
- return json.dumps({"error": f"Folder '{folder_path}' not found"}, indent=2)
681
-
682
- folder_analyses = []
683
- for folder in folders:
684
- analysis = self.analyzer.perform_folder_analysis(folder, folder_path)
747
+
748
+ if scope == "collection":
749
+ # Analyze entire collection
750
+ analysis = self.analyzer.perform_collection_analysis(collection)
685
751
 
686
752
  if include_improvements:
687
- improvements = self.analyzer.generate_folder_improvements(analysis)
753
+ improvements = self.analyzer.generate_improvements(analysis)
688
754
  analysis["improvements"] = improvements
689
755
  analysis["improvement_count"] = len(improvements)
690
756
 
691
- folder_analyses.append(analysis)
692
-
693
- return json.dumps(folder_analyses, indent=2)
694
- except Exception as e:
695
- stacktrace = format_exc()
696
- logger.error(f"Exception when analyzing folder: {stacktrace}")
697
- raise ToolException(
698
- f"Unable to analyze folder {folder_path}: {str(e)}")
757
+ return json.dumps(analysis, indent=2)
758
+
759
+ elif scope == "folder":
760
+ # Analyze specific folder
761
+ folders = self.analyzer.find_folders_by_path(
762
+ collection['collection']['item'], target_path)
699
763
 
700
- def analyze_request(self, request_path: str, include_improvements: bool = False, **kwargs) -> str:
701
- """Analyze a specific request within a collection."""
702
- try:
703
- collection = self._make_request(
704
- 'GET', f'/collections/{self.collection_id}')
705
- collection_data = collection["collection"]
764
+ if not folders:
765
+ return json.dumps({"error": f"Folder '{target_path}' not found"}, indent=2)
766
+
767
+ folder_analyses = []
768
+ for folder in folders:
769
+ analysis = self.analyzer.perform_folder_analysis(folder, target_path)
770
+
771
+ if include_improvements:
772
+ improvements = self.analyzer.generate_folder_improvements(analysis)
773
+ analysis["improvements"] = improvements
774
+ analysis["improvement_count"] = len(improvements)
775
+
776
+ folder_analyses.append(analysis)
777
+
778
+ return json.dumps(folder_analyses, indent=2)
779
+
780
+ elif scope == "request":
781
+ # Analyze specific request
782
+ collection_data = collection["collection"]
706
783
 
707
- # Find the request
708
- request_item = self.analyzer.find_request_by_path(
709
- collection_data["item"], request_path)
710
- if not request_item:
711
- raise ToolException(f"Request '{request_path}' not found")
784
+ # Find the request
785
+ request_item = self.analyzer.find_request_by_path(
786
+ collection_data["item"], target_path)
787
+ if not request_item:
788
+ raise ToolException(f"Request '{target_path}' not found")
712
789
 
713
- # Perform request analysis
714
- analysis = self.analyzer.perform_request_analysis(request_item)
715
- analysis["request_path"] = request_path
716
- analysis["collection_id"] = self.collection_id
717
-
718
- if include_improvements:
719
- improvements = self.analyzer.generate_request_improvements(analysis)
720
- analysis["improvements"] = improvements
721
- analysis["improvement_count"] = len(improvements)
790
+ # Perform request analysis
791
+ analysis = self.analyzer.perform_request_analysis(request_item)
792
+ analysis["request_path"] = target_path
793
+ analysis["collection_id"] = self.collection_id
794
+
795
+ if include_improvements:
796
+ improvements = self.analyzer.generate_request_improvements(analysis)
797
+ analysis["improvements"] = improvements
798
+ analysis["improvement_count"] = len(improvements)
722
799
 
723
- return json.dumps(analysis, indent=2)
800
+ return json.dumps(analysis, indent=2)
801
+
724
802
  except Exception as e:
725
803
  stacktrace = format_exc()
726
- logger.error(f"Exception when analyzing request: {stacktrace}")
804
+ logger.error(f"Exception when analyzing {scope}: {stacktrace}")
727
805
  raise ToolException(
728
- f"Unable to analyze request {request_path}: {str(e)}")
806
+ f"Unable to analyze {scope} {target_path or self.collection_id}: {str(e)}")
729
807
 
730
808
  # =================================================================
731
809
  # COLLECTION MANAGEMENT METHODS
@@ -1482,7 +1560,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
1482
1560
  # HELPER METHODS
1483
1561
  # =================================================================
1484
1562
 
1485
- def get_request(self, request_path: str, **kwargs) -> str:
1563
+ def get_request_by_path(self, request_path: str, **kwargs) -> str:
1486
1564
  """Get a specific request by path.
1487
1565
 
1488
1566
  Uses the _get_request_item_and_id helper to find the request and then fetches complete
@@ -1500,10 +1578,28 @@ class PostmanApiWrapper(BaseToolApiWrapper):
1500
1578
  return json.dumps(response, indent=2)
1501
1579
  except Exception as e:
1502
1580
  stacktrace = format_exc()
1503
- logger.error(f"Exception when getting request: {stacktrace}")
1581
+ logger.error(f"Exception when getting request by path: {stacktrace}")
1504
1582
  raise ToolException(
1505
1583
  f"Unable to get request '{request_path}': {str(e)}")
1506
1584
 
1585
+ def get_request_by_id(self, request_id: str, **kwargs) -> str:
1586
+ """Get a specific request by ID.
1587
+
1588
+ Directly fetches the request using its unique ID from the Postman API.
1589
+ """
1590
+ try:
1591
+ # Fetch the complete request information from the API using the ID
1592
+ response = self._make_request(
1593
+ 'GET', f'/collections/{self.collection_id}/requests/{request_id}'
1594
+ )
1595
+
1596
+ return json.dumps(response, indent=2)
1597
+ except Exception as e:
1598
+ stacktrace = format_exc()
1599
+ logger.error(f"Exception when getting request by ID: {stacktrace}")
1600
+ raise ToolException(
1601
+ f"Unable to get request with ID '{request_id}': {str(e)}")
1602
+
1507
1603
  def get_request_script(self, request_path: str, script_type: str = "prerequest", **kwargs) -> str:
1508
1604
  """
1509
1605
  Get the script (pre-request or test) for a request by path.
@@ -1549,3 +1645,143 @@ class PostmanApiWrapper(BaseToolApiWrapper):
1549
1645
  stacktrace = format_exc()
1550
1646
  logger.error(f"Exception when getting request {script_type} script: {stacktrace}")
1551
1647
  raise ToolException(f"Unable to get {script_type} script for request '{request_path}': {str(e)}")
1648
+
1649
+ def parse_collection_to_flat_structure(self, collection_response: Dict[str, Any], folder_path: str = None) -> Dict[str, Any]:
1650
+ """Parse collection response into a flattened structure with path-based keys.
1651
+
1652
+ Args:
1653
+ collection_response: The Postman collection response JSON
1654
+ folder_path: Optional folder path to filter results. If provided, only items
1655
+ within this folder will be included in the output, and collection
1656
+ metadata will be excluded.
1657
+ """
1658
+ collection = collection_response.get('collection', {})
1659
+ info = collection.get('info', {})
1660
+
1661
+ # If folder_path is specified, return minimal structure focused on the folder
1662
+ if folder_path is not None:
1663
+ result = {
1664
+ "folder_path": folder_path,
1665
+ "items": {}
1666
+ }
1667
+ else:
1668
+ # Full collection structure with metadata
1669
+ result = {
1670
+ "collection_postman_id": info.get('_postman_id'),
1671
+ "name": info.get('name'),
1672
+ "updatedAt": info.get('updatedAt'),
1673
+ "createdAt": info.get('createdAt'),
1674
+ "lastUpdatedBy": info.get('lastUpdatedBy'),
1675
+ "uid": info.get('uid'),
1676
+ "items": {}
1677
+ }
1678
+
1679
+ def parse_items(items, parent_path=""):
1680
+ """Recursively parse items into flat structure."""
1681
+ for item in items:
1682
+ item_name = item.get('name', '')
1683
+ current_path = f"{parent_path}/{item_name}" if parent_path else item_name
1684
+
1685
+ # If folder_path is specified, check if we should include this item
1686
+ if folder_path is not None:
1687
+ # Check if current path is within the specified folder
1688
+ if not (current_path == folder_path or current_path.startswith(folder_path + "/")):
1689
+ # If this is a folder, we need to check if it contains the target folder
1690
+ if 'item' in item and folder_path.startswith(current_path + "/"):
1691
+ # This folder is an ancestor of the target folder, continue traversing
1692
+ parse_items(item['item'], current_path)
1693
+ continue
1694
+
1695
+ # Check if this is a folder (has 'item' property) or a request
1696
+ if 'item' in item:
1697
+ # This is a folder
1698
+ result['items'][current_path] = {
1699
+ "type": "folder",
1700
+ "id": item.get('id'),
1701
+ "uid": item.get('uid')
1702
+ }
1703
+ # Recursively parse nested items
1704
+ parse_items(item['item'], current_path)
1705
+ else:
1706
+ # This is a request
1707
+ request_info = item.get('request', {})
1708
+
1709
+ # Parse URL
1710
+ url_info = request_info.get('url', {})
1711
+ if isinstance(url_info, str):
1712
+ url = url_info
1713
+ else:
1714
+ # URL is an object with raw property
1715
+ url = url_info.get('raw', '')
1716
+
1717
+ # Parse headers
1718
+ headers = request_info.get('header', [])
1719
+
1720
+ # Parse body
1721
+ body_info = None
1722
+ body = request_info.get('body', {})
1723
+ if body:
1724
+ body_mode = body.get('mode', '')
1725
+ if body_mode == 'raw':
1726
+ try:
1727
+ raw_data = body.get('raw', '')
1728
+ if raw_data:
1729
+ body_info = {
1730
+ "type": "json",
1731
+ "data": json.loads(raw_data) if raw_data.strip() else {}
1732
+ }
1733
+ except json.JSONDecodeError:
1734
+ body_info = {
1735
+ "type": "raw",
1736
+ "data": body.get('raw', '')
1737
+ }
1738
+ elif body_mode == 'formdata':
1739
+ body_info = {
1740
+ "type": "formdata",
1741
+ "data": body.get('formdata', [])
1742
+ }
1743
+ elif body_mode == 'urlencoded':
1744
+ body_info = {
1745
+ "type": "urlencoded",
1746
+ "data": body.get('urlencoded', [])
1747
+ }
1748
+
1749
+ # Parse URL parameters
1750
+ params = []
1751
+ if isinstance(url_info, dict):
1752
+ query = url_info.get('query', [])
1753
+ for param in query:
1754
+ if isinstance(param, dict):
1755
+ params.append({
1756
+ "key": param.get('key', ''),
1757
+ "value": param.get('value', ''),
1758
+ "disabled": param.get('disabled', False)
1759
+ })
1760
+
1761
+ request_data = {
1762
+ "id": item.get('id'),
1763
+ "uid": item.get('uid'),
1764
+ "full_postman_path": current_path,
1765
+ "type": "request",
1766
+ "method": request_info.get('method', 'GET'),
1767
+ "request_url": url,
1768
+ "headers": headers,
1769
+ "params": params
1770
+ }
1771
+
1772
+ # Add body if present
1773
+ if body_info:
1774
+ request_data["body"] = body_info
1775
+
1776
+ # Add description if present
1777
+ description = request_info.get('description')
1778
+ if description:
1779
+ request_data["description"] = description
1780
+
1781
+ result['items'][current_path] = request_data
1782
+
1783
+ # Parse the top-level items
1784
+ items = collection.get('item', [])
1785
+ parse_items(items)
1786
+
1787
+ return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.157
3
+ Version: 0.3.158
4
4
  Summary: SDK for building langchain agents using resources from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedjik@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -273,7 +273,7 @@ alita_sdk/tools/pandas/statsmodels/descriptive.py,sha256=APdofBnEiRhMrn6tLKwH076
273
273
  alita_sdk/tools/pandas/statsmodels/hypothesis_testing.py,sha256=fdNAayMB3W7avMfKJCcbf2_P54vUXbq8KVebOB48348,10508
274
274
  alita_sdk/tools/pandas/statsmodels/regression.py,sha256=Y1pWK4u_qzrfA740K-FX0nZ5FREGGPk8mfvykPIYoiI,9164
275
275
  alita_sdk/tools/postman/__init__.py,sha256=W0HdtACnTZw6tnzj7_qY_X5RoRyX3czcUSVaZJjBW-Y,4236
276
- alita_sdk/tools/postman/api_wrapper.py,sha256=G6pfCzZUok25qHkiZQvte7lrPYF3gbZX01jx0Si9MN8,66869
276
+ alita_sdk/tools/postman/api_wrapper.py,sha256=4Hf_aOvUB1G_BdlKvNaAqnQaoCnKDph-E7v4VEwaw5Y,77933
277
277
  alita_sdk/tools/postman/postman_analysis.py,sha256=2d-Oi2UORosIePIUyncSONw9hY7dw8Zc7BQvCd4aqpg,45115
278
278
  alita_sdk/tools/pptx/__init__.py,sha256=LNSTQk0BncfdWLXAOGX2WXezG3D4qSEuYwLpokmF9iM,3438
279
279
  alita_sdk/tools/pptx/pptx_wrapper.py,sha256=yyCYcTlIY976kJ4VfPo4dyxj4yeii9j9TWP6W8ZIpN8,29195
@@ -317,8 +317,8 @@ alita_sdk/tools/zephyr_enterprise/api_wrapper.py,sha256=Ir3zHljhbZQJRJJQOBzS_GL5
317
317
  alita_sdk/tools/zephyr_enterprise/zephyr_enterprise.py,sha256=hV9LIrYfJT6oYp-ZfQR0YHflqBFPsUw2Oc55HwK0H48,6809
318
318
  alita_sdk/tools/zephyr_scale/__init__.py,sha256=2NTcdrfkx4GSegqyXhsPLsEpc4FlACuDy85b0fk6cAo,4572
319
319
  alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=UHVQUVqcBc3SZvDfO78HSuBzwAsRw2cCDQa-xMOzndE,68663
320
- alita_sdk-0.3.157.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
321
- alita_sdk-0.3.157.dist-info/METADATA,sha256=IO3yoKg0xK703bmf11i1s-ifXSEuaWvZ6al0kqK6r9U,18667
322
- alita_sdk-0.3.157.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
323
- alita_sdk-0.3.157.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
324
- alita_sdk-0.3.157.dist-info/RECORD,,
320
+ alita_sdk-0.3.158.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
321
+ alita_sdk-0.3.158.dist-info/METADATA,sha256=ZEtjgt10_pjYxKpcHAC5IuLXnqGyNvwv8jnxsRza7g4,18667
322
+ alita_sdk-0.3.158.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
323
+ alita_sdk-0.3.158.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
324
+ alita_sdk-0.3.158.dist-info/RECORD,,