cartography 0.93.0__py3-none-any.whl → 0.94.0rc1__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 cartography might be problematic. Click here for more details.

@@ -1,4 +1,6 @@
1
1
  import logging
2
+ from collections import namedtuple
3
+ from time import sleep
2
4
  from typing import Any
3
5
  from typing import Dict
4
6
  from typing import List
@@ -15,6 +17,8 @@ from cartography.util import timeit
15
17
 
16
18
  logger = logging.getLogger(__name__)
17
19
 
20
+ RepoPermission = namedtuple('RepoPermission', ['repo_url', 'permission'])
21
+
18
22
 
19
23
  @timeit
20
24
  def get_teams(org: str, api_url: str, token: str) -> Tuple[PaginatedGraphqlData, Dict[str, Any]]:
@@ -45,26 +49,53 @@ def get_teams(org: str, api_url: str, token: str) -> Tuple[PaginatedGraphqlData,
45
49
 
46
50
  @timeit
47
51
  def _get_team_repos_for_multiple_teams(
48
- team_raw_data: List[Dict[str, Any]],
52
+ team_raw_data: list[dict[str, Any]],
49
53
  org: str,
50
54
  api_url: str,
51
55
  token: str,
52
- ) -> Dict[str, Any]:
53
- result = {}
56
+ ) -> dict[str, list[RepoPermission]]:
57
+ result: dict[str, list[RepoPermission]] = {}
54
58
  for team in team_raw_data:
55
59
  team_name = team['slug']
56
60
  repo_count = team['repositories']['totalCount']
57
61
 
58
- team_repos = _get_team_repos(org, api_url, token, team_name) if repo_count > 0 else None
62
+ if repo_count == 0:
63
+ # This team has access to no repos so let's move on
64
+ result[team_name] = []
65
+ continue
59
66
 
60
67
  repo_urls = []
61
68
  repo_permissions = []
62
- if team_repos:
63
- repo_urls = [t['url'] for t in team_repos.nodes] if team_repos.nodes else []
64
- repo_permissions = [t['permission'] for t in team_repos.edges] if team_repos.edges else []
69
+
70
+ max_tries = 5
71
+
72
+ for current_try in range(1, max_tries + 1):
73
+ team_repos = _get_team_repos(org, api_url, token, team_name)
74
+
75
+ try:
76
+ # The `or []` is because `.nodes` can be None. See:
77
+ # https://docs.github.com/en/graphql/reference/objects#teamrepositoryconnection
78
+ for repo in team_repos.nodes or []:
79
+ repo_urls.append(repo['url'])
80
+
81
+ # The `or []` is because `.edges` can be None.
82
+ for edge in team_repos.edges or []:
83
+ repo_permissions.append(edge['permission'])
84
+ # We're done! Break out of the retry loop.
85
+ break
86
+
87
+ except TypeError:
88
+ # Handles issue #1334
89
+ logger.warning(
90
+ f"GitHub returned None when trying to find repo or permission data for team {team_name}.",
91
+ exc_info=True,
92
+ )
93
+ if current_try == max_tries:
94
+ raise RuntimeError(f"GitHub returned a None repo url for team {team_name}, retries exhausted.")
95
+ sleep(current_try ** 2)
65
96
 
66
97
  # Shape = [(repo_url, 'WRITE'), ...]]
67
- result[team_name] = list(zip(repo_urls, repo_permissions))
98
+ result[team_name] = [RepoPermission(url, perm) for url, perm in zip(repo_urls, repo_permissions)]
68
99
  return result
69
100
 
70
101
 
@@ -114,8 +145,8 @@ def _get_team_repos(org: str, api_url: str, token: str, team: str) -> PaginatedG
114
145
  def transform_teams(
115
146
  team_paginated_data: PaginatedGraphqlData,
116
147
  org_data: Dict[str, Any],
117
- team_repo_data: Dict[str, Any],
118
- ) -> List[Dict[str, Any]]:
148
+ team_repo_data: dict[str, list[RepoPermission]],
149
+ ) -> list[dict[str, Any]]:
119
150
  result = []
120
151
  for team in team_paginated_data.nodes:
121
152
  team_name = team['slug']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cartography
3
- Version: 0.93.0
3
+ Version: 0.94.0rc1
4
4
  Summary: Explore assets and their relationships across your technical infrastructure.
5
5
  Home-page: https://www.github.com/lyft/cartography
6
6
  Maintainer: Lyft
@@ -230,7 +230,7 @@ cartography/intel/gcp/gke.py,sha256=qaTwsVaxkwNhW5_Mw4bedOk7fgJK8y0LwwcYlUABXDg,
230
230
  cartography/intel/gcp/storage.py,sha256=oO_ayEhkXlj2Gn7T5MU41ZXiqwRwe6Ud4wzqyRTsyf4,9075
231
231
  cartography/intel/github/__init__.py,sha256=y876JJGTDJZEOFCDiNCJfcLNxN24pVj4s2N0YmuuoaE,1914
232
232
  cartography/intel/github/repos.py,sha256=YPDdBMk6NkZjwPcqPW5LlCy_OS9tKcrZD6ygiUG93J0,21766
233
- cartography/intel/github/teams.py,sha256=mofyJeJVOD7Umh9Rq6QnAwom9bBHBx18kyvFMvQX5YE,5383
233
+ cartography/intel/github/teams.py,sha256=aXI-XbxlA1IDaAUX0XSdEt6pA2n4ew5j_doj1iNYCDM,6618
234
234
  cartography/intel/github/users.py,sha256=kQp0dxzP08DVrdvfVeCciQbrKPbbFvwbR_p_I_XGt7s,3826
235
235
  cartography/intel/github/util.py,sha256=K6hbxypy4luKhIE1Uh5VWZc9OyjMK2OuO00vBAQfloA,8049
236
236
  cartography/intel/gsuite/__init__.py,sha256=AGIUskGlLCVGHbnQicNpNWi9AvmV7_7hUKTt-hsB2J8,4306
@@ -332,10 +332,10 @@ cartography/models/semgrep/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
332
332
  cartography/models/semgrep/deployment.py,sha256=or5qZDuR51MXzINpH15jZrqmSUvXQevCNYWJ7D6v-JI,745
333
333
  cartography/models/semgrep/findings.py,sha256=xrn8sgXpNMrNJbKQagaAVxaCG9bVjTATSRR2XRBR4rg,5386
334
334
  cartography/models/semgrep/locations.py,sha256=kSk7Nn5Mn4Ob84MVZOo2GR0YFi-9Okq9pgA3FfC6_bk,3061
335
- cartography-0.93.0.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
336
- cartography-0.93.0.dist-info/METADATA,sha256=bZcpA3W4BYf5mQXLdALJ0KEf3_n_PqMI4TiPSda3Bv8,1988
337
- cartography-0.93.0.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
338
- cartography-0.93.0.dist-info/WHEEL,sha256=pd56usn78UTvq1xeX_ZwFhoK6jE5u5wzu4TTBIG5cQ0,91
339
- cartography-0.93.0.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
340
- cartography-0.93.0.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
341
- cartography-0.93.0.dist-info/RECORD,,
335
+ cartography-0.94.0rc1.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
336
+ cartography-0.94.0rc1.dist-info/METADATA,sha256=DGaNuQa_oe86QadP2SNQJD323D2P6NSB6lN8niWUd3I,1991
337
+ cartography-0.94.0rc1.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
338
+ cartography-0.94.0rc1.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
339
+ cartography-0.94.0rc1.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
340
+ cartography-0.94.0rc1.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
341
+ cartography-0.94.0rc1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.0.0)
2
+ Generator: setuptools (71.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5