Skip to content

Commit a975169

Browse files
committed
fix: handling of dates
1 parent 70847f9 commit a975169

File tree

2 files changed

+64
-21
lines changed

2 files changed

+64
-21
lines changed

src/api.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,29 +92,33 @@ def fetch_window(
9292
if cursor:
9393
url = base_url + f"&cursor={cursor}"
9494

95-
r = requests.get(url, headers=headers)
96-
if r.status_code == 429:
95+
req = requests.get(url, headers=headers)
96+
if req.status_code == 429:
9797
# parse Retry‑After or use exponential backoff
98-
wait = int(r.headers.get("Retry-After", 2**errors))
98+
wait = int(req.headers.get("Retry-After", 2**errors))
9999
sleep(wait + 0.1)
100100
errors += 1
101101
if errors > max_errors:
102102
print("")
103103
print(f"[{event_name}][{window_start}] too many 429s; abort")
104104
break
105105
continue
106-
elif not r.ok:
106+
elif not req.ok:
107107
errors += 1
108108
if errors > max_errors:
109109
print("")
110-
print(f"[{event_name}][{window_start}] errors: {r.status_code}; abort")
110+
print(
111+
f"[{event_name}][{window_start}] errors: {req.status_code}; abort"
112+
)
111113
break
112114
sleep(errors) # simple backoff
113115
continue
114116

115117
errors = 0
116118
events = [
117-
e for e in r.json() if {"key": "environment", "value": "prod"} in e["tags"]
119+
e
120+
for e in req.json()
121+
if {"key": "environment", "value": "prod"} in e["tags"]
118122
]
119123
new_docs = [filter_new(e, db) for e in events]
120124
new_docs = [d for d in new_docs if d]
@@ -131,7 +135,7 @@ def fetch_window(
131135
break
132136

133137
# look at Link header for next cursor or end
134-
link_header = r.headers.get("Link", "")
138+
link_header = req.headers.get("Link", "")
135139
next_link = None
136140
if link_header:
137141
for link in parse_header_links(link_header):
@@ -165,10 +169,10 @@ def parallel_fetch(
165169
max_workers = os.cpu_count()
166170

167171
windows = []
168-
cur = since
169-
while cur < until:
170-
nxt = min(cur + datetime.timedelta(days=days_per_chunk), until)
171-
windows.append((cur, nxt))
172+
cur = until
173+
while cur > since:
174+
nxt = max(cur - datetime.timedelta(days=days_per_chunk), since)
175+
windows.append((nxt, cur))
172176
cur = nxt
173177

174178
kwargs = {

src/run.py

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,26 @@ def cli():
4949
help="Which Sentry issues to fetch",
5050
)
5151
@click.option(
52-
"-s",
53-
"--since",
52+
"-S",
53+
"--start-date",
5454
type=click.DateTime(formats=["%Y-%m-%d"]),
5555
default=None,
5656
help=f"Start date (inclusive) in YYYY-MM-DD; defaults to {DEFAULT_DAYS_WINDOW} days ago",
5757
)
5858
@click.option(
59-
"-u",
60-
"--until",
59+
"-E",
60+
"--end-date",
6161
type=click.DateTime(formats=["%Y-%m-%d"]),
6262
default=None,
6363
help="End date (exclusive) in YYYY-MM-DD; defaults to today",
6464
)
65+
@click.option(
66+
"-D",
67+
"--days",
68+
type=int,
69+
default=None,
70+
help="End date (exclusive) in YYYY-MM-DD; defaults to today",
71+
)
6572
@click.option(
6673
"-c",
6774
"--chunk-days",
@@ -80,7 +87,7 @@ def cli():
8087
"-M", "--max-errors", type=click.IntRange(min=1), default=DEFAULT_MAX_ERRORS
8188
)
8289
@click.option("-L", "--cached-limit", type=click.IntRange(min=1), default=None)
83-
def get(event, since, until, chunk_days, jobs, max_errors, cached_limit):
90+
def get(event, start_date, end_date, days, chunk_days, jobs, max_errors, cached_limit):
8491
"""Fetch events in parallel using time-window chunking."""
8592

8693
token = os.getenv("SENTRY_TOKEN")
@@ -90,18 +97,50 @@ def get(event, since, until, chunk_days, jobs, max_errors, cached_limit):
9097

9198
now = datetime.now(timezone.utc)
9299

93-
since = since or (now - timedelta(days=DEFAULT_DAYS_WINDOW))
94-
until = until or now
100+
if start_date and days:
101+
click.echo("Warning: overriding --start-date because --days was present")
102+
start_date = None
103+
104+
if start_date:
105+
start_date = datetime(
106+
year=start_date.year,
107+
month=start_date.month,
108+
day=start_date.day,
109+
hour=now.hour,
110+
minute=now.minute,
111+
second=now.second,
112+
microsecond=now.microsecond,
113+
tzinfo=now.tzinfo,
114+
)
115+
if end_date:
116+
end_date = datetime(
117+
year=end_date.year,
118+
month=end_date.month,
119+
day=end_date.day,
120+
hour=now.hour,
121+
minute=now.minute,
122+
second=now.second,
123+
microsecond=now.microsecond,
124+
tzinfo=now.tzinfo,
125+
)
126+
else:
127+
end_date = now
128+
129+
start_date = start_date or (end_date - timedelta(days=days or DEFAULT_DAYS_WINDOW))
130+
start_date += timedelta(microseconds=1)
95131

96-
click.echo(f"{now:%Y-%m-%d %H:%M:%S} [Started]")
132+
click.echo(
133+
f"{now:%Y-%m-%d %H:%M:%S} [Started] "
134+
f"from: {start_date:%Y-%m-%d %H:%M:%S}, to: {end_date:%Y-%m-%d %H:%M:%S}"
135+
)
97136

98137
# Get events
99138
for ev in event:
100139
parallel_fetch(
101140
event_name=ev,
102141
token=token,
103-
since=since,
104-
until=until,
142+
since=start_date,
143+
until=end_date,
105144
days_per_chunk=chunk_days,
106145
max_workers=jobs,
107146
cached_limit=cached_limit,

0 commit comments

Comments
 (0)