cartography 0.85.2__py3-none-any.whl → 0.85.3__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.

@@ -23,7 +23,7 @@ GITHUB_ORG_REPOS_PAGINATED_GRAPHQL = """
23
23
  {
24
24
  url
25
25
  login
26
- repositories(first: 100, after: $cursor){
26
+ repositories(first: 50, after: $cursor){
27
27
  pageInfo{
28
28
  endCursor
29
29
  hasNextPage
@@ -59,7 +59,7 @@ GITHUB_ORG_REPOS_PAGINATED_GRAPHQL = """
59
59
  login
60
60
  __typename
61
61
  }
62
- collaborators(affiliation: OUTSIDE, first: 100) {
62
+ collaborators(affiliation: OUTSIDE, first: 50) {
63
63
  edges {
64
64
  permission
65
65
  }
@@ -1,6 +1,9 @@
1
1
  import json
2
2
  import logging
3
3
  import time
4
+ from datetime import datetime
5
+ from datetime import timedelta
6
+ from datetime import timezone as tz
4
7
  from typing import Any
5
8
  from typing import Dict
6
9
  from typing import List
@@ -10,9 +13,11 @@ from typing import Tuple
10
13
 
11
14
  import requests
12
15
 
16
+
13
17
  logger = logging.getLogger(__name__)
14
18
  # Connect and read timeouts of 60 seconds each; see https://requests.readthedocs.io/en/master/user/advanced/#timeouts
15
19
  _TIMEOUT = (60, 60)
20
+ _GRAPHQL_RATE_LIMIT_REMAINING_THRESHOLD = 500
16
21
 
17
22
 
18
23
  class PaginatedGraphqlData(NamedTuple):
@@ -20,6 +25,30 @@ class PaginatedGraphqlData(NamedTuple):
20
25
  edges: List[Dict[str, Any]]
21
26
 
22
27
 
28
+ def handle_rate_limit_sleep(token: str) -> None:
29
+ '''
30
+ Check the remaining rate limit and sleep if remaining is below threshold
31
+ :param token: The Github API token as string.
32
+ '''
33
+ response = requests.get('https://api.github.com/rate_limit', headers={'Authorization': f"token {token}"})
34
+ response.raise_for_status()
35
+ response_json = response.json()
36
+ rate_limit_obj = response_json['resources']['graphql']
37
+ remaining = rate_limit_obj['remaining']
38
+ threshold = _GRAPHQL_RATE_LIMIT_REMAINING_THRESHOLD
39
+ if remaining > threshold:
40
+ return
41
+ reset_at = datetime.fromtimestamp(rate_limit_obj['reset'], tz=tz.utc)
42
+ now = datetime.now(tz.utc)
43
+ # add an extra minute for safety
44
+ sleep_duration = reset_at - now + timedelta(minutes=1)
45
+ logger.warning(
46
+ f'Github graphql ratelimit has {remaining} remaining and is under threshold {threshold},'
47
+ f' sleeping until reset at {reset_at} for {sleep_duration}',
48
+ )
49
+ time.sleep(sleep_duration.seconds)
50
+
51
+
23
52
  def call_github_api(query: str, variables: str, token: str, api_url: str) -> Dict:
24
53
  """
25
54
  Calls the GitHub v4 API and executes a query
@@ -116,6 +145,9 @@ def fetch_all(
116
145
  while has_next_page:
117
146
  exc: Any = None
118
147
  try:
148
+ # In the future, we may use also use the rateLimit object from the graphql response.
149
+ # But we still need at least one call to the REST endpoint in case the graphql remaining is already 0
150
+ handle_rate_limit_sleep(token)
119
151
  resp = fetch_page(token, api_url, organization, query, cursor, **kwargs)
120
152
  retry = 0
121
153
  except requests.exceptions.Timeout as err:
@@ -135,7 +167,7 @@ def fetch_all(
135
167
  )
136
168
  raise exc
137
169
  elif retry > 0:
138
- time.sleep(1 * retry)
170
+ time.sleep(2 ** retry)
139
171
  continue
140
172
 
141
173
  resource = resp['data']['organization'][resource_type]
@@ -148,5 +180,6 @@ def fetch_all(
148
180
 
149
181
  cursor = resource['pageInfo']['endCursor']
150
182
  has_next_page = resource['pageInfo']['hasNextPage']
183
+
151
184
  org_data = {'url': resp['data']['organization']['url'], 'login': resp['data']['organization']['login']}
152
185
  return data, org_data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cartography
3
- Version: 0.85.2
3
+ Version: 0.85.3
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
@@ -228,10 +228,10 @@ cartography/intel/gcp/dns.py,sha256=y2pvbmV04cnrMyuu_nbW3oc7uwHX6yEzn1n7veCsjmk,
228
228
  cartography/intel/gcp/gke.py,sha256=qaTwsVaxkwNhW5_Mw4bedOk7fgJK8y0LwwcYlUABXDg,7966
229
229
  cartography/intel/gcp/storage.py,sha256=oO_ayEhkXlj2Gn7T5MU41ZXiqwRwe6Ud4wzqyRTsyf4,9075
230
230
  cartography/intel/github/__init__.py,sha256=y876JJGTDJZEOFCDiNCJfcLNxN24pVj4s2N0YmuuoaE,1914
231
- cartography/intel/github/repos.py,sha256=-4bX9U2G3FJhBW2c_NqbR2QcRUbS1FfSd2Fg8FRjNho,21768
231
+ cartography/intel/github/repos.py,sha256=YPDdBMk6NkZjwPcqPW5LlCy_OS9tKcrZD6ygiUG93J0,21766
232
232
  cartography/intel/github/teams.py,sha256=aX1dj7HHVjw0hv_VvG1dee3WzTfmVMraP1khlwvN7Xs,5287
233
233
  cartography/intel/github/users.py,sha256=kQp0dxzP08DVrdvfVeCciQbrKPbbFvwbR_p_I_XGt7s,3826
234
- cartography/intel/github/util.py,sha256=pPKqawBuMoz12_gsnNkmtts_s_kQscRX5u_m6Zaxur0,6056
234
+ cartography/intel/github/util.py,sha256=trigWITP7C44RjKpBT12fCcxtqo5WFqUOcB9VqtzifA,7465
235
235
  cartography/intel/gsuite/__init__.py,sha256=AGIUskGlLCVGHbnQicNpNWi9AvmV7_7hUKTt-hsB2J8,4306
236
236
  cartography/intel/gsuite/api.py,sha256=J0dkNdfBVMrEv8vvStQu7YKVxXSyV45WueFhUS4aOG4,10310
237
237
  cartography/intel/jamf/__init__.py,sha256=Nof-LrUeevoieo6oP2GyfTwx8k5TUIgreW6hSj53YjQ,419
@@ -321,10 +321,10 @@ cartography/models/semgrep/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
321
321
  cartography/models/semgrep/deployment.py,sha256=or5qZDuR51MXzINpH15jZrqmSUvXQevCNYWJ7D6v-JI,745
322
322
  cartography/models/semgrep/findings.py,sha256=fzoCbn3QPNAapellnkXT-SSngqaXtJo7ArEHSoCekM8,3883
323
323
  cartography/models/semgrep/locations.py,sha256=kSk7Nn5Mn4Ob84MVZOo2GR0YFi-9Okq9pgA3FfC6_bk,3061
324
- cartography-0.85.2.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
325
- cartography-0.85.2.dist-info/METADATA,sha256=qiS3adJc2OK6_0bPGwUtH0XkoDY6ZBtoDpIQPjKCvog,1987
326
- cartography-0.85.2.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
327
- cartography-0.85.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
328
- cartography-0.85.2.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
329
- cartography-0.85.2.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
330
- cartography-0.85.2.dist-info/RECORD,,
324
+ cartography-0.85.3.dist-info/LICENSE,sha256=489ZXeW9G90up6ep-D1n-lJgk9ciNT2yxXpFgRSidtk,11341
325
+ cartography-0.85.3.dist-info/METADATA,sha256=uP8WvTjJDL7jKi7ztSmgZSdaqbnn-47IPcsmeVlw53A,1987
326
+ cartography-0.85.3.dist-info/NOTICE,sha256=YOGAsjFtbyKj5tslYIg6V5jEYRuEvnSsIuDOUKj0Qj4,97
327
+ cartography-0.85.3.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
328
+ cartography-0.85.3.dist-info/entry_points.txt,sha256=GVIAWD0o0_K077qMA_k1oZU4v-M0a8GLKGJR8tZ-qH8,112
329
+ cartography-0.85.3.dist-info/top_level.txt,sha256=BHqsNJQiI6Q72DeypC1IINQJE59SLhU4nllbQjgJi9g,12
330
+ cartography-0.85.3.dist-info/RECORD,,